survivor

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

commit
65722a52e58cd9639ae676d6de9811be86d4263e
parent
84670de341ef6ef4a4a334569f1a320669798a10
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-02-18 21:58
structure main loop

Diffstat

M src/main.rs 151 +++++++++++++++++++++++++++++++++----------------------------

1 files changed, 81 insertions, 70 deletions


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

@@ -145,17 +145,6 @@ fn main() {
  145   145         let time1 = time::Instant::now();
  146   146         let dt = (time1 - time0).as_secs_f32();
  147   147 
  148    -1         clear(&mut screen);
  149    -1         circle(&mut screen, width / 2.0, height / 2.0, player_attack_radius, [0x00, 0xff, 0x00]);
  150    -1 
  151    -1         for diamond in diamonds.iter() {
  152    -1             let sx = diamond.x - player_x + width / 2.0;
  153    -1             let sy = diamond.y - player_y + height / 2.0;
  154    -1             sprite(&mut screen, sx, sy, &sprites::DIAMOND, false);
  155    -1         }
  156    -1 
  157    -1         sprite(&mut screen, width / 2.0, height / 2.0, &sprites::HERO, player_face == Dir::Left);
  158    -1 
  159   148         match input.getch() {
  160   149             Some(b'w') => { player_dir = Dir::Up },
  161   150             Some(b'A') => { player_dir = Dir::Up },
@@ -170,6 +159,7 @@ fn main() {
  170   159             _ => {},
  171   160         }
  172   161 
   -1   162         // move
  173   163         match player_dir {
  174   164             Dir::Up => { player_y -= player_speed * dt },
  175   165             Dir::Right => { player_x += player_speed * dt },
@@ -178,54 +168,6 @@ fn main() {
  178   168             Dir::Stop => {},
  179   169         }
  180   170 
  181    -1         enemies = enemies.into_iter().filter(|e| {
  182    -1             (e.y - player_y).abs() < height
  183    -1             && (e.x - player_x).abs() < width
  184    -1         }).collect();
  185    -1         while player_xp >= player_next_level {
  186    -1             player_last_level = player_next_level;
  187    -1             player_next_level *= 2;
  188    -1 
  189    -1             match rng.gen_range(0, 7) {
  190    -1                 PERK_POWER => { player_attack *= 1.1; },
  191    -1                 PERK_HEALTH => { player_health_max *= 1.1; },
  192    -1                 PERK_SPEED => { player_speed *= 1.1; },
  193    -1                 PERK_RADIUS => { player_attack_radius *= 1.1; },
  194    -1                 PERK_HEAL => { player_health = player_health_max; },
  195    -1                 PERK_RECOVER => { player_health_recover += 0.2 },
  196    -1                 PERK_ATTRACT => { player_diamond_radius *= 1.1; },
  197    -1                 _ => unreachable!(),
  198    -1             }
  199    -1         }
  200    -1 
  201    -1         for enemy in enemies.iter_mut() {
  202    -1             let dx = player_x - enemy.x;
  203    -1             let dy = player_y - enemy.y;
  204    -1 
  205    -1             let size = enemy.t.size + player_size;
  206    -1             if dx * dx + dy * 2.0 * dy * 2.0 < size * size {
  207    -1                 player_health -= enemy.t.power * dt;
  208    -1             }
  209    -1 
  210    -1             if dx * dx + dy * dy < player_attack_radius * player_attack_radius {
  211    -1                 enemy.health -= player_attack * dt;
  212    -1             }
  213    -1         }
  214    -1 
  215    -1         player_health = (player_health + player_health_recover * dt).min(player_health_max);
  216    -1 
  217    -1         diamonds = diamonds.into_iter().filter(|diamond| {
  218    -1             let dx = player_x - diamond.x;
  219    -1             let dy = player_y - diamond.y;
  220    -1             let d = (dx * dx + dy * dy).sqrt();
  221    -1             if d < player_diamond_radius {
  222    -1                 player_xp += 1;
  223    -1                 return false;
  224    -1             } else{
  225    -1                 return true;
  226    -1             }
  227    -1         }).collect();
  228    -1 
  229   171         for i in 0..enemies.len() {
  230   172             let enemy = &enemies[i];
  231   173 
@@ -260,28 +202,77 @@ fn main() {
  260   202             enemy.y += dy * enemy.t.speed * dt;
  261   203         }
  262   204 
  263    -1         if player_health < 0.0 {
  264    -1             println!("\nyou died (score: {})", player_xp);
  265    -1             break;
   -1   205         // recover
   -1   206         player_health = (player_health + player_health_recover * dt).min(player_health_max);
   -1   207 
   -1   208         // despawn
   -1   209         enemies = enemies.into_iter().filter(|e| {
   -1   210             (e.y - player_y).abs() < height
   -1   211             && (e.x - player_x).abs() < width
   -1   212         }).collect();
   -1   213 
   -1   214         // interact with enemies
   -1   215         for enemy in enemies.iter_mut() {
   -1   216             let dx = player_x - enemy.x;
   -1   217             let dy = player_y - enemy.y;
   -1   218 
   -1   219             let size = enemy.t.size + player_size;
   -1   220             if dx * dx + dy * 2.0 * dy * 2.0 < size * size {
   -1   221                 player_health -= enemy.t.power * dt;
   -1   222             }
   -1   223 
   -1   224             if dx * dx + dy * dy < player_attack_radius * player_attack_radius {
   -1   225                 enemy.health -= player_attack * dt;
   -1   226             }
  266   227         }
  267   228 
  268    -1         for enemy in enemies.iter() {
  269    -1             if enemy.health < 0.0 {
   -1   229         enemies = enemies.into_iter().filter(|enemy| {
   -1   230             if enemy.health <= 0.0 {
  270   231                 diamonds.push(Diamond {
  271   232                     x: enemy.x,
  272   233                     y: enemy.y,
  273   234                 });
   -1   235                 return false;
   -1   236             } else {
   -1   237                 return true;
  274   238             }
   -1   239         }).collect();
   -1   240 
   -1   241         if player_health < 0.0 {
   -1   242             println!("\nyou died (score: {})", player_xp);
   -1   243             break;
  275   244         }
  276    -1         enemies = enemies.into_iter().filter(|e| e.health > 0.0).collect();
  277   245 
  278    -1         enemies.sort_unstable_by_key(|m| m.y as i32);
  279    -1         for enemy in enemies.iter() {
  280    -1             let sx = enemy.x - player_x + width / 2.0;
  281    -1             let sy = enemy.y - player_y + height / 2.0;
  282    -1             sprite(&mut screen, sx, sy, enemy.t.sprite, enemy.x > player_x);
   -1   246         // interact with diamonds
   -1   247         diamonds = diamonds.into_iter().filter(|diamond| {
   -1   248             let dx = player_x - diamond.x;
   -1   249             let dy = player_y - diamond.y;
   -1   250             let d = (dx * dx + dy * dy).sqrt();
   -1   251             if d < player_diamond_radius {
   -1   252                 player_xp += 1;
   -1   253                 return false;
   -1   254             } else{
   -1   255                 return true;
   -1   256             }
   -1   257         }).collect();
   -1   258 
   -1   259         while player_xp >= player_next_level {
   -1   260             player_last_level = player_next_level;
   -1   261             player_next_level *= 2;
   -1   262 
   -1   263             match rng.gen_range(0, 7) {
   -1   264                 PERK_POWER => { player_attack *= 1.1; },
   -1   265                 PERK_HEALTH => { player_health_max *= 1.1; },
   -1   266                 PERK_SPEED => { player_speed *= 1.1; },
   -1   267                 PERK_RADIUS => { player_attack_radius *= 1.1; },
   -1   268                 PERK_HEAL => { player_health = player_health_max; },
   -1   269                 PERK_RECOVER => { player_health_recover += 0.2 },
   -1   270                 PERK_ATTRACT => { player_diamond_radius *= 1.1; },
   -1   271                 _ => unreachable!(),
   -1   272             }
  283   273         }
  284   274 
   -1   275         // spawn
  285   276         if rng.gen_f32() < dt * 2.0 {
  286   277             let (spawn_x, spawn_y) = match rng.gen_range(0, 4) {
  287   278                 0 => (
@@ -311,12 +302,32 @@ fn main() {
  311   302             i_enemy += 1;
  312   303         }
  313   304 
   -1   305         // render
   -1   306         clear(&mut screen);
   -1   307         circle(&mut screen, width / 2.0, height / 2.0, player_attack_radius, [0x00, 0xff, 0x00]);
   -1   308 
   -1   309         for diamond in diamonds.iter() {
   -1   310             let sx = diamond.x - player_x + width / 2.0;
   -1   311             let sy = diamond.y - player_y + height / 2.0;
   -1   312             sprite(&mut screen, sx, sy, &sprites::DIAMOND, false);
   -1   313         }
   -1   314 
   -1   315         sprite(&mut screen, width / 2.0, height / 2.0, &sprites::HERO, player_face == Dir::Left);
   -1   316 
   -1   317         enemies.sort_unstable_by_key(|e| e.y as i32);
   -1   318         for enemy in enemies.iter() {
   -1   319             let sx = enemy.x - player_x + width / 2.0;
   -1   320             let sy = enemy.y - player_y + height / 2.0;
   -1   321             sprite(&mut screen, sx, sy, enemy.t.sprite, enemy.x > player_x);
   -1   322         }
   -1   323 
  314   324         bar(&mut screen, 0, (player_xp - player_last_level) as f32 / (player_next_level - player_last_level) as f32, [0x00, 0x00, 0xff]);
  315   325         let h = screen.height;
  316   326         bar(&mut screen, h - 3, player_health / player_health_max, [0xff, 0x00, 0x00]);
  317   327 
  318   328         screen.render();
  319   329 
   -1   330         // sleep
  320   331         let time2 = time::Instant::now();
  321   332         if TICK > time2 - time1 {
  322   333             thread::sleep(TICK - (time2 - time1));