Browse Source

better controls

Inderjit Gill 1 year ago
parent
commit
d12611d3ff
3 changed files with 256 additions and 42 deletions
  1. 167
    10
      src/controller.rs
  2. 82
    28
      src/game.rs
  3. 7
    4
      src/lib.rs

+ 167
- 10
src/controller.rs View File

@@ -29,6 +29,37 @@ pub struct Controller {
29 29
 
30 30
     pub start: bool,
31 31
     pub select: bool,
32
+
33
+    up_previous: bool,
34
+    down_previous: bool,
35
+    left_previous: bool,
36
+    right_previous: bool,
37
+    a_previous: bool,
38
+    b_previous: bool,
39
+    start_previous: bool,
40
+    select_previous: bool,
41
+
42
+    pub up_just_released: bool,
43
+    pub down_just_released: bool,
44
+    pub left_just_released: bool,
45
+    pub right_just_released: bool,
46
+
47
+    pub a_just_released: bool,
48
+    pub b_just_released: bool,
49
+
50
+    pub start_just_released: bool,
51
+    pub select_just_released: bool,
52
+
53
+    pub up_just_pressed: bool,
54
+    pub down_just_pressed: bool,
55
+    pub left_just_pressed: bool,
56
+    pub right_just_pressed: bool,
57
+
58
+    pub a_just_pressed: bool,
59
+    pub b_just_pressed: bool,
60
+
61
+    pub start_just_pressed: bool,
62
+    pub select_just_pressed: bool,
32 63
 }
33 64
 
34 65
 impl Controller {
@@ -38,25 +69,151 @@ impl Controller {
38 69
             down: false,
39 70
             left: false,
40 71
             right: false,
41
-
42 72
             a: false,
43 73
             b: false,
44
-
45 74
             start: false,
46 75
             select: false,
76
+
77
+            up_previous: false,
78
+            down_previous: false,
79
+            left_previous: false,
80
+            right_previous: false,
81
+            a_previous: false,
82
+            b_previous: false,
83
+            start_previous: false,
84
+            select_previous: false,
85
+
86
+            up_just_released: false,
87
+            down_just_released: false,
88
+            left_just_released: false,
89
+            right_just_released: false,
90
+            a_just_released: false,
91
+            b_just_released: false,
92
+            start_just_released: false,
93
+            select_just_released: false,
94
+
95
+            up_just_pressed: false,
96
+            down_just_pressed: false,
97
+            left_just_pressed: false,
98
+            right_just_pressed: false,
99
+            a_just_pressed: false,
100
+            b_just_pressed: false,
101
+            start_just_pressed: false,
102
+            select_just_pressed: false,
47 103
         }
48 104
     }
49 105
 
