use dungeon::{Dungeon, UpdateResult, player_input::PlayerInput, pos::Direction}; use graphics::{Key, Window}; pub struct Game { window: Window, dungeon: Dungeon, // to ensure the most recently-pressed direction key is used: current_dir: Option<(Direction, Key)>, } impl Game { pub fn new(window: Window, seed: Option) -> Self { let dungeon = match seed { Some(s) => Dungeon::new(s), None => Dungeon::random(), }; Self { window, dungeon, current_dir: None, } } fn player_dir(&mut self) -> Option { const MOVE_KEYS: [(Direction, [Key; 2]); 4] = [ (Direction::North, [Key::Up, Key::W]), (Direction::West, [Key::Left, Key::A]), (Direction::South, [Key::Down, Key::S]), (Direction::East, [Key::Right, Key::D]), ]; // if a key was just pressed, use it for the new direction to move in for (dir, keys) in MOVE_KEYS { for key in keys { if self.window.is_key_pressed(key) { self.current_dir = Some((dir, key)); return Some(dir); } } } // otherwise, use existing direction, so long as the key is still down match self.current_dir { Some((dir, key)) if self.window.is_key_down(key) => return Some(dir), _ => self.current_dir = None, } // otherwise, use any key that is already down for (dir, keys) in MOVE_KEYS { for key in keys { if self.window.is_key_down(key) { self.current_dir = Some((dir, key)); return Some(dir); } } } // otherwise, no direction key is pressed, so return None None } pub fn run(&mut self) { // Main game loop while self.window.is_open() { // Handle debug keys if self.window.is_key_pressed(Key::F3) { self.window.toggle_debug(); } if self.window.is_key_pressed(Key::F4) { self.dungeon .msg .set_message("Lorem ipsum dolor sit amet consectetur adipiscing elit"); } let inputs = PlayerInput { direction: self.player_dir(), interact: self.window.is_key_pressed(Key::Return), }; // Update game state let result = self .dungeon .update(inputs, self.window.delta_time().as_secs_f32()); match result { UpdateResult::EntityMovement => {} UpdateResult::NextFloor => { // TODO: stairs audio } UpdateResult::MessageUpdated(changed) => { if changed { self.window.audio().speak.play(); } } } // Update on screen message if self.dungeon.msg.update(inputs) { self.window.audio().speak.play(); } // Draw a single frame self.window.draw_frame(&self.dungeon); } } }