Particles_ruby2d

require 'ruby2d'
require 'parallel'

@parts = []

class Part < Square
  attr_reader :dx, :dy

  def initialize(**args)
    speed = rand * 10 + 5
    direction = rand * 360
    @dx, @dy = speed * Math.cos(Math::PI * 2 * direction / 360),
      speed * Math.sin(Math::PI * 2 * direction / 360)

    super(**args)
  end

end

def add_part(x, y, n)
  n.times { @parts << Part.new(x: x, y: y, size: 4) }
end

def remove_outsiders
  @parts.delete_if {|p|
    !(p.x).between?(-5, 645) || !(p.y).between?(-5, 485)
  }

  @txt.text = 'Particles: %s' % @parts.size
end

def move_particle(obj)
  obj.x += obj.dx; obj.y += obj.dy
end

on :key_down do |e| close if e.key == 'q' end
on :mouse_down do |e| add_part(e.x, e.y, 90) end

@txt = Text.new('Particles: 0')

update do
  remove_outsiders
  Parallel.map(@parts, in_threads: 20) {|o| move_particle(o)}
end

show