survivor

graphical action game for the linux terminal
git clone https://git.ce9e.org/survivor.git

commit
8a3074b5fb0209454190dc6a2e8a53570b6daf97
parent
8b457fc6faf4ac2869eb286d1bc8decd34e5fbab
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-02-19 16:44
split game.step() into subfunctions

Diffstat

M src/game.rs 142 ++++++++++++++++++++++++++++++++++++-------------------------
M src/main.rs 1 -

2 files changed, 83 insertions, 60 deletions


diff --git a/src/game.rs b/src/game.rs

@@ -68,6 +68,42 @@ impl Player {
   68    68     }
   69    69 }
   70    70 
   -1    71 impl Player {
   -1    72     pub fn recover(&mut self, dt: f32) {
   -1    73         self.health = (self.health + self.health_recover * dt).min(self.health_max);
   -1    74     }
   -1    75 
   -1    76     pub fn levelup(&mut self, rng: &mut random::Rng) {
   -1    77         while self.xp >= self.next_level {
   -1    78             self.last_level = self.next_level;
   -1    79             self.next_level *= 2;
   -1    80 
   -1    81             match rng.gen_range(0, 7) {
   -1    82                 PERK_POWER => {
   -1    83                     self.power *= 1.1;
   -1    84                 }
   -1    85                 PERK_HEALTH => {
   -1    86                     self.health_max *= 1.1;
   -1    87                 }
   -1    88                 PERK_SPEED => {
   -1    89                     self.speed *= 1.1;
   -1    90                 }
   -1    91                 PERK_RADIUS => {
   -1    92                     self.damage_radius *= 1.1;
   -1    93                 }
   -1    94                 PERK_HEAL => {
   -1    95                     self.health = self.health_max;
   -1    96                 }
   -1    97                 PERK_RECOVER => self.health_recover += 0.2,
   -1    98                 PERK_ATTRACT => {
   -1    99                     self.diamond_radius *= 1.1;
   -1   100                 }
   -1   101                 _ => unreachable!(),
   -1   102             }
   -1   103         }
   -1   104     }
   -1   105 }
   -1   106 
   71   107 pub struct Game {
   72   108     pub player: Player,
   73   109     pub diamonds: Vec<Diamond>,
@@ -94,21 +130,17 @@ impl Game {
   94   130         };
   95   131     }
   96   132 
   97    -1     pub fn step(&mut self, dt: f32) {
   98    -1         let height = win::iconvert_y(self.win.height);
   99    -1         let width = win::iconvert_x(self.win.width);
  100    -1         let sprite_height = win::iconvert_y(sprites::HEIGHT);
  101    -1         let sprite_width = win::iconvert_x(sprites::WIDTH);
  102    -1 
  103    -1         // move
   -1   133     fn move_player(&mut self, dt: f32) {
  104   134         match self.player.dir {
  105   135             Dir::Up => self.player.y -= self.player.speed * dt,
  106   136             Dir::Right => self.player.x += self.player.speed * dt,
  107   137             Dir::Down => self.player.y += self.player.speed * dt,
  108   138             Dir::Left => self.player.x -= self.player.speed * dt,
  109   139             Dir::Stop => {}
  110    -1         }
   -1   140         };
   -1   141     }
  111   142 
   -1   143     fn move_enemies(&mut self, dt: f32) {
  112   144         for i in 0..self.enemies.len() {
  113   145             let enemy = &self.enemies[i];
  114   146 
@@ -142,18 +174,42 @@ impl Game {
  142   174             enemy.x += dx * enemy.t.speed * dt;
  143   175             enemy.y += dy * enemy.t.speed * dt;
  144   176         }
   -1   177     }
  145   178 
  146    -1         // recover
  147    -1         self.player.health =
  148    -1             (self.player.health + self.player.health_recover * dt).min(self.player.health_max);
   -1   179     fn spawn_enemies(&mut self, dt: f32) {
   -1   180         let height = win::iconvert_y(self.win.height);
   -1   181         let width = win::iconvert_x(self.win.width);
   -1   182         let sprite_height = win::iconvert_y(sprites::HEIGHT);
   -1   183         let sprite_width = win::iconvert_x(sprites::WIDTH);
  149   184 
  150    -1         // despawn
   -1   185         if self.enemies.len() < MAX_ENEMIES && self.rng.gen_f32() < dt * 2.0 {
   -1   186             let (spawn_x, spawn_y) = match self.rng.gen_range(0, 4) {
   -1   187                 0 => (self.rng.gen_f32() * width, -sprite_height),
   -1   188                 1 => (width + sprite_width, self.rng.gen_f32() * height),
   -1   189                 2 => (self.rng.gen_f32() * width, height + sprite_height),
   -1   190                 3 => (-sprite_width, self.rng.gen_f32() * height),
   -1   191                 _ => unreachable!(),
   -1   192             };
   -1   193 
   -1   194             self.enemies.push(enemies::get_enemy(
   -1   195                 spawn_x + self.player.x - width / 2.0,
   -1   196                 spawn_y + self.player.y - height / 2.0,
   -1   197                 self.i_enemy,
   -1   198             ));
   -1   199             self.i_enemy += 1;
   -1   200         }
   -1   201     }
   -1   202 
   -1   203     fn despawn_enemies(&mut self) {
   -1   204         let height = win::iconvert_y(self.win.height);
   -1   205         let width = win::iconvert_x(self.win.width);
  151   206         self.enemies = std::mem::take(&mut self.enemies)
  152   207             .into_iter()
  153   208             .filter(|e| (e.y - self.player.y).abs() < height && (e.x - self.player.x).abs() < width)
  154   209             .collect();
   -1   210     }
  155   211 
  156    -1         // interact with enemies
   -1   212     fn apply_damage(&mut self, dt: f32) {
  157   213         for enemy in self.enemies.iter_mut() {
  158   214             let dx = self.player.x - enemy.x;
  159   215             let dy = self.player.y - enemy.y;
@@ -182,8 +238,9 @@ impl Game {
  182   238                 }
  183   239             })
  184   240             .collect();
   -1   241     }
  185   242 
  186    -1         // interact with diamonds
   -1   243     fn pick_diamonds(&mut self) {
  187   244         self.diamonds = std::mem::take(&mut self.diamonds)
  188   245             .into_iter()
  189   246             .filter(|diamond| {
@@ -198,56 +255,22 @@ impl Game {
  198   255                 }
  199   256             })
  200   257             .collect();
   -1   258     }
  201   259 
  202    -1         while self.player.xp >= self.player.next_level {
  203    -1             self.player.last_level = self.player.next_level;
  204    -1             self.player.next_level *= 2;
  205    -1 
  206    -1             match self.rng.gen_range(0, 7) {
  207    -1                 PERK_POWER => {
  208    -1                     self.player.power *= 1.1;
  209    -1                 }
  210    -1                 PERK_HEALTH => {
  211    -1                     self.player.health_max *= 1.1;
  212    -1                 }
  213    -1                 PERK_SPEED => {
  214    -1                     self.player.speed *= 1.1;
  215    -1                 }
  216    -1                 PERK_RADIUS => {
  217    -1                     self.player.damage_radius *= 1.1;
  218    -1                 }
  219    -1                 PERK_HEAL => {
  220    -1                     self.player.health = self.player.health_max;
  221    -1                 }
  222    -1                 PERK_RECOVER => self.player.health_recover += 0.2,
  223    -1                 PERK_ATTRACT => {
  224    -1                     self.player.diamond_radius *= 1.1;
  225    -1                 }
  226    -1                 _ => unreachable!(),
  227    -1             }
  228    -1         }
   -1   260     pub fn step(&mut self, dt: f32) {
   -1   261         self.spawn_enemies(dt);
   -1   262         self.move_player(dt);
   -1   263         self.move_enemies(dt);
   -1   264         self.despawn_enemies();
  229   265 
  230    -1         // spawn
  231    -1         if self.enemies.len() < MAX_ENEMIES && self.rng.gen_f32() < dt * 2.0 {
  232    -1             let (spawn_x, spawn_y) = match self.rng.gen_range(0, 4) {
  233    -1                 0 => (self.rng.gen_f32() * width, -sprite_height),
  234    -1                 1 => (width + sprite_width, self.rng.gen_f32() * height),
  235    -1                 2 => (self.rng.gen_f32() * width, height + sprite_height),
  236    -1                 3 => (-sprite_width, self.rng.gen_f32() * height),
  237    -1                 _ => unreachable!(),
  238    -1             };
   -1   266         self.apply_damage(dt);
   -1   267         self.pick_diamonds();
  239   268 
  240    -1             self.enemies.push(enemies::get_enemy(
  241    -1                 spawn_x + self.player.x - width / 2.0,
  242    -1                 spawn_y + self.player.y - height / 2.0,
  243    -1                 self.i_enemy,
  244    -1             ));
  245    -1             self.i_enemy += 1;
  246    -1         }
  247    -1         self.enemies.sort_unstable_by_key(|e| e.y as i32);
   -1   269         self.player.recover(dt);
   -1   270         self.player.levelup(&mut self.rng);
  248   271     }
  249   272 
  250    -1     pub fn render(&self, screen: &mut term::Screen) {
   -1   273     pub fn render(&mut self, screen: &mut term::Screen) {
  251   274         let height = win::iconvert_y(self.win.height);
  252   275         let width = win::iconvert_x(self.win.width);
  253   276 
@@ -268,6 +291,7 @@ impl Game {
  268   291         }
  269   292 
  270   293         let mut player_rendered = false;
   -1   294         self.enemies.sort_unstable_by_key(|e| e.y as i32);
  271   295         for enemy in self.enemies.iter() {
  272   296             if !player_rendered && enemy.y > self.player.y {
  273   297                 self.win.sprite(

diff --git a/src/main.rs b/src/main.rs

@@ -82,7 +82,6 @@ fn main() {
   82    82             break;
   83    83         }
   84    84 
   85    -1         // sleep
   86    85         let time2 = time::Instant::now();
   87    86         if TICK > time2 - time1 {
   88    87             thread::sleep(TICK - (time2 - time1));