class Eagle::Particles2D

Overview

A particle emitter for fire, smoke, sparks, explosions, rain and magic effects.

Configure how particles spawn, move and change over their life, add the node to the tree, and it runs by itself. Particles are simulated on the CPU and drawn in one batch, so thousands are fine.

fire = Particles2D.new(amount: 120, position: v2(200, 300))
fire.lifetime = 0.8
fire.speed = 40..90
fire.direction = -Math::PI / 2         # up
fire.spread = 0.4
fire.gravity = v2(0, -60)              # rises
fire.scale_start, fire.scale_end = 1.2, 0.2
fire.color_over_life = [Color::YELLOW, Color::ORANGE, Color::RED.alpha(0)]
fire.blend = GPU::BlendMode::Additive
SceneTree.root.add(fire)

boom = Particles2D.new(amount: 0, position: v2(400, 300))
boom.speed = 100..300
boom.spread = Mathf::TAU               # every direction
boom.on_finished { boom.queue_free }
SceneTree.root.add(boom)
boom.explode(80)                       # one burst, then remove itself

By default particles live in world space, so a moving emitter leaves a trail. Set world_space = false to make them follow the node.

Defined in:

eagle/nodes/particles2d.cr

Constructors

Instance Method Summary

Instance methods inherited from class Eagle::Node2D

direction_to(other : Node2D) : Vec2 direction_to, distance_to(other : Node2D) : Float32 distance_to, down : Vec2 down, forward : Vec2 forward, global_position : Vec2 global_position, global_position=(p : Vec2) global_position=, global_rotation : Float32 global_rotation, global_scale : Vec2 global_scale, global_transform : Transform2D global_transform, look_at(target : Vec2) : Nil look_at, modulate : Color modulate, modulate=(modulate : Color) modulate=, parent_2d : Node2D | Nil parent_2d, position : Vec2 position, position=(p : Vec2) position=, right : Vec2 right, rotate(rad : Number) : Nil rotate, rotation : Float32 rotation, rotation=(rotation : Float32) rotation=, rotation_degrees : Float32 rotation_degrees, rotation_degrees=(d : Number) rotation_degrees=, scale : Vec2 scale, scale=(s : Vec2)
scale=(s : Number)
scale=
, to_global(local : Vec2) : Vec2 to_global, to_local(global : Vec2) : Vec2 to_local, top_level=(top_level : Bool) top_level=, top_level? : Bool top_level?, transform : Transform2D transform, transform=(t : Transform2D) transform=, translate(x : Number, y : Number) : Nil
translate(v : Vec2) : Nil
translate
, x : Float32 x, x=(v : Number) x=, y : Float32 y, y=(v : Number) y=

Constructor methods inherited from class Eagle::Node2D

new(name : String = "", position : Eagle::Vec2 = Vec2::ZERO, rotation : Float32 = 0_f32, scale : Eagle::Vec2 = Vec2::ONE) new

Instance methods inherited from class Eagle::Node

