1use game_gem::prelude::*;
6
7struct ParticlesExample {
8 emitters: Vec<ParticleEmitter>,
9}
10
11impl GameState for ParticlesExample {
12 fn on_enter(&mut self, _ctx: &mut Context) {
13 let mut fire = ParticleEmitter::new(vec2(400.0, 500.0));
15 fire.configure(|cfg| {
16 cfg
17 .rate(80.0)
18 .shape(EmitterShape::Line { x1: 370.0, y1: 500.0, x2: 430.0, y2: 500.0 })
19 .speed(80.0, 200.0)
20 .angle(std::f32::consts::PI * 1.1, std::f32::consts::PI * 1.9)
21 .size(3.0, 10.0)
22 .lifetime(0.3, 1.0)
23 .gravity(0.0, -80.0)
24 .color_start(Color::from_hex("#FF6600").unwrap())
25 .color_end(Color::from_hex("#FFFF00").unwrap())
26 .size_end(0.0)
27 .drag(1.5);
28 });
29 self.emitters.push(fire);
30
31 let mut sparkles = ParticleEmitter::new(vec2(400.0, 300.0));
33 sparkles.configure(|cfg| {
34 cfg
35 .rate(30.0)
36 .shape(EmitterShape::Circle { cx: 400.0, cy: 300.0, radius: 150.0 })
37 .speed(10.0, 50.0)
38 .angle(0.0, std::f32::consts::TAU)
39 .size(2.0, 6.0)
40 .lifetime(0.5, 1.5)
41 .gravity(0.0, 20.0)
42 .color_start(Color::from_hex("#FFFFFF").unwrap())
43 .color_end(Color::TRANSPARENT)
44 .size_end(0.0);
45 });
46 self.emitters.push(sparkles);
47 }
48
49 fn update(&mut self, ctx: &mut Context) {
50 let dt = ctx.time.delta() as f32;
51
52 self.emitters[0].position.x = ctx.input.mouse.position.x;
54 self.emitters[0].position.y = ctx.screen_height() - 50.0;
55
56 if ctx.input.mouse.is_pressed(MouseButton::Left) {
58 self.emitters[1].position = ctx.input.mouse.position;
59 self.emitters[1].burst_now(50);
60 }
61
62 for emitter in &mut self.emitters {
64 emitter.update(dt);
65 }
66
67 if ctx.input.keyboard.is_pressed(KeyCode::Escape) {
68 ctx.quit();
69 }
70 }
71
72 fn render(&mut self, ctx: &mut Context) {
73 ctx.graphics.clear(Color::from_hex("#0A0A1A").unwrap());
74
75 for emitter in &self.emitters {
77 for particle in emitter.particles() {
78 if !particle.alive {
79 continue;
80 }
81 ctx.graphics.draw_circle(
82 particle.position.x,
83 particle.position.y,
84 particle.size,
85 particle.color,
86 );
87 }
88 }
89
90 ctx.graphics.draw_text(
92 &format!("Particles: {}", self.emitters.iter().map(|e| e.alive_count()).sum::<usize>()),
93 10.0, 10.0, 18.0, Color::WHITE,
94 );
95 ctx.graphics.draw_text(
96 "Move mouse = fire | Click = sparkles | Esc = quit",
97 10.0, 35.0, 14.0, Color::LIGHT_GRAY,
98 );
99 }
100}
101
102fn main() {
103 let example = ParticlesExample {
104 emitters: Vec::new(),
105 };
106
107 Game::new()
108 .window_title("game-gem: Particles Example")
109 .window_size(800, 600)
110 .clear_color(Color::from_hex("#0A0A1A").unwrap())
111 .run(example);
112}