diff --git a/src/game_state.rs b/src/game_state.rs index 784fa4d6e8222987b139688af573c169959de36f..f5aed50c44c24c3c7a22978fc100f9edd4b819ad 100644 --- a/src/game_state.rs +++ b/src/game_state.rs @@ -14,7 +14,7 @@ use run::Run; use textures::Textures; use crate::game_state::tile::Tile; use tetra::math::Vec2; -use std::cmp::min; +use std::cmp::{min, max}; use rand::{thread_rng, Rng}; use tetra::graphics::text::{VectorFontBuilder, Font, Text}; use crate::game_state::combat_log::PlayerAction; @@ -27,20 +27,23 @@ pub struct GameState { high_score: usize, textures: Textures, font: Font, + font_huge: Font, } impl GameState { pub fn new(ctx: &mut Context) -> tetra::Result<GameState> { let textures = Textures::init(ctx); let font = VectorFontBuilder::new("./resources/corbel.ttf")?.with_size(ctx, 16.0); + let huge = VectorFontBuilder::new("./resources/corbel.ttf")?.with_size(ctx, 50.0); if textures.is_ok() { - if font.is_ok() { + if font.is_ok() && huge.is_ok() { Ok(GameState { current_run: Run::new(), high_score: 0, textures: textures.unwrap(), font: font.unwrap(), + font_huge: huge.unwrap(), }) } else { Err(font.err().unwrap()) @@ -64,10 +67,15 @@ impl State for GameState { fn draw(&mut self, ctx: &mut Context) -> tetra::Result { graphics::clear(ctx, Color::rgb(0.220, 0.220, 0.220)); - self.draw_board(ctx); + if self.current_run.player.current_hp > 0 { + self.draw_board(ctx); + } else { + self.draw_game_over(ctx); + } self.draw_stats(ctx); self.draw_combat_log(ctx); + Ok(()) } } @@ -85,12 +93,20 @@ impl GameState { return match key { Key::CapsLock => false, + Key::N => self.create_new_run(), Key::W | Key::A | Key::S | Key::D | Key::Down | Key::Up | Key::Right | Key::Left => GameState::handle_user_movement(self, key), Key::Space => true, _ => false }; } + fn create_new_run(&mut self) -> bool { + if self.current_run.player.current_hp == 0 { + self.current_run = Run::new(); + } + false + } + fn handle_user_movement(&mut self, key: Key) -> bool { let player_position = self.current_run.level.get_player_position(); let target_position = GameState::calculate_target_position(player_position, key); @@ -104,7 +120,7 @@ impl GameState { Tile::Empty => { self.current_run.level.move_player_to(target_position); self.current_run.combat_log.player_action = Option::from(Move); - }, + } Tile::Wall => return false, Tile::Enemy(id) => self.attack_enemy(id, target_position), _ => () @@ -185,6 +201,14 @@ impl GameState { } else { self.current_run.combat_log.damage_taken = None } + + if self.current_run.player.current_hp == 0 { + self.finish_run(); + } + } + + fn finish_run(&mut self) { + self.high_score = max(self.high_score, self.current_run.level_count); } fn check_is_neighbor(a: Point, b: Point) -> bool { @@ -195,11 +219,11 @@ impl GameState { fn check_neighbor_uint(a: usize, b: usize) -> bool { if a > b { if a - b == 1 { - return true + return true; } } else if b > a { if b - a == 1 { - return true + return true; } } false @@ -263,6 +287,12 @@ impl GameState { // DRAWING HELPERS impl GameState { + fn draw_game_over(&mut self, ctx: &mut Context) { + Text::new("YOU ARE DEAD", self.font_huge.clone()) + .draw(ctx, Vec2::new(500.0, 400.0)); + self.draw_string("For a new run, press 'N'!".parse().unwrap(), 500.0, 460.0, ctx); + } + fn draw_board(&mut self, ctx: &mut Context) { GameState::draw_boundary(self, ctx); GameState::draw_tiles(self, ctx); @@ -363,7 +393,7 @@ impl GameState { format!("You attacked for {} damage. The enemy has {} hit points remaining.", damage_done, remaining_hp), 300.0, text_top, - ctx + ctx, ), None => () };