Browse Source

better controls

master
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 {

pub start: bool,
pub select: bool,

up_previous: bool,
down_previous: bool,
left_previous: bool,
right_previous: bool,
a_previous: bool,
b_previous: bool,
start_previous: bool,
select_previous: bool,

pub up_just_released: bool,
pub down_just_released: bool,
pub left_just_released: bool,
pub right_just_released: bool,

pub a_just_released: bool,
pub b_just_released: bool,

pub start_just_released: bool,
pub select_just_released: bool,

pub up_just_pressed: bool,
pub down_just_pressed: bool,
pub left_just_pressed: bool,
pub right_just_pressed: bool,

pub a_just_pressed: bool,
pub b_just_pressed: bool,

pub start_just_pressed: bool,
pub select_just_pressed: bool,
}

impl Controller {
@@ -38,25 +69,151 @@ impl Controller {
down: false,
left: false,
right: false,

a: false,
b: false,

start: false,
select: false,

up_previous: false,
down_previous: false,
left_previous: false,
right_previous: false,
a_previous: false,
b_previous: false,
start_previous: false,
select_previous: false,

up_just_released: false,
down_just_released: false,
left_just_released: false,
right_just_released: false,
a_just_released: false,
b_just_released: false,
start_just_released: false,
select_just_released: false,

up_just_pressed: false,
down_just_pressed: false,
left_just_pressed: false,
right_just_pressed: false,
a_just_pressed: false,
b_just_pressed: false,
start_just_pressed: false,
select_just_pressed: false,
}
}

pub fn reset_controller(&mut self) {
self.up_just_released = false;
self.down_just_released = false;
self.left_just_released = false;
self.right_just_released = false;
self.a_just_released = false;
self.b_just_released = false;
self.start_just_released = false;
self.select_just_released = false;

self.up_just_pressed = false;
self.down_just_pressed = false;
self.left_just_pressed = false;
self.right_just_pressed = false;
self.a_just_pressed = false;
self.b_just_pressed = false;
self.start_just_pressed = false;
self.select_just_pressed = false;
}

pub fn input(&mut self, button: ControllerButton, action: ControllerAction) {
self.up_previous = self.up;
self.down_previous = self.down;
self.left_previous = self.left;
self.right_previous = self.right;
self.a_previous = self.a;
self.b_previous = self.b;
self.start_previous = self.start;
self.select_previous = self.select;

match button {
ControllerButton::Left => self.left = self.bool_from_action(action),
ControllerButton::Right => self.right = self.bool_from_action(action),
ControllerButton::Up => self.up = self.bool_from_action(action),
ControllerButton::Down => self.down = self.bool_from_action(action),
ControllerButton::A => self.a = self.bool_from_action(action),
ControllerButton::B => self.b = self.bool_from_action(action),
ControllerButton::Start => self.start = self.bool_from_action(action),
ControllerButton::Select => self.select = self.bool_from_action(action),
ControllerButton::Left => {
self.left = self.bool_from_action(action);

if self.left == true && self.left_previous == false {
self.left_just_pressed = true;
}
if self.left == false && self.left_previous == true {
self.left_just_released = true;
}
},
ControllerButton::Right => {
self.right = self.bool_from_action(action);

if self.right == true && self.right_previous == false {
self.right_just_pressed = true;
}
if self.right == false && self.right_previous == true {
self.right_just_released = true;
}
},
ControllerButton::Up => {
self.up = self.bool_from_action(action);

if self.up == true && self.up_previous == false {
self.up_just_pressed = true;
}
if self.up == false && self.up_previous == true {
self.up_just_released = true;
}
},
ControllerButton::Down => {
self.down = self.bool_from_action(action);

if self.down == true && self.down_previous == false {
self.down_just_pressed = true;
}
if self.down == false && self.down_previous == true {
self.down_just_released = true;
}
},
ControllerButton::A => {
self.a = self.bool_from_action(action);

if self.a == true && self.a_previous == false {
self.a_just_pressed = true;
}
if self.a == false && self.a_previous == true {
self.a_just_released = true;
}
},
ControllerButton::B => {
self.b = self.bool_from_action(action);

if self.b == true && self.b_previous == false {
self.b_just_pressed = true;
}
if self.b == false && self.b_previous == true {
self.b_just_released = true;
}
},
ControllerButton::Start => {
self.start = self.bool_from_action(action);

if self.start == true && self.start_previous == false {
self.start_just_pressed = true;
}
if self.start == false && self.start_previous == true {
self.start_just_released = true;
}
},
ControllerButton::Select => {
self.select = self.bool_from_action(action);

if self.select == true && self.select_previous == false {
self.select_just_pressed = true;
}
if self.select == false && self.select_previous == true {
self.select_just_released = true;
}
},
};
}


