]> git.seodisparate.com - LD53/commitdiff
Add HP, tweaks (just about done)
authorStephen Seo <seo.disparate@gmail.com>
Sun, 30 Apr 2023 10:42:16 +0000 (19:42 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sun, 30 Apr 2023 10:42:16 +0000 (19:42 +0900)
src/music.rs
src/world.rs

index 588b84b3413332aee2f0e3218a84795617fbb82f..6e783a19b7d9dc37393feb2fd2db0c88a7131eb0 100644 (file)
@@ -309,6 +309,7 @@ pub struct Music {
     factor: f32,
     factor_slowing: Option<bool>,
     factor_speeding: Option<bool>,
+    game_over: bool,
 }
 
 impl Music {
@@ -322,9 +323,26 @@ impl Music {
             factor: 1f32,
             factor_slowing: None,
             factor_speeding: None,
+            game_over: false,
         }
     }
 
+    pub fn reset(&mut self) {
+        self.started = false;
+        self.pulse1_time = 0f32;
+        self.pulse1_idx = 0;
+        self.tri_time = 0f32;
+        self.tri_idx = 0;
+        self.factor = 1f32;
+        self.factor_slowing = None;
+        self.factor_speeding = None;
+        self.game_over = false;
+    }
+
+    pub fn gameover(&mut self) {
+        self.game_over = true;
+    }
+
     pub fn speed_up(&mut self) {
         self.factor_slowing = None;
         //self.factor_speeding = Some(true);
@@ -344,6 +362,15 @@ impl Music {
         self.factor = 1f32;
     }
 
+    pub fn damaged(&self) {
+        crate::tone(
+            Pitch::D5.to_u32() | (Pitch::D1.to_u32() << 16),
+            30 << 8,
+            60,
+            TONE_NOISE,
+        )
+    }
+
     fn get_factor(&self) -> f32 {
         self.factor
     }
@@ -357,32 +384,39 @@ impl Music {
             return;
         }
 
-        if let Some(not_reverting) = &mut self.factor_slowing {
-            if *not_reverting {
-                self.factor -= SLOWDOWN_RATE;
-                if self.factor <= SLOWDOWN_MIN {
-                    *not_reverting = false;
-                    self.factor = SLOWDOWN_MIN;
-                }
-            } else {
-                self.factor += SLOWDOWN_REVERT_RATE;
-                if self.factor >= 1f32 {
-                    self.factor = 1f32;
-                    self.factor_slowing.take();
-                }
+        if self.game_over {
+            self.factor -= SLOWDOWN_RATE;
+            if self.factor <= 0f32 {
+                self.reset();
             }
-        } else if let Some(not_reverting) = &mut self.factor_speeding {
-            if *not_reverting {
-                self.factor += SPEEDUP_RATE;
-                if self.factor >= SPEEDUP_MAX {
-                    *not_reverting = false;
-                    self.factor = SPEEDUP_MAX;
+        } else {
+            if let Some(not_reverting) = &mut self.factor_slowing {
+                if *not_reverting {
+                    self.factor -= SLOWDOWN_RATE;
+                    if self.factor <= SLOWDOWN_MIN {
+                        *not_reverting = false;
+                        self.factor = SLOWDOWN_MIN;
+                    }
+                } else {
+                    self.factor += SLOWDOWN_REVERT_RATE;
+                    if self.factor >= 1f32 {
+                        self.factor = 1f32;
+                        self.factor_slowing.take();
+                    }
                 }
-            } else {
-                self.factor -= SPEEDUP_REVERT_RATE;
-                if self.factor <= 1f32 {
-                    self.factor = 1f32;
-                    self.factor_speeding.take();
+            } else if let Some(not_reverting) = &mut self.factor_speeding {
+                if *not_reverting {
+                    self.factor += SPEEDUP_RATE;
+                    if self.factor >= SPEEDUP_MAX {
+                        *not_reverting = false;
+                        self.factor = SPEEDUP_MAX;
+                    }
+                } else {
+                    self.factor -= SPEEDUP_REVERT_RATE;
+                    if self.factor <= 1f32 {
+                        self.factor = 1f32;
+                        self.factor_speeding.take();
+                    }
                 }
             }
         }
index 21ad7d278583d4a4aa93126310800af6de26eae3..1001981875a48f3c06f28f735b61bc415b75e5bf 100644 (file)
@@ -1,7 +1,7 @@
 use crate::helpers::round_f32_to_i32;
 use crate::music::Music;
 use crate::sprites::*;
-use tinyrand::{Rand, StdRand};
+use tinyrand::{Rand, Seeded, StdRand};
 
 const CAR_ANIM_FRAMES: u8 = 10;
 const MOVE_RATE: f32 = 1f32;
@@ -10,6 +10,8 @@ const SPEEDUP_INC: f32 = 0.47f32;
 const SLOWDOWN_DIV: f32 = 1.3f32;
 const BUILDING_FRAMES: u32 = 100;
 const BUILDING_RANGE: f32 = 90f32;
+const DAMAGED_FRAMES_MAX: u16 = 120;
+const GAMEOVER_SLOWDOWN_RATE: f32 = 0.01f32;
 
 #[derive(Copy, Clone, Debug, PartialEq)]
 enum Building {
@@ -50,6 +52,8 @@ pub struct World {
     status_text: Option<(&'static str, u32)>,
     score_buf: [u8; 16],
     music: Music,
+    lives: u8,
+    damaged_frames: u16,
 }
 
 impl World {
@@ -57,7 +61,7 @@ impl World {
         World {
             car_state: false,
             car_frames: 0,
-            rand: StdRand::default(),
+            rand: StdRand::seed(3),
             street_offset: 0.0f32,
             shrubs: [None, None, None, None, None, None, None, None],
             building: None,
@@ -66,12 +70,46 @@ impl World {
             is_in_range: false,
             score: 0,
             rate_multiplier: 1f32,
-            status_text: None,
+            status_text: Some(("Ludum Dare 53:\nHouse Delivery!\n\nBy: BurnedKirby", 300)),
             score_buf: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             music: Music::new(),
+            lives: 3,
+            damaged_frames: 0,
         }
     }
 
+    fn reset(&mut self) {
+        self.car_state = false;
+        self.car_frames = 0;
+        self.street_offset = 0f32;
+        for shrub in &mut self.shrubs {
+            shrub.take();
+        }
+        self.building = None;
+        self.building_frames = 0;
+        self.building_frames_max = BUILDING_FRAMES;
+        self.is_in_range = false;
+        self.score = 0;
+        self.rate_multiplier = 1f32;
+        self.status_text = Some(("Ludum Dare 53:\nHouse Delivery!\n\nBy: BurnedKirby", 300));
+        for score in &mut self.score_buf {
+            *score = 0;
+        }
+        self.music.reset();
+        self.lives = 3;
+        self.damaged_frames = 0;
+    }
+
+    pub fn decrement_lives(&mut self) -> bool {
+        if self.lives > 0 {
+            self.lives -= 1;
+            if self.lives == 0 {
+                self.music.gameover();
+            }
+        }
+        self.lives != 0
+    }
+
     pub fn get_move_rate(&self) -> f32 {
         MOVE_RATE * self.rate_multiplier
     }
@@ -90,11 +128,28 @@ impl World {
             }
         }
 
+        if self.rate_multiplier <= 0f32 {
+            self.car_state = true;
+        }
+
         self.street_offset -= self.get_move_rate();
         if self.street_offset <= -45f32 {
             self.street_offset += 45f32;
         }
 
+        self.music.update();
+
+        if let Some((_, t)) = &mut self.status_text {
+            *t -= 1;
+            if *t == 0 {
+                self.status_text.take();
+            }
+        }
+
+        if self.damaged_frames != 0 {
+            self.damaged_frames -= 1;
+        }
+
         let mut empty_shrub_exists: Option<usize> = None;
         let move_rate = self.get_move_rate();
         for (idx, shrub) in self.shrubs.iter_mut().enumerate() {
@@ -109,6 +164,24 @@ impl World {
             }
         }
 
+        {
+            let move_rate = self.get_move_rate();
+            if let Some((x, _, _)) = &mut self.building {
+                *x -= move_rate;
+            }
+        }
+
+        if self.lives == 0 {
+            self.rate_multiplier -= GAMEOVER_SLOWDOWN_RATE;
+            if self.rate_multiplier < 0f32 {
+                self.rate_multiplier = 0f32;
+            }
+            if (gamepad & crate::BUTTON_2) != 0 {
+                self.reset();
+            }
+            return;
+        }
+
         if empty_shrub_exists.is_some() && self.rand.next_u16() % 32 == 0 {
             self.shrubs[empty_shrub_exists.unwrap()] =
                 Some((180f32, (self.rand.next_u16() % 80 + 60) as f32));
@@ -122,7 +195,6 @@ impl World {
                 self.building_frames_max = BUILDING_FRAMES + (self.rand.next_u16() % 100) as u32;
             }
         } else {
-            self.building.as_mut().unwrap().0 -= self.get_move_rate();
             let pos_ref: &f32 = &self.building.as_ref().unwrap().0;
             let building_type = self.building.as_ref().unwrap().1;
             let state_ref: &u8 = &self.building.as_ref().unwrap().2;
@@ -130,12 +202,16 @@ impl World {
                 self.is_in_range = true;
             } else if building_type == Building::House && *pos_ref < -(HOUSE0_WIDTH as f32) {
                 if self.is_in_range {
-                    self.rate_multiplier /= 2f32;
-                    if self.rate_multiplier < 1f32 {
-                        self.rate_multiplier = 1f32;
+                    if self.decrement_lives() {
+                        self.rate_multiplier /= 2f32;
+                        if self.rate_multiplier < 1f32 {
+                            self.rate_multiplier = 1f32;
+                        }
+                        self.status_text = Some(("Miss!\nSlow down!", 120));
+                        self.music.slow_down();
+                        self.damaged_frames = DAMAGED_FRAMES_MAX;
                     }
-                    self.status_text = Some(("Miss!\nSlow down!", 120));
-                    self.music.slow_down();
+                    self.music.damaged();
                 }
                 self.building.take();
                 self.is_in_range = false;
@@ -183,26 +259,21 @@ impl World {
                     }
                     Building::WrongHouse => {
                         self.building.as_mut().unwrap().2 = 1;
-                        self.rate_multiplier /= SLOWDOWN_DIV;
-                        if self.rate_multiplier < 1f32 {
-                            self.rate_multiplier = 1f32;
+                        if self.decrement_lives() {
+                            self.rate_multiplier /= SLOWDOWN_DIV;
+                            if self.rate_multiplier < 1f32 {
+                                self.rate_multiplier = 1f32;
+                            }
+                            self.status_text = Some(("Oh no!\nSlow down!", 120));
+                            self.music.slow_down();
+                            self.damaged_frames = DAMAGED_FRAMES_MAX;
                         }
-                        self.status_text = Some(("Oh no!\nSlow down!", 120));
-                        self.music.slow_down();
+                        self.music.damaged();
                     }
                 }
                 self.music.start();
             }
         }
-
-        if let Some((_, t)) = &mut self.status_text {
-            *t -= 1;
-            if *t == 0 {
-                self.status_text.take();
-            }
-        }
-
-        self.music.update();
     }
 
     pub fn draw(&mut self) {
@@ -283,10 +354,12 @@ impl World {
             }
         }
 
-        if self.car_state {
-            crate::blit(&CAR0, 10, 103, CAR0_WIDTH, CAR0_HEIGHT, CAR0_FLAGS);
-        } else {
-            crate::blit(&CAR1, 10, 103, CAR1_WIDTH, CAR1_HEIGHT, CAR1_FLAGS);
+        if self.damaged_frames % 4 < 2 || self.lives == 0 {
+            if self.car_state {
+                crate::blit(&CAR0, 10, 103, CAR0_WIDTH, CAR0_HEIGHT, CAR0_FLAGS);
+            } else {
+                crate::blit(&CAR1, 10, 103, CAR1_WIDTH, CAR1_HEIGHT, CAR1_FLAGS);
+            }
         }
 
         if self.is_in_range {
@@ -294,9 +367,13 @@ impl World {
                 *crate::DRAW_COLORS = 0x1;
             }
             if let Some((_, Building::WrongHouse, _)) = self.building {
-                crate::text("Don't Press!", 5, 5);
+                crate::text("Don't Press!", 5, 10);
+            } else if let Some((_, Building::SpeedUp, _)) = self.building {
+                crate::text("Tap or Press X?", 5, 10);
+            } else if let Some((_, Building::SlowDown, _)) = self.building {
+                crate::text("Tap or Press X?", 5, 10);
             } else {
-                crate::text("Tap or Press X!", 5, 5);
+                crate::text("Tap or Press X!", 5, 10);
             }
         }
 
@@ -304,6 +381,14 @@ impl World {
             *crate::DRAW_COLORS = 0x1;
         }
 
+        match self.lives {
+            3 => crate::text("3 HP", 0, 0),
+            2 => crate::text("2 HP", 0, 0),
+            1 => crate::text("1 HP", 0, 0),
+            0 => crate::text("0 HP", 0, 0),
+            _ => unreachable!(),
+        }
+
         if let Some((s, t)) = self.status_text {
             if (t / 10) % 4 <= 1 {
                 crate::text(s, 20, 30);
@@ -328,9 +413,23 @@ impl World {
             for i in width..16 {
                 self.score_buf[i] = 0;
             }
-            crate::custom_text(self.score_buf, width, 160 - width as i32 * 8, 0);
+            if self.lives > 0 {
+                crate::custom_text(self.score_buf, width, 160 - width as i32 * 8, 0);
+            } else {
+                crate::text("GAME OVER", 40, 40);
+                crate::text("Score:", 50, 50);
+                crate::custom_text(self.score_buf, width, 70 - (width / 2) as i32 * 8, 60);
+                crate::text("Press Z to restart", 10, 70);
+            }
         } else {
-            crate::text("99999999999999", 160 - 10 * 8, 0);
+            if self.lives > 0 {
+                crate::text("99999999999999", 160 - 10 * 8, 0);
+            } else {
+                crate::text("GAME OVER", 40, 40);
+                crate::text("Score:", 50, 50);
+                crate::text("99999999999999", 70 - 7 * 8, 60);
+                crate::text("Press Z to restart", 10, 70);
+            }
         }
     }
 }