106
+    pub fn reset_controller(&mut self) {
107
+        self.up_just_released = false;
108
+        self.down_just_released = false;
109
+        self.left_just_released = false;
110
+        self.right_just_released = false;
111
+        self.a_just_released = false;
112
+        self.b_just_released = false;
113
+        self.start_just_released = false;
114
+        self.select_just_released = false;
115
+
116
+        self.up_just_pressed = false;
117
+        self.down_just_pressed = false;
118
+        self.left_just_pressed = false;
119
+        self.right_just_pressed = false;
120
+        self.a_just_pressed = false;
121
+        self.b_just_pressed = false;
122
+        self.start_just_pressed = false;
123
+        self.select_just_pressed = false;
124
+    }
125
+
50 126
     pub fn input(&mut self, button: ControllerButton, action: ControllerAction) {
127
+        self.up_previous = self.up;
128
+        self.down_previous = self.down;
129
+        self.left_previous = self.left;
130
+        self.right_previous = self.right;
131
+        self.a_previous = self.a;
132
+        self.b_previous = self.b;
133
+        self.start_previous = self.start;
134
+        self.select_previous = self.select;
135
+
51 136
         match button {
52
-            ControllerButton::Left => self.left = self.bool_from_action(action),
53
-            ControllerButton::Right => self.right = self.bool_from_action(action),
54
-            ControllerButton::Up => self.up = self.bool_from_action(action),
55
-            ControllerButton::Down => self.down = self.bool_from_action(action),
56
-            ControllerButton::A => self.a = self.bool_from_action(action),
57
-            ControllerButton::B => self.b = self.bool_from_action(action),
58
-            ControllerButton::Start => self.start = self.bool_from_action(action),
59
-            ControllerButton::Select => self.select = self.bool_from_action(action),
137
+            ControllerButton::Left => {
138
+                self.left = self.bool_from_action(action);
139
+
140
+                if self.left == true && self.left_previous == false {
141
+                    self.left_just_pressed = true;
142
+                }
143
+                if self.left == false && self.left_previous == true {
144
+                    self.left_just_released = true;
145
+                }
146
+            },
147
+            ControllerButton::Right => {
148
+                self.right = self.bool_from_action(action);
149
+
150
+                if self.right == true && self.right_previous == false {
151
+                    self.right_just_pressed = true;
152
+                }
153
+                if self.right == false && self.right_previous == true {
154
+                    self.right_just_released = true;
155
+                }
156
+            },
157
+            ControllerButton::Up => {
158
+                self.up = self.bool_from_action(action);
159
+
160
+                if self.up == true && self.up_previous == false {
161
+                    self.up_just_pressed = true;
162
+                }
163
+                if self.up == false && self.up_previous == true {
164
+                    self.up_just_released = true;
165
+                }
166
+            },
167
+            ControllerButton::Down => {
168
+                self.down = self.bool_from_action(action);
169
+
170
+                if self.down == true && self.down_previous == false {
171
+                    self.down_just_pressed = true;
172
+                }
173
+                if self.down == false && self.down_previous == true {
174
+                    self.down_just_released = true;
175
+                }
176
+            },
177
+            ControllerButton::A => {
178
+                self.a = self.bool_from_action(action);
179
+
180
+                if self.a == true && self.a_previous == false {
181
+                    self.a_just_pressed = true;
182
+                }
183
+                if self.a == false && self.a_previous == true {
184
+                    self.a_just_released = true;
185
+                }
186
+            },
187
+            ControllerButton::B => {
188
+                self.b = self.bool_from_action(action);
189
+
190
+                if self.b == true && self.b_previous == false {
191
+                    self.b_just_pressed = true;
192
+                }
193
+                if self.b == false && self.b_previous == true {
194
+                    self.b_just_released = true;
195
+                }
196
+            },
197
+            ControllerButton::Start => {
198
+                self.start = self.bool_from_action(action);
199
+
200
+                if self.start == true && self.start_previous == false {
201
+                    self.start_just_pressed = true;
202
+                }
203
+                if self.start == false && self.start_previous == true {
204
+                    self.start_just_released = true;
205
+                }
206
+            },
207
+            ControllerButton::Select => {
208
+                self.select = self.bool_from_action(action);
209
+
210
+                if self.select == true && self.select_previous == false {
211
+                    self.select_just_pressed = true;
212
+                }
213
+                if self.select == false && self.select_previous == true {
214
+                    self.select_just_released = true;
215
+                }
216
+            },
60 217
         };
61 218
     }
62 219
 

+ 82
- 28
src/game.rs View File

