Class: SFML::ParticleSystem

Inherits:
Object
  • Object
show all
Defined in:
lib/sfml/graphics/particle_system.rb

Overview

A pool-backed particle emitter built on top of SFML::VertexArray. Each particle is two triangles (a quad) so a single CSFML draw call ships thousands at once.

class Sparks < SFML::ParticleSystem
def emit_one
  angle = rand(0.0..2 * Math::PI)
  speed = rand(80.0..200.0)
  spawn(
    position:  @origin,
    velocity:  SFML::Vector2.new(Math.cos(angle), Math.sin(angle)) * speed,
    lifetime:  0.8,
    color:     SFML::Color.new(255, 200, 50),
    size:      4,
  )
end
end

sparks = Sparks.new(max: 500)

def update(dt)
5.times { sparks.emit_one } if mouse_down?
sparks.update(dt)
end

def draw
window.draw(sparks)
end

Particles fade linearly from full alpha at spawn to zero alpha at lifetime. Override #update_particle(p, dt) to apply gravity, drag, custom colour curves, etc.

Acceleration: pass gravity: to the constructor for the common case (px/s² added to velocity every frame). For richer behaviour, subclass and override.

Defined Under Namespace

Classes: Particle

Constant Summary collapse

DEFAULT_GRAVITY =

No gravity by default [0.0, 0.0].

[0.0, 0.0].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max: 1000, gravity: DEFAULT_GRAVITY, texture: nil) ⇒ ParticleSystem

Returns a new instance of ParticleSystem.



57
58
59
60
61
62
63
64
# File 'lib/sfml/graphics/particle_system.rb', line 57

def initialize(max: 1000, gravity: DEFAULT_GRAVITY, texture: nil)
  @max          = Integer(max)
  @gravity_x    = Float(gravity[0])
  @gravity_y    = Float(gravity[1])
  @texture      = texture
  @particles    = []
  @vertex_array = VertexArray.new(:triangles)
end

Instance Attribute Details

#particles ⇒ Object (readonly)

The particles, texture components.



67
68
69
# File 'lib/sfml/graphics/particle_system.rb', line 67

def particles
  @particles
end

#texture ⇒ Object (readonly)

The particles, texture components.



67
68
69
# File 'lib/sfml/graphics/particle_system.rb', line 67

def texture
  @texture
end

Instance Method Details

#clear ⇒ Object

Drop every live particle.



100
101
102
103
# File 'lib/sfml/graphics/particle_system.rb', line 100

def clear
  @particles.clear
  self
end

#draw_on(target, states_ptr = nil) ⇒ Object

Drawable interface — rebuilds the VertexArray and forwards.



133
134
135
136
# File 'lib/sfml/graphics/particle_system.rb', line 133

def draw_on(target, states_ptr = nil)
  _rebuild_vertex_array
  @vertex_array.draw_on(target, states_ptr)
end

#empty? ⇒ Boolean

true if empty.

Returns:

  • (Boolean)


71
72
# File 'lib/sfml/graphics/particle_system.rb', line 71

def empty? = @particles.empty?
# `true` if full.

#full? ⇒ Boolean

true if full.

Returns:

  • (Boolean)


73
# File 'lib/sfml/graphics/particle_system.rb', line 73

def full?  = @particles.size >= @max

#size ⇒ Object

Returns the size.



69
70
# File 'lib/sfml/graphics/particle_system.rb', line 69

def size = @particles.size
# `true` if empty.

#spawn(position:, velocity: [0, 0], lifetime: 1.0, color: Color.white, size: 4) ⇒ Object

Spawn a new particle. Silently dropped if the pool is full (better than reallocating; users can size up max:).

Parameters:

  • position (Vector2, Array) —

    world coords

  • velocity (Vector2, Array) (defaults to: [0, 0]) —

    px/s

  • lifetime (Numeric) (defaults to: 1.0) —

    seconds

  • color (SFML::Color) (defaults to: Color.white)
  • size (Numeric) (defaults to: 4) —

    half-side of the quad in pixels



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/sfml/graphics/particle_system.rb', line 83

def spawn(position:, velocity: [0, 0], lifetime: 1.0, color: Color.white, size: 4)
  return if full?

  px, py = _xy(position)
  vx, vy = _xy(velocity)

  @particles << Particle.new(
    Float(px), Float(py),
    Float(vx), Float(vy),
    0.0, Float(lifetime),
    color.r, color.g, color.b, color.a,
    Float(size),
  )
  self
end

#update(dt) ⇒ Object

Advance all particles by dt and remove dead ones.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/sfml/graphics/particle_system.rb', line 106

def update(dt)
  seconds = dt.is_a?(Time) ? dt.as_seconds : Float(dt)
  gx, gy  = @gravity_x, @gravity_y

  @particles.each do |p|
    next unless p.alive?

    # Gravity + integration. Subclasses can override
    # update_particle to layer additional forces / drag.
    p.vx += gx * seconds
    p.vy += gy * seconds
    p.x  += p.vx * seconds
    p.y  += p.vy * seconds
    p.age += seconds
    update_particle(p, seconds)
  end

  @particles.delete_if { |p| !p.alive? }

  self
end

#update_particle(_particle, _dt) ⇒ Object

Hook: tweak a particle's state. Default does nothing; override for drag, attractors, colour curves over lifetime, etc.



130
# File 'lib/sfml/graphics/particle_system.rb', line 130

def update_particle(_particle, _dt); end