entevsbaer/src/input.rs

130 lines
4.0 KiB
Rust
Raw Normal View History

2022-01-15 22:04:23 +01:00
use std::collections::{HashMap, HashSet};
2022-01-15 02:09:12 +01:00
use bevy::{
input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType, GamepadEvent, GamepadEventType},
prelude::*,
};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Source {
KeyboardRight,
KeyboardLeft,
Gamepad(Gamepad),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Key {
Up,
Down,
Left,
Right,
Jump,
}
const KEYBOARD_KEYS: &[(KeyCode, Source, Key)] = &[
(KeyCode::Up, Source::KeyboardRight, Key::Up),
(KeyCode::Down, Source::KeyboardRight, Key::Down),
(KeyCode::Left, Source::KeyboardRight, Key::Left),
(KeyCode::Right, Source::KeyboardRight, Key::Right),
(KeyCode::Return, Source::KeyboardRight, Key::Jump),
(KeyCode::W, Source::KeyboardLeft, Key::Up),
(KeyCode::S, Source::KeyboardLeft, Key::Down),
(KeyCode::A, Source::KeyboardLeft, Key::Left),
(KeyCode::D, Source::KeyboardLeft, Key::Right),
(KeyCode::Space, Source::KeyboardLeft, Key::Jump),
];
const GAMEPAD_KEYS: &[(GamepadButtonType, Key)] = &[
(GamepadButtonType::DPadUp, Key::Up),
(GamepadButtonType::DPadDown, Key::Down),
(GamepadButtonType::DPadLeft, Key::Left),
(GamepadButtonType::DPadRight, Key::Right),
(GamepadButtonType::South, Key::Jump),
];
#[derive(Default)]
2022-01-15 22:04:23 +01:00
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
}
}
}
2022-01-15 02:09:12 +01:00
pub fn setup(mut commands: Commands) {
commands.insert_resource(InputState::default());
}
pub fn handle(
keyboard: Res<Input<KeyCode>>,
mut gamepad_event: EventReader<GamepadEvent>,
mut state: ResMut<InputState>,
) {
// handle keyboard
for (key_code, source, key) in KEYBOARD_KEYS {
if keyboard.pressed(*key_code) {
2022-01-15 22:04:23 +01:00
state.keys.insert((source.clone(), *key));
2022-01-15 02:09:12 +01:00
} else {
2022-01-15 22:04:23 +01:00
state.keys.remove(&(source.clone(), *key));
2022-01-15 02:09:12 +01:00
}
}
// handle gamepads
for event in gamepad_event.iter() {
match event {
GamepadEvent(gamepad, GamepadEventType::ButtonChanged(button, value)) => {
if let Some((_, key)) = GAMEPAD_KEYS.iter().find(|(button_, _)| {
button == button_
}) {
if *value > 0.01 {
2022-01-15 22:04:23 +01:00
state.keys.insert((Source::Gamepad(*gamepad), *key));
2022-01-15 02:09:12 +01:00
} else {
2022-01-15 22:04:23 +01:00
state.keys.remove(&(Source::Gamepad(*gamepad), *key));
2022-01-15 02:09:12 +01:00
}
}
}
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::DPadX, value)) |
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, value)) => {
2022-01-15 22:04:23 +01:00
state.x.insert(Source::Gamepad(*gamepad), *value);
2022-01-15 02:09:12 +01:00
}
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::DPadY, value)) |
GamepadEvent(gamepad, GamepadEventType::AxisChanged(GamepadAxisType::LeftStickY, value)) => {
2022-01-15 22:04:23 +01:00
state.y.insert(Source::Gamepad(*gamepad), *value);
2022-01-15 02:09:12 +01:00
}
_ => {}
}
}
}