<<(child : Node) : self <<, [](path : String) : Node [], []?(path : String) : Node | Nil []?, add(child : Node) : Node
add(*children : Node) : Nil
add
, add_child(child : Node) : Node add_child, add_to_group(group : String) : self add_to_group, ancestor_of?(node : Node) : Bool ancestor_of?, can_process? : Bool can_process?, child?(name : String) : Node | Nil child?, child_added : Eagle::Emitter(Node) child_added, child_count : Int32 child_count, child_removed : Eagle::Emitter(Node) child_removed, children : Array(Eagle::Node) children, children_of(type : T.class) : Array(T) forall T children_of, clear_children : Nil clear_children, draw(g : Graphics) : Nil draw, dump(io : IO = STDOUT, indent = 0) : Nil dump, each_ancestor(& : Node -> ) : Nil each_ancestor, each_child(& : Node -> ) : Nil each_child, each_descendant(&block : Node -> ) : Nil each_descendant, emit_child_added(*args) : Nil emit_child_added, emit_child_removed(*args) : Nil emit_child_removed, emit_tree_entered(*args) : Nil emit_tree_entered, emit_tree_exited(*args) : Nil emit_tree_exited, enter_tree : Nil enter_tree, exit_tree : Nil exit_tree, find(name : String) : Node | Nil find, find_all(type : T.class) : Array(T) forall T find_all, first_child : Node | Nil first_child, free : Nil free, get_node(path : String, type : T.class) : T forall T
get_node(path : String) : Node
get_node
, get_node?(path : String) : Node | Nil get_node?, groups : Set(String) groups, in_group?(group : String) : Bool in_group?, in_tree? : Bool in_tree?, input(event : Event) : Nil input, name : String name, name=(name : String) name=, on_child_added(&block : Node -> Nil) : Proc(Node, Nil) on_child_added, on_child_removed(&block : Node -> Nil) : Proc(Node, Nil) on_child_removed, on_tree_entered(&block : -> Nil) : Proc(Nil) on_tree_entered, on_tree_exited(&block : -> Nil) : Proc(Nil) on_tree_exited, parent : Node | Nil parent, path : String path, physics_process(dt : Float32) : Nil physics_process, process(dt : Float32) : Nil process, process_mode : Eagle::Node::ProcessMode process_mode, process_mode=(process_mode : Eagle::Node::ProcessMode) process_mode=, queue_free : Nil queue_free, queued_free? : Bool queued_free?, ready : Nil ready, ready_called? : Bool ready_called?, remove(child : Node) : Nil remove, remove_child(child : Node) : Nil remove_child, remove_from_group(group : String) : Nil remove_from_group, remove_from_parent : Nil remove_from_parent, resized(width : Int32, height : Int32) : Nil resized, root : Node root, to_s(io : IO) : Nil to_s, tree_entered : Eagle::Emitter() tree_entered, tree_exited : Eagle::Emitter() tree_exited, visible=(visible : Bool) visible=, visible? : Bool visible?, z_index : Int32 z_index, z_index=(z_index : Int32) z_index=

Constructor methods inherited from class Eagle::Node

new(name : String = "") new

Constructor Detail

def self.new(name : String = "", amount : Int32 = 100, position : Vec2 = Vec2::ZERO, max_particles : Int32 | Nil = nil, seed : Int32 | Nil = nil) #

Creates an emitter.


Instance Method Detail

def alive_count : Int32 #

Number of live particles.


def amount : Int32 #

Particles emitted per second while emitting.


def amount=(amount : Int32) #

Particles emitted per second while emitting.


def angular_speed : Range(Float32, Float32) #

Spin range in radians per second.


def angular_speed=(angular_speed : Range(Float32, Float32)) #

Spin range in radians per second.


def angular_speed=(r : Range(Number, Number)) #

Sets the spin range.


def blend : GPU::BlendMode #

Blend mode. Additive makes overlapping particles glow.


def blend=(blend : GPU::BlendMode) #

Blend mode. Additive makes overlapping particles glow.


def clear : Nil #

Kills every particle.


def color_at(t : Float32) : Color #

The color at life fraction t.


def color_over_life : Array(Color) #

Colors a particle passes through from birth to death, evenly spaced. Fade to a transparent color for a soft end.


def color_over_life=(color_over_life : Array(Color)) #

Colors a particle passes through from birth to death, evenly spaced. Fade to a transparent color for a soft end.


def custom_update : Proc(Particle, Float32, Particle) | Nil #

A block run for every particle each frame to apply custom behavior, such as swirling. It receives the particle and dt and returns the updated particle.


def custom_update=(custom_update : Proc(Particle, Float32, Particle) | Nil) #

A block run for every particle each frame to apply custom behavior, such as swirling. It receives the particle and dt and returns the updated particle.


def damping : Float32 #

Drag that slows particles down over time.


def damping=(damping : Float32) #

Drag that slows particles down over time.


def damping=(v : Number) #

Sets the damping.


def direction : Float32 #

Launch direction in radians. The default points up.


def direction=(direction : Float32) #

Launch direction in radians. The default points up.


def direction=(v : Number) #

Sets the launch direction in radians.


def draw_tree(g : Graphics) : Nil #

Draws every live particle.


def emission_radius : Float32 #

Radius for EmissionShape::Circle.


def emission_radius=(emission_radius : Float32) #

Radius for EmissionShape::Circle.


def emission_rect : Vec2 #

