use clap::Parser; use dungeon::*; use graphics::*; struct Game { window: Window, dungeon: Dungeon, // to ensure the most recently-pressed direction key is used: current_dir: Option<(Direction, KeyCode)>, } impl Game { fn new(window: Window) -> Self { // Initial game state let dungeon = Dungeon::new(); Self { window, dungeon, current_dir: None, } } fn player_dir(&mut self) -> Option { const MOVE_KEYS: [(Direction, [KeyCode; 2]); 4] = [ (Direction::North, [KeyCode::KEY_UP, KeyCode::KEY_W]), (Direction::West, [KeyCode::KEY_LEFT, KeyCode::KEY_A]), (Direction::South, [KeyCode::KEY_DOWN, KeyCode::KEY_S]), (Direction::East, [KeyCode::KEY_RIGHT, KeyCode::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 } fn run(&mut self) { // Main game loop while self.window.is_open() { // Handle keyboard input if self.window.is_key_pressed(KeyCode::KEY_F3) { self.window.toggle_debug(); } let inputs = PlayerInput { direction: self.player_dir(), }; // Update game state self.dungeon.update(inputs, self.window.delta_time()); // Draw a single frame self.window.draw_frame(&self.dungeon); } } } #[derive(Parser)] struct Args { /// Enable vsync #[arg(long)] vsync: bool, // Enable verbose logging #[arg(short, long)] verbose: bool, } fn main() -> Result<()> { // Parse arguments let args = Args::parse(); // Load the window let window = WindowBuilder::new() .vsync(args.vsync) .verbose(args.verbose) .build()?; Game::new(window).run(); Ok(()) }