233 lines
5.5 KiB
Rust
233 lines
5.5 KiB
Rust
use sfml::system::Vector2;
|
|
use sfml::window::joystick::{
|
|
Axis,
|
|
axis_position,
|
|
is_connected,
|
|
COUNT,
|
|
};
|
|
|
|
use sfml::window::{
|
|
Key,
|
|
Event,
|
|
};
|
|
|
|
/// The different actions that a user can do.
|
|
pub enum Action {
|
|
/// The jump button.
|
|
///
|
|
/// A bool at true means that the button was pressed,
|
|
/// A bool at false means that the button was released.
|
|
Jump(bool),
|
|
}
|
|
|
|
/// Contains the data needed to manage the controls of the player.
|
|
#[derive(Copy, Clone)]
|
|
pub enum Controls {
|
|
/// A keyboard controller.
|
|
Keyboard(KeyboardMap),
|
|
|
|
/// A gamepad controller.
|
|
Gamepad(GamepadMap),
|
|
}
|
|
|
|
impl Controls {
|
|
|
|
/// Returns the default keyboard controls.
|
|
pub fn default_keyboard() -> Controls {
|
|
Controls::Keyboard(KeyboardMap::default())
|
|
}
|
|
|
|
/// Returns the default gamepad controls from id.
|
|
///
|
|
/// Returns None if the gamepad corresponding to the id is not connected.
|
|
pub fn default_gamepad_from_id(id: u32) -> Option<Controls> {
|
|
match GamepadMap::from_id(id) {
|
|
Some(map) => Some(Controls::Gamepad(map)),
|
|
None => None,
|
|
}
|
|
}
|
|
|
|
/// Returns the default gamepad controls from id.
|
|
///
|
|
/// Returns None if the gamepad corresponding to the id is not connected.
|
|
pub fn all_gamepads() -> Vec<Controls> {
|
|
GamepadMap::all()
|
|
.into_iter()
|
|
.map(|x| Controls::Gamepad(x))
|
|
.collect()
|
|
}
|
|
|
|
/// Converts an event and depending on the config, returns the corresponding action.
|
|
pub fn convert(&self, event: &Event) -> Option<Action> {
|
|
match self {
|
|
Controls::Keyboard(ref map) => map.convert(event),
|
|
Controls::Gamepad(ref map) => map.convert(event),
|
|
}
|
|
}
|
|
|
|
/// Returns the direction of the controls.
|
|
pub fn direction(&self) -> Vector2<f32> {
|
|
match self {
|
|
Controls::Keyboard(ref map) => map.direction(),
|
|
Controls::Gamepad(ref map) => map.direction(),
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// A map between keyboard keys and actions.
|
|
#[derive(Copy, Clone)]
|
|
pub struct KeyboardMap {
|
|
|
|
/// The key corresponding to the jump button.
|
|
jump_key: Key,
|
|
|
|
/// The key corresponding to the up button.
|
|
up_key: Key,
|
|
|
|
/// The key corresponding to the left button.
|
|
left_key: Key,
|
|
|
|
/// The key corresponding to the right button.
|
|
right_key: Key,
|
|
|
|
/// The key corresponding to the down button.
|
|
down_key: Key,
|
|
|
|
}
|
|
|
|
impl KeyboardMap {
|
|
|
|
/// Creates the default keyboard config.
|
|
pub fn default() -> KeyboardMap {
|
|
KeyboardMap {
|
|
jump_key: Key::Space,
|
|
up_key: Key::Up,
|
|
left_key: Key::Left,
|
|
right_key: Key::Right,
|
|
down_key: Key::Down,
|
|
}
|
|
}
|
|
|
|
/// Converts an event and depending on the config, returns the corresponding action.
|
|
pub fn convert(&self, event: &Event) -> Option<Action> {
|
|
|
|
match event {
|
|
Event::KeyPressed { code, .. } if *code == self.jump_key =>
|
|
Some(Action::Jump(true)),
|
|
|
|
Event::KeyReleased { code, .. } if *code == self.jump_key =>
|
|
Some(Action::Jump(false)),
|
|
|
|
_ => None,
|
|
}
|
|
|
|
}
|
|
|
|
/// Returns the direction of the keys.
|
|
pub fn direction(&self) -> Vector2<f32> {
|
|
|
|
let mut ret = Vector2::new(0.0, 0.0);
|
|
|
|
const RIGHT: Vector2<f32> = Vector2 { x: 1.0, y: 0.0 };
|
|
const UP: Vector2<f32> = Vector2 {x: 0.0, y: 1.0};
|
|
|
|
if self.right_key.is_pressed() {
|
|
ret += RIGHT;
|
|
}
|
|
|
|
if self.left_key.is_pressed() {
|
|
ret -= RIGHT;
|
|
}
|
|
|
|
if self.up_key.is_pressed() {
|
|
ret += UP;
|
|
}
|
|
|
|
if self.down_key.is_pressed() {
|
|
ret -= UP;
|
|
}
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// A map between gamepad buttons and actions.
|
|
#[derive(Copy, Clone)]
|
|
pub struct GamepadMap {
|
|
|
|
/// Id of the gamepad.
|
|
id: u32,
|
|
|
|
/// Number of the jump button.
|
|
jump_button: u32,
|
|
|
|
/// Left / Right axis.
|
|
left_right_axis: Axis,
|
|
|
|
}
|
|
|
|
impl GamepadMap {
|
|
|
|
/// Creates the default gamepad from an id.
|
|
///
|
|
/// Returns None if the gamepad corresponding to the id is not connected.
|
|
pub fn from_id(id: u32) -> Option<GamepadMap> {
|
|
|
|
if ! is_connected(id){
|
|
return None;
|
|
}
|
|
|
|
Some(GamepadMap {
|
|
id: id,
|
|
jump_button: 1,
|
|
left_right_axis: Axis::X,
|
|
})
|
|
}
|
|
|
|
/// Creates a vector containing all connected gamepads.
|
|
pub fn all() -> Vec<GamepadMap> {
|
|
let mut gamepads = vec![];
|
|
|
|
for id in 0 .. COUNT {
|
|
if let Some(gamepad) = GamepadMap::from_id(id) {
|
|
gamepads.push(gamepad);
|
|
}
|
|
}
|
|
|
|
gamepads
|
|
}
|
|
|
|
/// Converts an event and depending on the config, returns the corresponding action.
|
|
pub fn convert(&self, event: &Event) -> Option<Action> {
|
|
|
|
match event {
|
|
Event::JoystickButtonPressed { joystickid, button } if
|
|
*joystickid == self.id && *button == self.jump_button => {
|
|
|
|
Some(Action::Jump(true))
|
|
|
|
},
|
|
|
|
Event::JoystickButtonReleased { joystickid, button } if
|
|
*joystickid == self.id && *button == self.jump_button => {
|
|
|
|
Some(Action::Jump(false))
|
|
|
|
},
|
|
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
/// Returns the direction of the directionnal buttons of the gamepad.
|
|
pub fn direction(&self) -> Vector2<f32> {
|
|
Vector2::new(
|
|
axis_position(self.id, self.left_right_axis) / 100.0,
|
|
0.0
|
|
)
|
|
}
|
|
}
|