def emission_rect=(emission_rect : Vec2) #

def emission_shape : Eagle::Particles2D::EmissionShape #

Where particles spawn; see EmissionShape.


def emission_shape=(emission_shape : Eagle::Particles2D::EmissionShape) #

Where particles spawn; see EmissionShape.


def emit(n : Int32) : Nil #

Spawns n particles right away, for bursts.


def emit_finished(*args) : Nil #

Emitted when emission has stopped and the last particle has died. Connect with on_finished { ... }, for example to remove a one-shot explosion.


def emitting=(emitting : Bool) #

Whether new particles are spawned. Existing ones finish their lives either way.


def emitting? : Bool #

Whether new particles are spawned. Existing ones finish their lives either way.


def explode(n : Int32) : Nil #

Spawns n particles and stops emitting. #finished fires when the last one dies.


def finished : Eagle::Emitter() #

Emitted when emission has stopped and the last particle has died. Connect with on_finished { ... }, for example to remove a one-shot explosion.


def gravity : Vec2 #

Constant acceleration, such as v2(0, 400) for sparks that fall.


def gravity=(gravity : Vec2) #

Constant acceleration, such as v2(0, 400) for sparks that fall.


def lifetime : Float32 #

How long each particle lives, in seconds.


def lifetime=(lifetime : Float32) #

How long each particle lives, in seconds.


def lifetime=(v : Number) #

Sets the lifetime.


def lifetime_random : Float32 #

Random variation of lifetime, as a fraction: 0.2 means up to 20% longer or shorter.


def lifetime_random=(lifetime_random : Float32) #

Random variation of lifetime, as a fraction: 0.2 means up to 20% longer or shorter.


def max_particles : Int32 #

Hard cap on live particles.


def max_particles=(max_particles : Int32) #

Hard cap on live particles.


def on_finished(&block : -> Nil) : Proc(Nil) #

Emitted when emission has stopped and the last particle has died. Connect with on_finished { ... }, for example to remove a one-shot explosion.


def one_shot=(one_shot : Bool) #

Emit #amount particles at once, then stop.


def one_shot? : Bool #

Emit #amount particles at once, then stop.


def particles : Array(Particle) #

The particle pool, including dead particles.


def process(dt : Float32) : Nil #

Updates the simulation. Called by the engine.


def restart : Nil #

Kills every particle and starts emitting again.


def scale_end : Float32 #

Size multiplier when it dies. Size eases between the two.


def scale_end=(scale_end : Float32) #

Size multiplier when it dies. Size eases between the two.


def scale_end=(v : Number) #

Sets the ending size.


def scale_random : Float32 #

Random size variation, as a fraction.


def scale_random=(scale_random : Float32) #

Random size variation, as a fraction.


def scale_start : Float32 #

Size multiplier when a particle is born.


def scale_start=(scale_start : Float32) #

Size multiplier when a particle is born.


def scale_start=(v : Number) #

Sets the starting size.


def seed : Int32 | Nil #

Seed for the random generator, for repeatable effects.


def seed=(seed : Int32 | Nil) #

Seed for the random generator, for repeatable effects.


def speed : Range(Float32, Float32) #

Launch speed range in points per second. Each particle picks a random value.


def speed=(speed : Range(Float32, Float32)) #

Launch speed range in points per second. Each particle picks a random value.


def speed=(r : Range(Number, Number)) #

Sets the speed range.


def speed=(v : Number) #

Sets a fixed speed.


def spread : Float32 #

Random spread around #direction, in radians on each side. Mathf::TAU fires in every direction.


def spread=(spread : Float32) #

Random spread around #direction, in radians on each side. Mathf::TAU fires in every direction.


def spread=(v : Number) #

Sets the spread in radians.


def texture : Drawable | Nil #

Texture for each particle. nil uses a soft white circle.


def texture=(texture : Drawable | Nil) #

Texture for each particle. nil uses a soft white circle.


def update(dt : Float32) : Nil #

Advances the simulation by dt. Public so tests and tools can step it manually.


def world_space=(world_space : Bool) #

When true (the default), particles stay where they were emitted as the node moves.


def world_space? : Bool #

When true (the default), particles stay where they were emitted as the node moves.