@@ -180,6 +180,9 @@ pub struct Game {
180 180
     colour_saturation: f64,
181 181
     colour_lightness: f64,
182 182
 
183
+    menu_active_item: i32,
184
+    menu_volume: i32,
185
+
183 186
     is_game_over: bool,
184 187
 
185 188
     score: i32,
@@ -233,6 +236,9 @@ impl Game {
233 236
             colour_saturation: config.colour_saturation,
234 237
             colour_lightness: config.colour_lightness,
235 238
 
239
+            menu_active_item: 0,
240
+            menu_volume: 4,
241
+
236 242
             is_game_over: false,
237 243
 
238 244
             score: 0,
@@ -280,6 +286,7 @@ impl Game {
280 286
             ((1.0 - random) * 360.0) as f64,
281 287
             self.colour_saturation,
282 288
             self.colour_lightness,
289
+            1.0
283 290
         )?;
284 291
 
285 292
         use_next_shape(self, random)?;
@@ -298,7 +305,8 @@ impl Game {
298 305
 
299 306
         if let Ok(c) = get_colour_from_hsl(90.0,
300 307
                                            self.colour_saturation,
301
-                                           self.colour_lightness) {
308
+                                           self.colour_lightness,
309
+                                           1.0) {
302 310
             render_score(geometry, self.score, Block2D { x, y: y + 14 }, c);
303 311
             render_level(geometry, self.level, Block2D { x, y: y + 10 }, c);
304 312
             render_lines(geometry, self.lines, Block2D { x, y: y + 6 }, c);
@@ -311,21 +319,29 @@ impl Game {
311 319
         if self.mode == GameMode::Paused {
312 320
             if let Ok(c) = get_colour_from_hsl(90.0,
313 321
                                                self.colour_saturation,
314
-                                               self.colour_lightness) {
322
+                                               self.colour_lightness,
323
+                                               1.0) {
315 324
                 let board_centre = Block2D {
316 325
                     x: (self.board.width / 2) as i32 + self.board_offset.x,
317 326
                     y: (self.board.height / 2) as i32 + self.board_offset.y,
318 327
                 };
319 328
 
320
-                geometry.push_filled_fullscreen(Col::new(0.0, 0.0, 0.0, 0.6));
321
-                render_paused(geometry, board_centre, c, c);
329
+                geometry.push_filled_fullscreen(Col::new(0.0, 0.0, 0.0, 0.4));
330
+
331
+
332
+                if let Ok(background_colour) = get_colour_from_hsl(90.0,
333
+                                                                   self.colour_saturation / 2.0,
334
+                                                                   self.colour_lightness / 2.0,
335
+                                                                   0.7) {
336
+                    render_pause_menu(self, geometry, board_centre, c, background_colour);
337
+                }
322 338
             }
323 339
         }
324
-
325 340
     }
326 341
 
327
-    pub fn input(&mut self, button: ControllerButton, action: ControllerAction) -> bool {
328
-        if button == ControllerButton::Start && action == ControllerAction::Up {
342
+    pub fn tick(&mut self, controller: &Controller, delta: f32, random: f32) -> bool {
343
+
344
+        if controller.start_just_released {
329 345
             if self.mode == GameMode::Playing {
330 346
                 play_sound(SoundEffect::PauseIn);
331 347
                 self.mode = GameMode::Paused;
@@ -333,13 +349,9 @@ impl Game {
333 349
                 play_sound(SoundEffect::PauseOut);
334 350
                 self.mode = GameMode::Playing;
335 351
                 self.resume_from_paused = true;
336
-                return true;
337 352
             }
338 353
         }
339
-        false
340
-    }
341 354
 
342
-    pub fn tick(&mut self, controller: &Controller, delta: f32, random: f32) -> bool {
343 355
         // always followed by a render
344 356
         // returns true if tick should be called again
345 357
         //
@@ -358,10 +370,18 @@ impl Game {
358 370
                 Ok(res) => res,
359 371
                 Err(_) => false,
360 372
             },
361
-            GameMode::Paused => false,
373
+            GameMode::Paused => match self.tick_paused(controller) {
374
+                Ok(res) => res,
375
+                Err(_) => false,
376
+            },
362 377
         }
363 378
     }
364 379
 
380
+    fn tick_paused(&mut self, controller: &Controller) -> error::Result<bool> {
381
+        let updated = update_pause_menu(self, controller);
382
+        Ok(updated)
383
+    }
384
+
365 385
     // counting on the fact that delta will always be a 'sensible' value.
366 386
     // so if the player has paused the game for a while, on the first resumed call to tick_playing
367 387
     // delta should be 0 rather than a large multi-second value
@@ -525,13 +545,14 @@ fn use_next_shape(game: &mut Game, random: f32) -> error::Result<()> {
525 545
         (random * 360.0) as f64,
526 546
         game.colour_saturation,
527 547
         game.colour_lightness,
548
+        1.0
528 549
     )?;
529 550
 
530 551
     Ok(())
531 552
 }
532 553
 
533
-fn get_colour_from_hsl(hue: f64, saturation: f64, lightness: f64) -> error::Result<Col> {
534
-    let hsluv = Colour::HSLuv(hue, saturation, lightness, 1.0);
554
+fn get_colour_from_hsl(hue: f64, saturation: f64, lightness: f64, alpha: f64) -> error::Result<Col> {
555
+    let hsluv = Colour::HSLuv(hue, saturation, lightness, alpha);
535 556
     col_from_colour(&hsluv)
536 557
 }
537 558
 
@@ -618,12 +639,7 @@ fn apply_user_input(game: &mut Game, controller: &Controller, delta: f32) {
618 639
             }
619 640
         }
620 641
 
621
-        if can_apply_input(
622
-            &mut game.up_cooldown,
623
-            controller.up,
624
-            game.default_cooldown,
625
-            delta,
626
-        ) {
642
+        if controller.up_just_pressed {
627 643
             let new_angle;
628 644
             if shape.fully_rotate {
629 645
                 new_angle = match game.piece.angle {
@@ -644,12 +660,8 @@ fn apply_user_input(game: &mut Game, controller: &Controller, delta: f32) {
644 660
             }
645 661
         }
646 662
 
647
-        if can_apply_input(
648
-            &mut game.down_cooldown,
649
-            controller.down,
650
-            game.default_cooldown,
651
-            delta,
652
-        ) {
663
+
664
+        if controller.down_just_pressed {
653 665
             game.piece_is_dropping = true;
654 666
         }
655 667
 
@@ -957,8 +969,50 @@ fn render_next_shape(geometry: &mut Geometry, shape: &Shape, offset: Block2D, co
957 969
     }
958 970
 }
959 971
 
960
-fn render_paused(geometry: &mut Geometry, pos: Block2D, text_colour: Col, _background_colour: Col) {
961
-    geometry.push_text("PAUSED", pos, text_colour);
972
+
973
+fn update_pause_menu(game: &mut Game, controller: &Controller) -> bool {
974
+
975
+    let mut update = false;
976
+
977
+    if controller.down_just_pressed {
978
+        log("paused: down pressed");
979
+        game.menu_active_item += 1;
980
+        update = true;
981
+    }
982
+
983
+    if controller.up_just_pressed {
984
+        log("paused: up pressed");
985
+        game.menu_active_item -= 1;
986
+        update = true;
987
+    }
988
+
989
+    if game.menu_active_item < 0 {
990
+        game.menu_active_item = 2;
991
+    }
992
+
993
+    if game.menu_active_item > 2 {
994
+        game.menu_active_item = 0;
995
+    }
996
+
997
+    update
998
+}
999
+
1000
+fn render_pause_menu(game: &Game, geometry: &mut Geometry, centre: Block2D, text_colour: Col, background_colour: Col) {
1001
+    let lines = build_paused_menu(game);
1002
+    geometry.push_centred_boxed_multiline(&lines, centre, text_colour, background_colour);
1003
+}
1004
+
1005
+fn build_paused_menu(game: &Game) -> Vec<&str> {
1006
+    let mut lines: Vec<&str> = vec!["  RESUME", "  Volume: [---*--]", "  Restart"];
1007
+
1008
+    match game.menu_active_item {
1009
+        0 => lines[0] = "> RESUME",
1010
+        1 => lines[1] = "> Volume: [---*--]",
1011
+        2 => lines[2] = "> Restart",
1012
+        _ => (),
1013
+    }
1014
+
1015
+    lines
962 1016
 }
963 1017
 
964 1018
 fn define_shapes() -> HashMap<ShapeKind, Shape> {

+ 7
- 4
src/lib.rs View File

@@ -180,7 +180,11 @@ impl Bridge {
180 180
     }
181 181
 
182 182
     pub fn tick(&mut self, delta: f32, random: f32) -> bool {
183
-        self.game.tick(&self.controller, delta, random)
183
+        let res = self.game.tick(&self.controller, delta, random);
184
+
185
+        self.controller.reset_controller();
186
+
187
+        res
184 188
     }
185 189
 
186 190
     // use the current gamestate to update geometry
@@ -226,10 +230,9 @@ impl Bridge {
226 230
         }
227 231
     }
228 232
 
229
-    // return true if we need to call tick after receiving an input event
230
-    // (only true when we resume playing after being paused)
233
+    // always call tick after an input event
231 234
     fn input(&mut self, button: ControllerButton, action: ControllerAction) -> bool {
232 235
         self.controller.input(button, action);
233
-        self.game.input(button, action)
236
+        true
234 237
     }
235 238
 }

Loading…
Cancel
Save