mod game; mod renderer; mod texture; use game::Game; use minifb::{Key, Window, WindowOptions}; use renderer::Renderer; use std::time::Instant; const SCREEN_W: usize = 640; const SCREEN_H: usize = 480; fn main() { println!("=== DOOM-LIKE MAZE ==="); println!("Find the exit!"); println!(" W / Up — forward"); println!(" S / Down — backward"); println!(" A / D — strafe left / right"); println!(" ← / → — turn"); println!(" Esc — quit\n"); let mut game = Game::new(); let renderer = Renderer::new(SCREEN_W, SCREEN_H); let mut window = Window::new( "Maze — Find the Exit!", SCREEN_W, SCREEN_H, WindowOptions::default(), ) .expect("Failed to create window"); let mut framebuffer = vec![0u32; SCREEN_W * SCREEN_H]; let mut last = Instant::now(); let frame_budget = std::time::Duration::from_micros(16600); // ~60 fps while window.is_open() && !window.is_key_down(Key::Escape) { let frame_start = Instant::now(); let dt = (frame_start - last).as_secs_f64().min(0.1); last = frame_start; // ---- input ---- let move_speed = 2.8; let turn_speed = 2.8; let strafe_speed = 2.2; if window.is_key_down(Key::Left) { game.rotate(-turn_speed * dt); } if window.is_key_down(Key::Right) { game.rotate(turn_speed * dt); } // Combine forward + strafe into one displacement (prevents two-step // wall clipping when pressing W+D / W+A near a wall). let fwd = if window.is_key_down(Key::W) || window.is_key_down(Key::Up) { move_speed * dt } else if window.is_key_down(Key::S) || window.is_key_down(Key::Down) { -move_speed * dt } else { 0.0 }; let strf = if window.is_key_down(Key::D) { strafe_speed * dt } else if window.is_key_down(Key::A) { -strafe_speed * dt } else { 0.0 }; game.apply_movement(fwd, strf); // ---- win condition ---- if game.check_win() { println!("🎉 You found the exit! Generating a new maze…"); game = Game::new(); last = Instant::now(); // avoid huge dt spike } // ---- render ---- renderer.render(&game, &mut framebuffer); window .update_with_buffer(&framebuffer, SCREEN_W, SCREEN_H) .unwrap(); // Sleep the remainder of the frame budget (saves CPU). let elapsed = frame_start.elapsed(); if elapsed < frame_budget { std::thread::sleep(frame_budget - elapsed); } } }