2018-10-13 18:30:44 +02:00
|
|
|
use sfml::system::Vector2;
|
2018-11-19 15:30:57 +01:00
|
|
|
use sfml::window::joystick::{axis_position, is_button_pressed, is_connected, Axis, COUNT};
|
|
|
|
|
|
|
|
use sfml::window::{Event, Key};
|
2018-10-13 18:30:44 +02:00
|
|
|
|
|
|
|
/// 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),
|
|
|
|
}
|
2018-10-02 21:48:19 +02:00
|
|
|
|
|
|
|
/// Contains the data needed to manage the controls of the player.
|
2018-10-13 18:30:44 +02:00
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub enum Controls {
|
|
|
|
/// A keyboard controller.
|
|
|
|
Keyboard(KeyboardMap),
|
2018-10-02 21:48:19 +02:00
|
|
|
|
2018-10-13 18:30:44 +02:00
|
|
|
/// A gamepad controller.
|
|
|
|
Gamepad(GamepadMap),
|
2018-10-02 21:48:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Controls {
|
2018-10-13 18:30:44 +02:00
|
|
|
/// 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(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-15 10:10:53 +02:00
|
|
|
/// Returns whether the running key is pressed.
|
|
|
|
pub fn is_running(&self) -> bool {
|
|
|
|
match self {
|
|
|
|
Controls::Keyboard(ref map) => map.is_running(),
|
|
|
|
Controls::Gamepad(ref map) => map.is_running(),
|
|
|
|
}
|
|
|
|
}
|
2018-10-13 18:30:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A map between keyboard keys and actions.
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct KeyboardMap {
|
|
|
|
/// The key corresponding to the jump button.
|
|
|
|
jump_key: Key,
|
|
|
|
|
2018-10-15 10:10:53 +02:00
|
|
|
/// The key corresponding to the run button.
|
|
|
|
run_key: Key,
|
|
|
|
|
2018-10-13 18:30:44 +02:00
|
|
|
/// The key corresponding to the left button.
|
|
|
|
left_key: Key,
|
|
|
|
|
|
|
|
/// The key corresponding to the right button.
|
|
|
|
right_key: Key,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl KeyboardMap {
|
|
|
|
/// Creates the default keyboard config.
|
|
|
|
pub fn default() -> KeyboardMap {
|
|
|
|
KeyboardMap {
|
|
|
|
jump_key: Key::Space,
|
2018-10-15 10:10:53 +02:00
|
|
|
run_key: Key::LAlt,
|
2018-10-13 18:30:44 +02:00
|
|
|
left_key: Key::Left,
|
|
|
|
right_key: Key::Right,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts an event and depending on the config, returns the corresponding action.
|
|
|
|
pub fn convert(&self, event: &Event) -> Option<Action> {
|
|
|
|
match event {
|
2018-11-19 15:30:57 +01:00
|
|
|
Event::KeyPressed { code, .. } if *code == self.jump_key => Some(Action::Jump(true)),
|
2018-10-13 18:30:44 +02:00
|
|
|
|
2018-11-19 15:30:57 +01:00
|
|
|
Event::KeyReleased { code, .. } if *code == self.jump_key => Some(Action::Jump(false)),
|
2018-10-13 18:30:44 +02:00
|
|
|
|
|
|
|
_ => 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 };
|
|
|
|
|
|
|
|
if self.right_key.is_pressed() {
|
|
|
|
ret += RIGHT;
|
2018-10-02 21:48:19 +02:00
|
|
|
}
|
2018-10-13 18:30:44 +02:00
|
|
|
|
|
|
|
if self.left_key.is_pressed() {
|
|
|
|
ret -= RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
|
2018-10-15 10:10:53 +02:00
|
|
|
/// Returns whether the running button is held down.
|
|
|
|
pub fn is_running(&self) -> bool {
|
|
|
|
self.run_key.is_pressed()
|
|
|
|
}
|
2018-10-13 18:30:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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,
|
|
|
|
|
2018-10-15 10:10:53 +02:00
|
|
|
/// Number of the run button.
|
|
|
|
run_button: u32,
|
|
|
|
|
2018-10-13 18:30:44 +02:00
|
|
|
/// 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> {
|
2018-11-19 15:30:57 +01:00
|
|
|
if !is_connected(id) {
|
2018-10-13 18:30:44 +02:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(GamepadMap {
|
2018-11-19 15:21:02 +01:00
|
|
|
id,
|
2018-10-13 18:30:44 +02:00
|
|
|
jump_button: 1,
|
2018-10-15 12:58:14 +02:00
|
|
|
run_button: 0,
|
2018-10-13 18:30:44 +02:00
|
|
|
left_right_axis: Axis::X,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a vector containing all connected gamepads.
|
|
|
|
pub fn all() -> Vec<GamepadMap> {
|
|
|
|
let mut gamepads = vec![];
|
|
|
|
|
2018-11-19 15:30:57 +01:00
|
|
|
for id in 0..COUNT {
|
2018-10-13 18:30:44 +02:00
|
|
|
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 {
|
2018-11-19 15:30:57 +01:00
|
|
|
Event::JoystickButtonPressed { joystickid, button }
|
|
|
|
if *joystickid == self.id && *button == self.jump_button =>
|
|
|
|
{
|
2018-10-13 18:30:44 +02:00
|
|
|
Some(Action::Jump(true))
|
2018-11-19 15:30:57 +01:00
|
|
|
}
|
2018-10-13 18:30:44 +02:00
|
|
|
|
2018-11-19 15:30:57 +01:00
|
|
|
Event::JoystickButtonReleased { joystickid, button }
|
|
|
|
if *joystickid == self.id && *button == self.jump_button =>
|
|
|
|
{
|
2018-10-13 18:30:44 +02:00
|
|
|
Some(Action::Jump(false))
|
2018-11-19 15:30:57 +01:00
|
|
|
}
|
2018-10-13 18:30:44 +02:00
|
|
|
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the direction of the directionnal buttons of the gamepad.
|
|
|
|
pub fn direction(&self) -> Vector2<f32> {
|
2018-11-19 15:30:57 +01:00
|
|
|
Vector2::new(axis_position(self.id, self.left_right_axis) / 100.0, 0.0)
|
2018-10-02 21:48:19 +02:00
|
|
|
}
|
2018-10-15 10:10:53 +02:00
|
|
|
|
|
|
|
/// Returns whether the run button is held down.
|
|
|
|
pub fn is_running(&self) -> bool {
|
|
|
|
is_button_pressed(self.id, self.run_button)
|
|
|
|
}
|
2018-10-02 21:48:19 +02:00
|
|
|
}
|