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::{
|
use bevy::{
|
||||||
input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType, GamepadEvent, GamepadEventType},
|
input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType, GamepadEvent, GamepadEventType},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
@ -42,7 +42,46 @@ const GAMEPAD_KEYS: &[(GamepadButtonType, Key)] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Default)]
|
#[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) {
|
pub fn setup(mut commands: Commands) {
|
||||||
commands.insert_resource(InputState::default());
|
commands.insert_resource(InputState::default());
|
||||||
|
@ -56,9 +95,9 @@ pub fn handle(
|
||||||
// handle keyboard
|
// handle keyboard
|
||||||
for (key_code, source, key) in KEYBOARD_KEYS {
|
for (key_code, source, key) in KEYBOARD_KEYS {
|
||||||
if keyboard.pressed(*key_code) {
|
if keyboard.pressed(*key_code) {
|
||||||
state.0.insert((source.clone(), *key));
|
state.keys.insert((source.clone(), *key));
|
||||||
} else {
|
} else {
|
||||||
state.0.remove(&(source.clone(), *key));
|
state.keys.remove(&(source.clone(), *key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,37 +109,19 @@ pub fn handle(
|
||||||
button == button_
|
button == button_
|
||||||
}) {
|
}) {
|
||||||
if *value > 0.01 {
|
if *value > 0.01 {
|
||||||
state.0.insert((Source::Gamepad(*gamepad), *key));
|
state.keys.insert((Source::Gamepad(*gamepad), *key));
|
||||||
} else {
|
} 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::DPadX, value)) |
|
||||||
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, value)) => {
|
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, value)) => {
|
||||||
if *value < -0.01 {
|
state.x.insert(Source::Gamepad(*gamepad), *value);
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::DPadY, value)) |
|
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::DPadY, value)) |
|
||||||
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickY, value)) => {
|
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickY, value)) => {
|
||||||
if *value < -0.01 {
|
state.y.insert(Source::Gamepad(*gamepad), *value);
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub fn spawn_player(
|
||||||
input: Res<InputState>,
|
input: Res<InputState>,
|
||||||
asset_server: Res<AssetServer>,
|
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 {
|
if *key == Key::Jump {
|
||||||
! players.iter().any(|player| player.input_source == *input_source)
|
! players.iter().any(|player| player.input_source == *input_source)
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,58 +102,11 @@ pub fn input(
|
||||||
const SPEED: f32 = 4.0;
|
const SPEED: f32 = 4.0;
|
||||||
|
|
||||||
for (mut velocity, mut player, mut transform, contact) in players.iter_mut() {
|
for (mut velocity, mut player, mut transform, contact) in players.iter_mut() {
|
||||||
let x;
|
let direction = input.direction_of(&player.input_source);
|
||||||
let z;
|
let x = direction.x;
|
||||||
let target_rotation;
|
let z = direction.y;
|
||||||
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 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
|
1.2
|
||||||
} else if x != 0.0 || z != 0.0 {
|
} else if x != 0.0 || z != 0.0 {
|
||||||
// walk bobbing
|
// walk bobbing
|
||||||
|
@ -168,7 +121,9 @@ pub fn input(
|
||||||
velocity.linear = target_velocity;
|
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() {
|
if (player.rotation - 2.0 * PI - target_rotation).abs() < (player.rotation - target_rotation).abs() {
|
||||||
player.rotation -= 2.0 * PI;
|
player.rotation -= 2.0 * PI;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue