From 37fa9904635be8d7ffcd08de1981327ce3327baf Mon Sep 17 00:00:00 2001 From: Astro Date: Sat, 15 Jan 2022 22:04:23 +0100 Subject: [PATCH] input: overhaul --- src/input.rs | 73 +++++++++++++++++++++++++++++++++------------------ src/player.rs | 61 ++++++------------------------------------ 2 files changed, 55 insertions(+), 79 deletions(-) diff --git a/src/input.rs b/src/input.rs index 87321c6..88741b3 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,4 +1,4 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use bevy::{ input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType, GamepadEvent, GamepadEventType}, prelude::*, @@ -42,7 +42,46 @@ const GAMEPAD_KEYS: &[(GamepadButtonType, Key)] = &[ ]; #[derive(Default)] -pub struct InputState(pub HashSet<(Source, Key)>); +pub struct InputState { + pub keys: HashSet<(Source, Key)>, + x: HashMap, + y: HashMap, +} + +impl InputState { + pub fn direction_of(&self, source: &Source) -> Vec2 { + let x = *self.x.get(source) + .unwrap_or(&0.0) + + if self.keys.contains(&(source.clone(), Key::Left)) { + -1.0 + } else { + 0.0 + } + + if self.keys.contains(&(source.clone(), Key::Right)) { + 1.0 + } else { + 0.0 + }; + let y = *self.y.get(source) + .unwrap_or(&0.0) + + if self.keys.contains(&(source.clone(), Key::Down)) { + -1.0 + } else { + 0.0 + } + + if self.keys.contains(&(source.clone(), Key::Up)) { + 1.0 + } else { + 0.0 + }; + let result = Vec2::new(x, -y); + if result.length_squared() > 0.0 { + result.normalize() + } else { + result + } + } +} pub fn setup(mut commands: Commands) { commands.insert_resource(InputState::default()); @@ -56,9 +95,9 @@ pub fn handle( // handle keyboard for (key_code, source, key) in KEYBOARD_KEYS { if keyboard.pressed(*key_code) { - state.0.insert((source.clone(), *key)); + state.keys.insert((source.clone(), *key)); } else { - state.0.remove(&(source.clone(), *key)); + state.keys.remove(&(source.clone(), *key)); } } @@ -70,37 +109,19 @@ pub fn handle( button == button_ }) { if *value > 0.01 { - state.0.insert((Source::Gamepad(*gamepad), *key)); + state.keys.insert((Source::Gamepad(*gamepad), *key)); } else { - state.0.remove(&(Source::Gamepad(*gamepad), *key)); + state.keys.remove(&(Source::Gamepad(*gamepad), *key)); } } } GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::DPadX, value)) | GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, value)) => { - if *value < -0.01 { - state.0.insert((Source::Gamepad(*gamepad), Key::Left)); - state.0.remove(&(Source::Gamepad(*gamepad), Key::Right)); - } else if *value > 0.01 { - state.0.insert((Source::Gamepad(*gamepad), Key::Right)); - state.0.remove(&(Source::Gamepad(*gamepad), Key::Left)); - } else { - state.0.remove(&(Source::Gamepad(*gamepad), Key::Left)); - state.0.remove(&(Source::Gamepad(*gamepad), Key::Right)); - } + state.x.insert(Source::Gamepad(*gamepad), *value); } GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::DPadY, value)) | GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickY, value)) => { - if *value < -0.01 { - state.0.insert((Source::Gamepad(*gamepad), Key::Down)); - state.0.remove(&(Source::Gamepad(*gamepad), Key::Up)); - } else if *value > 0.01 { - state.0.insert((Source::Gamepad(*gamepad), Key::Up)); - state.0.remove(&(Source::Gamepad(*gamepad), Key::Down)); - } else { - state.0.remove(&(Source::Gamepad(*gamepad), Key::Up)); - state.0.remove(&(Source::Gamepad(*gamepad), Key::Down)); - } + state.y.insert(Source::Gamepad(*gamepad), *value); } _ => {} } diff --git a/src/player.rs b/src/player.rs index f4de0ba..470d355 100644 --- a/src/player.rs +++ b/src/player.rs @@ -21,7 +21,7 @@ pub fn spawn_player( input: Res, asset_server: Res, ) { - let input_source = match input.0.iter().find(|(input_source, key)| + let input_source = match input.keys.iter().find(|(input_source, key)| if *key == Key::Jump { ! players.iter().any(|player| player.input_source == *input_source) } else { @@ -102,58 +102,11 @@ pub fn input( const SPEED: f32 = 4.0; for (mut velocity, mut player, mut transform, contact) in players.iter_mut() { - let x; - let z; - let target_rotation; - match [Key::Right, Key::Left, Key::Up, Key::Down].map(|key| input.0.contains(&(player.input_source.clone(), key))) { - [false, false, false, true] => { - z = 1.0; - x = 0.0; - target_rotation = Some(0.0); - } - [false, true, false, true] => { - z = 0.7; - x = -0.7; - target_rotation = Some(1.75 * PI); - } - [false, true, false, false] => { - z = 0.0; - x = -1.0; - target_rotation = Some(1.5 * PI); - } - [false, true, true, false] => { - z = -0.7; - x = -0.7; - target_rotation = Some(1.25 * PI); - } - [false, false, true, false] => { - z = -1.0; - x = 0.0; - target_rotation = Some(1.0 * PI); - } - [true, false, true, false] => { - z = -0.7; - x = 0.7; - target_rotation = Some(0.75 * PI); - } - [true, false, false, false] => { - z = 0.0; - x = 1.0; - target_rotation = Some(0.5 * PI); - } - [true, false, false, true] => { - z = 0.7; - x = 0.7; - target_rotation = Some(0.25 * PI); - } - _ => { - z = 0.0; - x = 0.0; - target_rotation = None; - } - } + let direction = input.direction_of(&player.input_source); + let x = direction.x; + let z = direction.y; - let y = if input.0.contains(&(player.input_source.clone(), Key::Jump)) { + let y = if input.keys.contains(&(player.input_source.clone(), Key::Jump)) { 1.2 } else if x != 0.0 || z != 0.0 { // walk bobbing @@ -168,7 +121,9 @@ pub fn input( velocity.linear = target_velocity; } - if let Some(target_rotation) = target_rotation { + if direction.length_squared() > 0.0 { + let target_rotation = direction.angle_between(Vec2::Y); + if (player.rotation - 2.0 * PI - target_rotation).abs() < (player.rotation - target_rotation).abs() { player.rotation -= 2.0 * PI; }