input: overhaul
This commit is contained in:
parent
7f39a45b92
commit
37fa990463
73
src/input.rs
73
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<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);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue