]> git.seodisparate.com - LudumDare45_StartWithNothing/commitdiff
Gave planets a particle system
authorStephen Seo <seo.disparate@gmail.com>
Sun, 6 Oct 2019 03:53:26 +0000 (12:53 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sun, 6 Oct 2019 03:53:26 +0000 (12:53 +0900)
src/main.rs

index 4f7012b03e10615c779bd5338d7dfd7322ab4699..1a0dd69759fb8540ddbca5c26f41094c4726213c 100644 (file)
@@ -26,9 +26,9 @@ const DOUBLE_CLICK_TIME: f64 = 350.0;
 
 fn interp_sq_inv(x: f32) -> f32 {
     if x < 0.0 {
-        return 0.0
+        return 0.0;
     } else if x > 1.0 {
-        return 1.0
+        return 1.0;
     }
     let y = x - 1.0;
     -y * y + 1.0
@@ -36,9 +36,9 @@ fn interp_sq_inv(x: f32) -> f32 {
 
 fn interp_sq(x: f32) -> f32 {
     if x < 0.0 {
-        return 0.0
+        return 0.0;
     } else if x > 1.0 {
-        return 1.0
+        return 1.0;
     }
     x * x
 }
@@ -478,15 +478,13 @@ impl Menu {
 
     fn s_08() -> Menu {
         Menu {
-            items: vec![
-                Menu::instant_text(
-                    50.0,
-                    HEIGHT_F - 90.0,
-                    35.0,
-                    true,
-                    "(Try double-clicking now...)",
-                ),
-            ],
+            items: vec![Menu::instant_text(
+                50.0,
+                HEIGHT_F - 90.0,
+                35.0,
+                true,
+                "(Try double-clicking now...)",
+            )],
         }
     }
 
@@ -494,15 +492,22 @@ impl Menu {
         Menu {
             items: vec![
                 Menu::pause(400.0, true),
-                Menu::text(50.0, HEIGHT_F - 140.0, 40.0, false,
-                    "A new planet... It has most certainly been a while."),
-            ]
+                Menu::text(
+                    50.0,
+                    HEIGHT_F - 140.0,
+                    40.0,
+                    false,
+                    "A new planet... It has most certainly been a while.",
+                ),
+            ],
         }
     }
 }
 
 struct Particle {
     rect: Rectangle,
+    circle: Circle,
+    is_rect: bool,
     velx: f32,
     vely: f32,
     velr: f32,
@@ -517,9 +522,12 @@ struct ParticleSystem {
     spawn_time: f64,
     lifetime: f64,
     host_rect: Rectangle,
+    host_circle: Circle,
+    is_rect: bool,
     direction: Vector,
     color: Color,
     opacity: f32,
+    vel_multiplier: f32,
 }
 
 impl ParticleSystem {
@@ -527,9 +535,12 @@ impl ParticleSystem {
         spawn_time: f64,
         lifetime: f64,
         host_rect: Rectangle,
+        host_circle: Circle,
+        is_rect: bool,
         direction: Vector,
         color: Color,
         opacity: f32,
+        vel_multiplier: f32,
     ) -> Self {
         Self {
             particles: Vec::new(),
@@ -537,9 +548,12 @@ impl ParticleSystem {
             spawn_time,
             lifetime,
             host_rect,
+            host_circle,
+            is_rect,
             direction,
             color,
             opacity,
+            vel_multiplier,
         }
     }
 
@@ -549,9 +563,14 @@ impl ParticleSystem {
             if self.particles[i].life_timer > self.particles[i].lifetime {
                 self.particles.swap_remove(i);
             } else {
-                self.particles[i].rect.pos.x += self.particles[i].velx * dt as f32;
-                self.particles[i].rect.pos.y += self.particles[i].vely * dt as f32;
-                self.particles[i].r += self.particles[i].velr * dt as f32;
+                if self.is_rect {
+                    self.particles[i].rect.pos.x += self.particles[i].velx * dt as f32;
+                    self.particles[i].rect.pos.y += self.particles[i].vely * dt as f32;
+                    self.particles[i].r += self.particles[i].velr * dt as f32;
+                } else {
+                    self.particles[i].circle.pos.x += self.particles[i].velx * dt as f32;
+                    self.particles[i].circle.pos.y += self.particles[i].vely * dt as f32;
+                }
             }
         }
 
@@ -560,16 +579,21 @@ impl ParticleSystem {
             self.spawn_timer -= self.spawn_time;
             self.particles.push(Particle {
                 rect: self.host_rect,
-                velx: rand::thread_rng()
+                circle: self.host_circle,
+                is_rect: self.is_rect,
+                velx: (rand::thread_rng()
                     .gen_range(-PARTICLE_RAND_VEL_RANGE, PARTICLE_RAND_VEL_RANGE)
-                    + self.direction.x,
-                vely: rand::thread_rng()
+                    + self.direction.x)
+                    * self.vel_multiplier,
+                vely: (rand::thread_rng()
                     .gen_range(-PARTICLE_RAND_VEL_RANGE, PARTICLE_RAND_VEL_RANGE)
-                    + self.direction.y,
+                    + self.direction.y)
+                    * self.vel_multiplier,
                 // velx: self.direction.x,
                 // vely: self.direction.y,
                 velr: rand::thread_rng()
-                    .gen_range(-PARTICLE_RAND_ROT_RANGE, PARTICLE_RAND_ROT_RANGE),
+                    .gen_range(-PARTICLE_RAND_ROT_RANGE, PARTICLE_RAND_ROT_RANGE)
+                    * self.vel_multiplier,
                 r: rand::thread_rng().gen_range(0.0, 90.0),
                 lifetime: self.lifetime,
                 life_timer: 0.0,
@@ -583,15 +607,20 @@ impl ParticleSystem {
         }
         for particle in &mut self.particles {
             self.color.a = (1.0 - (particle.life_timer / particle.lifetime) as f32) * self.opacity;
-            let pre_transform =
-                Transform::translate((-particle.rect.size.x / 2.0, -particle.rect.size.y / 2.0))
-                    * Transform::rotate(particle.r);
-            window.draw_ex(
-                &particle.rect,
-                Col(self.color),
-                transform * pre_transform,
-                1,
-            );
+            if particle.is_rect {
+                let pre_transform = Transform::translate((
+                    -particle.rect.size.x / 2.0,
+                    -particle.rect.size.y / 2.0,
+                )) * Transform::rotate(particle.r);
+                window.draw_ex(
+                    &particle.rect,
+                    Col(self.color),
+                    transform * pre_transform,
+                    1,
+                );
+            } else {
+                window.draw_ex(&particle.circle, Col(self.color), transform, 1);
+            }
         }
     }
 }
@@ -608,16 +637,27 @@ impl RotatingParticleSystem {
         spawn_time: f64,
         lifetime: f64,
         host_rect: Rectangle,
+        host_circle: Circle,
+        is_rect: bool,
         direction: Vector,
         color: Color,
         opacity: f32,
         rotation: f32,
         velr: f32,
         offset: f32,
+        vel_multiplier: f32,
     ) -> Self {
         RotatingParticleSystem {
             particle_system: ParticleSystem::new(
-                spawn_time, lifetime, host_rect, direction, color, opacity,
+                spawn_time,
+                lifetime,
+                host_rect,
+                host_circle,
+                is_rect,
+                direction,
+                color,
+                opacity,
+                vel_multiplier,
             ),
             r: rotation,
             velr,
@@ -641,17 +681,26 @@ impl RotatingParticleSystem {
         self.particle_system.direction =
             Transform::rotate(self.r) * Vector::new(0.0, -PARTICLE_RAND_VEL_DIST);
         self.particle_system.draw(window, transform);
-        let mut moved_rect = self.particle_system.host_rect;
-        moved_rect.pos += Transform::rotate(self.r) * Vector::new(self.offset, 0.0);
-        let mut solid_color = self.particle_system.color;
-        solid_color.a = self.particle_system.opacity;
-        window.draw_ex(
-            &moved_rect,
-            Col(solid_color),
-            Transform::translate((-moved_rect.size.x / 2.0, -moved_rect.size.y / 2.0))
-                * Transform::rotate(self.r * 1.3),
-            1,
-        );
+        if self.particle_system.is_rect {
+            let mut moved_rect = self.particle_system.host_rect;
+            moved_rect.pos += Transform::rotate(self.r) * Vector::new(self.offset, 0.0);
+            let mut solid_color = self.particle_system.color;
+            solid_color.a = self.particle_system.opacity;
+            window.draw_ex(
+                &moved_rect,
+                Col(solid_color),
+                transform
+                    * Transform::translate((-moved_rect.size.x / 2.0, -moved_rect.size.y / 2.0))
+                    * Transform::rotate(self.r * 1.3),
+                1,
+            );
+        } else {
+            let mut moved_cir = self.particle_system.host_circle;
+            moved_cir.pos += Transform::rotate(self.r) * Vector::new(self.offset, 0.0);
+            let mut solid_color = self.particle_system.color;
+            solid_color.a = self.particle_system.opacity;
+            window.draw_ex(&moved_cir, Col(solid_color), transform, 1);
+        }
     }
 }
 
@@ -671,12 +720,7 @@ struct ExplConvParticleSystem {
 }
 
 impl ExplConvParticleSystem {
-    fn new(
-        lifetime: f64,
-        host_circle: Circle,
-        color: Color,
-        opacity: f32,
-    ) -> Self {
+    fn new(lifetime: f64, host_circle: Circle, color: Color, opacity: f32) -> Self {
         ExplConvParticleSystem {
             particles: Vec::new(),
             lifetime,
@@ -704,7 +748,7 @@ impl ExplConvParticleSystem {
         if self.life_timer >= self.lifetime {
             if !self.particles.is_empty() {
                 self.particles.clear();
-                planets.push(Planet{ circle: self.host_circle, color: self.color, });
+                planets.push(Planet::new(self.host_circle, self.color));
                 return true;
             }
             return false;
@@ -713,15 +757,15 @@ impl ExplConvParticleSystem {
         if self.life_timer < self.lifetime / 2.0 {
             let amount = interp_sq_inv((self.life_timer / self.lifetime) as f32 * 2.0);
             for particle in &mut self.particles {
-                let dir = Transform::rotate(particle.r) * Vector::new(
-                    particle.offset * amount, 0.0);
+                let dir =
+                    Transform::rotate(particle.r) * Vector::new(particle.offset * amount, 0.0);
                 particle.circle.pos = dir + self.host_circle.pos;
             }
         } else {
             let amount = 1.0 - interp_sq(((self.life_timer / self.lifetime) as f32 - 0.5) * 2.0);
             for particle in &mut self.particles {
-                let dir = Transform::rotate(particle.r) * Vector::new(
-                    particle.offset * amount, 0.0);
+                let dir =
+                    Transform::rotate(particle.r) * Vector::new(particle.offset * amount, 0.0);
                 particle.circle.pos = dir + self.host_circle.pos;
             }
         }
@@ -734,12 +778,7 @@ impl ExplConvParticleSystem {
         }
         for particle in &mut self.particles {
             self.color.a = ((self.life_timer / self.lifetime) as f32 / 2.0 + 0.5) * self.opacity;
-            window.draw_ex(
-                &particle.circle,
-                Col(self.color),
-                transform,
-                1,
-            );
+            window.draw_ex(&particle.circle, Col(self.color), transform, 1);
         }
     }
 }
@@ -747,6 +786,36 @@ impl ExplConvParticleSystem {
 struct Planet {
     circle: Circle,
     color: Color,
+    particle_system: ParticleSystem,
+}
+
+impl Planet {
+    fn new(circle: Circle, color: Color) -> Self {
+        Planet {
+            circle,
+            color,
+            particle_system: ParticleSystem::new(
+                3500.0,
+                900.0,
+                Rectangle::new((0.0, 0.0), (1.0, 1.0)),
+                circle,
+                false,
+                Vector::new(0.0, 0.0),
+                color,
+                1.0,
+                0.3,
+            ),
+        }
+    }
+
+    fn update(&mut self, dt: f64) {
+        self.particle_system.update(dt);
+    }
+
+    fn draw(&mut self, window: &mut Window, transform: Transform) {
+        self.particle_system.draw(window, transform);
+        window.draw_ex(&self.circle, Col(self.color), transform, 1);
+    }
 }
 
 struct GameState {
@@ -802,20 +871,26 @@ impl State for GameState {
                 PP_GEN_RATE,
                 1000.0,
                 Rectangle::new((400.0, 300.0), (32.0, 32.0)),
+                Circle::new((100.0, 100.0), 32.0),
+                true,
                 Vector::new(0.0, 0.0),
                 Color::WHITE,
                 0.0,
+                1.0,
             ),
             joining_particles: RotatingParticleSystem::new(
                 PP_GEN_RATE,
                 1000.0,
                 Rectangle::new((400.0, 300.0), (16.0, 16.0)),
+                Circle::new((100.0, 100.0), 32.0),
+                true,
                 Vector::new(0.0, 0.0),
                 Color::GREEN,
                 0.0,
                 0.0,
                 0.1,
                 JOINING_FAR_DIST,
+                1.0,
             ),
             is_create_mode: false,
             click_release_time: 0.0,
@@ -852,8 +927,10 @@ impl State for GameState {
                             if self.click_release_time < DOUBLE_CLICK_TIME {
                                 if self.state == 8 {
                                     let mut expl_conv_system = ExplConvParticleSystem::new(
-                                        1500.0, Circle::new(self.mouse_pos, 20.0),
-                                        Color::GREEN, 1.0,
+                                        1500.0,
+                                        Circle::new(self.mouse_pos, 20.0),
+                                        Color::GREEN,
+                                        1.0,
                                     );
                                     expl_conv_system.activate(30, 200.0);
                                     self.expl_conv_p_systems.push(expl_conv_system);
@@ -861,8 +938,7 @@ impl State for GameState {
                                     self.state_dirty = true;
                                 }
                             }
-                        }
-                        else if self.selection_mode {
+                        } else if self.selection_mode {
                             if let Some(idx) = self.current_item {
                                 match self.state {
                                     0 => {
@@ -1182,6 +1258,9 @@ impl State for GameState {
                 self.expl_conv_p_systems.swap_remove(i);
             }
         }
+        for planet in &mut self.planets {
+            planet.update(dt);
+        }
 
         Ok(())
     }
@@ -1263,7 +1342,7 @@ impl State for GameState {
             expl_conv_ps.draw(window, Transform::IDENTITY);
         }
         for planet in &mut self.planets {
-            window.draw(&planet.circle, Col(planet.color));
+            planet.draw(window, Transform::IDENTITY);
         }
         Ok(())
     }