summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs145
1 files changed, 106 insertions, 39 deletions
diff --git a/src/main.rs b/src/main.rs
index d51fdfd..391bb90 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,7 +2,7 @@ mod game;
2mod renderer; 2mod renderer;
3mod texture; 3mod texture;
4 4
5use game::Game; 5use game::{Game, GameState};
6use minifb::{Key, Window, WindowOptions}; 6use minifb::{Key, Window, WindowOptions};
7use renderer::Renderer; 7use renderer::Renderer;
8use std::time::Instant; 8use std::time::Instant;
@@ -11,19 +11,22 @@ const SCREEN_W: usize = 640;
11const SCREEN_H: usize = 480; 11const SCREEN_H: usize = 480;
12 12
13fn main() { 13fn main() {
14 println!("=== DOOM-LIKE MAZE ==="); 14 println!("=== DUNGEON CRAWLER ===");
15 println!("Find the exit!"); 15 println!(" W / S — forward / backward");
16 println!(" W / Up — forward"); 16 println!(" A / D — strafe left / right");
17 println!(" S / Down — backward"); 17 println!(" Q / E — turn 90° left / right");
18 println!(" A / D — strafe left / right"); 18 println!(" Space — attack");
19 println!(" ← / → — turn"); 19 println!(" Z — use selected inventory item");
20 println!(" Esc — quit\n"); 20 println!(" X — discard selected inventory item");
21 println!(" 1-4 — select inventory slot");
22 println!(" C — skip turn");
23 println!(" Esc — quit\n");
21 24
22 let mut game = Game::new(); 25 let mut game = Game::new();
23 let renderer = Renderer::new(SCREEN_W, SCREEN_H); 26 let renderer = Renderer::new(SCREEN_W, SCREEN_H);
24 27
25 let mut window = Window::new( 28 let mut window = Window::new(
26 "Maze — Find the Exit!", 29 "Dungeon Crawler",
27 SCREEN_W, 30 SCREEN_W,
28 SCREEN_H, 31 SCREEN_H,
29 WindowOptions::default(), 32 WindowOptions::default(),
@@ -34,45 +37,109 @@ fn main() {
34 let mut last = Instant::now(); 37 let mut last = Instant::now();
35 let frame_budget = std::time::Duration::from_micros(16600); // ~60 fps 38 let frame_budget = std::time::Duration::from_micros(16600); // ~60 fps
36 39
40 // Track previous key state for edge-triggered actions.
41 let mut prev_w = false;
42 let mut prev_s = false;
43 let mut prev_a = false;
44 let mut prev_d = false;
45 let mut prev_q = false;
46 let mut prev_e = false;
47 let mut prev_space = false;
48 let mut prev_z = false;
49 let mut prev_x = false;
50 let mut prev_c = false;
51 let mut prev_1 = false;
52 let mut prev_2 = false;
53 let mut prev_3 = false;
54 let mut prev_4 = false;
55
37 while window.is_open() && !window.is_key_down(Key::Escape) { 56 while window.is_open() && !window.is_key_down(Key::Escape) {
38 let frame_start = Instant::now(); 57 let frame_start = Instant::now();
39 let dt = (frame_start - last).as_secs_f64().min(0.1); 58 let dt = (frame_start - last).as_secs_f64().min(0.1);
40 last = frame_start; 59 last = frame_start;
41 60
42 // ---- input ---- 61 // ---- read current key states ----
43 let move_speed = 2.8; 62 let cur_w = window.is_key_down(Key::W);
44 let turn_speed = 2.8; 63 let cur_s = window.is_key_down(Key::S);
45 let strafe_speed = 2.2; 64 let cur_a = window.is_key_down(Key::A);
65 let cur_d = window.is_key_down(Key::D);
66 let cur_q = window.is_key_down(Key::Q);
67 let cur_e = window.is_key_down(Key::E);
68 let cur_space = window.is_key_down(Key::Space);
69 let cur_z = window.is_key_down(Key::Z);
70 let cur_x = window.is_key_down(Key::X);
71 let cur_c = window.is_key_down(Key::C);
72 let cur_1 = window.is_key_down(Key::Key1);
73 let cur_2 = window.is_key_down(Key::Key2);
74 let cur_3 = window.is_key_down(Key::Key3);
75 let cur_4 = window.is_key_down(Key::Key4);
46 76
47 if window.is_key_down(Key::Left) { 77 // ---- input (edge-triggered, only in WaitingForInput) ----
48 game.rotate(-turn_speed * dt); 78 if game.can_act() {
79 if cur_w && !prev_w {
80 game.move_forward();
81 } else if cur_s && !prev_s {
82 game.move_backward();
83 } else if cur_a && !prev_a {
84 game.strafe_left();
85 } else if cur_d && !prev_d {
86 game.strafe_right();
87 } else if cur_q && !prev_q {
88 game.turn_left();
89 } else if cur_e && !prev_e {
90 game.turn_right();
91 } else if cur_space && !prev_space {
92 game.attack();
93 } else if cur_z && !prev_z {
94 game.use_item();
95 } else if cur_x && !prev_x {
96 game.discard_item();
97 } else if cur_c && !prev_c {
98 game.skip_turn();
99 } else if cur_1 && !prev_1 {
100 game.select_slot(0);
101 } else if cur_2 && !prev_2 {
102 game.select_slot(1);
103 } else if cur_3 && !prev_3 {
104 game.select_slot(2);
105 } else if cur_4 && !prev_4 {
106 game.select_slot(3);
107 }
49 } 108 }
50 if window.is_key_down(Key::Right) { 109
51 game.rotate(turn_speed * dt); 110 // Update previous states.
111 prev_w = cur_w;
112 prev_s = cur_s;
113 prev_a = cur_a;
114 prev_d = cur_d;
115 prev_q = cur_q;
116 prev_e = cur_e;
117 prev_space = cur_space;
118 prev_z = cur_z;
119 prev_x = cur_x;
120 prev_c = cur_c;
121 prev_1 = cur_1;
122 prev_2 = cur_2;
123 prev_3 = cur_3;
124 prev_4 = cur_4;
125
126 // ---- advance animations / state machine ----
127 game.update_animation(dt);
128
129 // ---- death check ----
130 if game.state == GameState::GameOver {
131 let score = (game.kills * 100) + (game.depth.pow(2) * 50) + 500; // fists = base damage 1
132 println!(
133 "You had become yet another legend of this dungeon.\nScore: {}",
134 score
135 );
136 std::process::exit(0);
52 } 137 }
53 // Combine forward + strafe into one displacement (prevents two-step 138
54 // wall clipping when pressing W+D / W+A near a wall). 139 // ---- win check (placeholder — becomes staircase in Phase 1) ----
55 let fwd = if window.is_key_down(Key::W) || window.is_key_down(Key::Up) {
56 move_speed * dt
57 } else if window.is_key_down(Key::S) || window.is_key_down(Key::Down) {
58 -move_speed * dt
59 } else {
60 0.0
61 };
62 let strf = if window.is_key_down(Key::D) {
63 strafe_speed * dt
64 } else if window.is_key_down(Key::A) {
65 -strafe_speed * dt
66 } else {
67 0.0
68 };
69 game.apply_movement(fwd, strf);
70
71 // ---- win condition ----
72 if game.check_win() { 140 if game.check_win() {
73 println!("🎉 You found the exit! Generating a new maze…"); 141 println!("You found the exit in {} heartbeats!", game.heartbeats());
74 game = Game::new(); 142 std::process::exit(0);
75 last = Instant::now(); // avoid huge dt spike
76 } 143 }
77 144
78 // ---- render ---- 145 // ---- render ----