input: overhaul

This commit is contained in:
Astro 2022-01-15 22:04:23 +01:00
parent 7f39a45b92
commit 37fa990463
2 changed files with 55 additions and 79 deletions

View File

@ -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<Source, f32>,
y: HashMap<Source, f32>,
}
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);
}
_ => {}
}

View File

@ -21,7 +21,7 @@ pub fn spawn_player(
input: Res<InputState>,
asset_server: Res<AssetServer>,
) {
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;
}