+ 82
- 28
src/game.rs View File

@@ -180,6 +180,9 @@ pub struct Game {
colour_saturation: f64,
colour_lightness: f64,

menu_active_item: i32,
menu_volume: i32,

is_game_over: bool,

score: i32,
@@ -233,6 +236,9 @@ impl Game {
colour_saturation: config.colour_saturation,
colour_lightness: config.colour_lightness,

menu_active_item: 0,
menu_volume: 4,

is_game_over: false,

score: 0,
@@ -280,6 +286,7 @@ impl Game {
((1.0 - random) * 360.0) as f64,
self.colour_saturation,
self.colour_lightness,
1.0
)?;

use_next_shape(self, random)?;
@@ -298,7 +305,8 @@ impl Game {

if let Ok(c) = get_colour_from_hsl(90.0,
self.colour_saturation,
self.colour_lightness) {
self.colour_lightness,
1.0) {
render_score(geometry, self.score, Block2D { x, y: y + 14 }, c);
render_level(geometry, self.level, Block2D { x, y: y + 10 }, c);
render_lines(geometry, self.lines, Block2D { x, y: y + 6 }, c);
@@ -311,21 +319,29 @@ impl Game {
if self.mode == GameMode::Paused {
if let Ok(c) = get_colour_from_hsl(90.0,
self.colour_saturation,
self.colour_lightness) {
self.colour_lightness,
1.0) {
let board_centre = Block2D {
x: (self.board.width / 2) as i32 + self.board_offset.x,
y: (self.board.height / 2) as i32 + self.board_offset.y,
};

geometry.push_filled_fullscreen(Col::new(0.0, 0.0, 0.0, 0.6));
render_paused(geometry, board_centre, c, c);
geometry.push_filled_fullscreen(Col::new(0.0, 0.0, 0.0, 0.4));


if let Ok(background_colour) = get_colour_from_hsl(90.0,
self.colour_saturation / 2.0,
self.colour_lightness / 2.0,
0.7) {
render_pause_menu(self, geometry, board_centre, c, background_colour);
}
}
}

}

pub fn input(&mut self, button: ControllerButton, action: ControllerAction) -> bool {
if button == ControllerButton::Start && action == ControllerAction::Up {
pub fn tick(&mut self, controller: &Controller, delta: f32, random: f32) -> bool {

if controller.start_just_released {
if self.mode == GameMode::Playing {
play_sound(SoundEffect::PauseIn);
self.mode = GameMode::Paused;
@@ -333,13 +349,9 @@ impl Game {
play_sound(SoundEffect::PauseOut);
self.mode = GameMode::Playing;
self.resume_from_paused = true;
return true;
}
}
false
}

pub fn tick(&mut self, controller: &Controller, delta: f32, random: f32) -> bool {
// always followed by a render
// returns true if tick should be called again
//
@@ -358,10 +370,18 @@ impl Game {
Ok(res) => res,
Err(_) => false,
},
GameMode::Paused => false,
GameMode::Paused => match self.tick_paused(controller) {
Ok(res) => res,
Err(_) => false,
},
}
}

fn tick_paused(&mut self, controller: &Controller) -> error::Result<bool> {
let updated = update_pause_menu(self, controller);
Ok(updated)
}

// counting on the fact that delta will always be a 'sensible' value.
// so if the player has paused the game for a while, on the first resumed call to tick_playing
// 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<()> {
(random * 360.0) as f64,
game.colour_saturation,
game.colour_lightness,
1.0
)?;

Ok(())
}

fn get_colour_from_hsl(hue: f64, saturation: f64, lightness: f64) -> error::Result<Col> {
let hsluv = Colour::HSLuv(hue, saturation, lightness, 1.0);
fn get_colour_from_hsl(hue: f64, saturation: f64, lightness: f64, alpha: f64) -> error::Result<Col> {
let hsluv = Colour::HSLuv(hue, saturation, lightness, alpha);
col_from_colour(&hsluv)
}

@@ -618,12 +639,7 @@ fn apply_user_input(game: &mut Game, controller: &Controller, delta: f32) {
}
}

if can_apply_input(
&mut game.up_cooldown,
controller.up,
game.default_cooldown,
delta,
) {
if controller.up_just_pressed {
let new_angle;
if shape.fully_rotate {
new_angle = match game.piece.angle {
@@ -644,12 +660,8 @@ fn apply_user_input(game: &mut Game, controller: &Controller, delta: f32) {
}
}

if can_apply_input(
&mut game.down_cooldown,
controller.down,
game.default_cooldown,
delta,
) {

if controller.down_just_pressed {
game.piece_is_dropping = true;
}

@@ -957,8 +969,50 @@ fn render_next_shape(geometry: &mut Geometry, shape: &Shape, offset: Block2D, co
}
}

fn render_paused(geometry: &mut Geometry, pos: Block2D, text_colour: Col, _background_colour: Col) {
geometry.push_text("PAUSED", pos, text_colour);

fn update_pause_menu(game: &mut Game, controller: &Controller) -> bool {

let mut update = false;

if controller.down_just_pressed {
log("paused: down pressed");
game.menu_active_item += 1;
update = true;
}

if controller.up_just_pressed {
log("paused: up pressed");
game.menu_active_item -= 1;
update = true;
}

if game.menu_active_item < 0 {
game.menu_active_item = 2;
}

if game.menu_active_item > 2 {
game.menu_active_item = 0;
}

update
}

fn render_pause_menu(game: &Game, geometry: &mut Geometry, centre: Block2D, text_colour: Col, background_colour: Col) {
let lines = build_paused_menu(game);
geometry.push_centred_boxed_multiline(&lines, centre, text_colour, background_colour);
}

fn build_paused_menu(game: &Game) -> Vec<&str> {
let mut lines: Vec<&str> = vec![" RESUME", " Volume: [---*--]", " Restart"];

match game.menu_active_item {
0 => lines[0] = "> RESUME",
1 => lines[1] = "> Volume: [---*--]",
2 => lines[2] = "> Restart",
_ => (),
}

lines
}

fn define_shapes() -> HashMap<ShapeKind, Shape> {

+ 7
- 4
src/lib.rs View File

@@ -180,7 +180,11 @@ impl Bridge {
}

pub fn tick(&mut self, delta: f32, random: f32) -> bool {
self.game.tick(&self.controller, delta, random)
let res = self.game.tick(&self.controller, delta, random);

self.controller.reset_controller();

res
}

// use the current gamestate to update geometry
@@ -226,10 +230,9 @@ impl Bridge {
}
}

// return true if we need to call tick after receiving an input event
// (only true when we resume playing after being paused)
// always call tick after an input event
fn input(&mut self, button: ControllerButton, action: ControllerAction) -> bool {
self.controller.input(button, action);
self.game.input(button, action)
true
}
}

Loading…
Cancel
Save