Working on gamepads
This commit is contained in:
parent
2858e3d5ec
commit
c771d1ccea
@ -23,4 +23,6 @@ features = [
|
||||
'HtmlImageElement',
|
||||
'Window',
|
||||
'Performance',
|
||||
'Gamepad',
|
||||
'GamepadEvent',
|
||||
]
|
||||
|
@ -135,6 +135,11 @@ impl Character {
|
||||
&self.controls
|
||||
}
|
||||
|
||||
/// Changes the controls.
|
||||
pub fn set_controls(&mut self, controls: Option<Controls>) {
|
||||
self.controls = controls;
|
||||
}
|
||||
|
||||
/// Returns a view that looks at the character.
|
||||
pub fn view(&self) -> Bbox {
|
||||
Bbox::from_center_and_size(self.position, Vector::new(24.0 * 16.0, 24.0 * 9.0))
|
||||
|
@ -16,6 +16,9 @@ pub enum Action {
|
||||
pub enum Controls {
|
||||
/// A keyboard controller.
|
||||
Keyboard(KeyboardMap),
|
||||
|
||||
/// A gamepad controller.
|
||||
Gamepad(GamepadMap),
|
||||
}
|
||||
|
||||
impl Controls {
|
||||
@ -24,15 +27,12 @@ impl 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 default_gamepad(gamepad: web_sys::Gamepad) -> Controls {
|
||||
Controls::Gamepad(GamepadMap::from_gamepad(gamepad))
|
||||
}
|
||||
|
||||
// /// Returns the default gamepad controls from id.
|
||||
// ///
|
||||
@ -48,7 +48,7 @@ impl Controls {
|
||||
pub fn convert(&self, event: &Event) -> Option<Action> {
|
||||
match self {
|
||||
Controls::Keyboard(ref map) => map.convert(event),
|
||||
// Controls::Gamepad(ref map) => map.convert(event),
|
||||
Controls::Gamepad(ref map) => map.convert(event),
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ impl Controls {
|
||||
pub fn direction(&self, keyboard: &Keyboard) -> Vector {
|
||||
match self {
|
||||
Controls::Keyboard(ref map) => map.direction(keyboard),
|
||||
// Controls::Gamepad(ref map) => map.direction(),
|
||||
Controls::Gamepad(ref map) => map.direction(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,3 +120,60 @@ impl KeyboardMap {
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
/// A map between gamepad buttons and actions.
|
||||
#[derive(Clone)]
|
||||
pub struct GamepadMap {
|
||||
/// Id of the gamepad.
|
||||
inner: web_sys::Gamepad,
|
||||
|
||||
/// Number of the jump button.
|
||||
jump_button: u32,
|
||||
|
||||
/// Number of the run button.
|
||||
run_button: u32,
|
||||
// /// Left / Right axis.
|
||||
// left_right_axis: Axis,
|
||||
}
|
||||
|
||||
impl GamepadMap {
|
||||
/// Creates a gamepad map from a javascript gamepad.
|
||||
pub fn from_gamepad(gamepad: web_sys::Gamepad) -> GamepadMap {
|
||||
GamepadMap {
|
||||
inner: gamepad,
|
||||
jump_button: 0,
|
||||
run_button: 3,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts an event and depending on the config, returns the corresponding action.
|
||||
pub fn convert(&self, event: &Event) -> Option<Action> {
|
||||
None
|
||||
// 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) -> Vector {
|
||||
Vector::new(0.0, 0.0)
|
||||
// Vector2::new(axis_position(self.id, self.left_right_axis) / 100.0, 0.0)
|
||||
}
|
||||
|
||||
// /// Returns whether the run button is held down.
|
||||
// pub fn is_running(&self) -> bool {
|
||||
// is_button_pressed(self.id, self.run_button)
|
||||
// }
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use wasm_bindgen::JsCast;
|
||||
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::character::Character;
|
||||
use crate::engine::controls::Controls;
|
||||
use crate::engine::controls::{Controls, GamepadMap};
|
||||
use crate::engine::event::{Key, Keyboard};
|
||||
use crate::engine::map::Map;
|
||||
use crate::engine::math::now;
|
||||
@ -84,13 +84,24 @@ impl Engine {
|
||||
|
||||
let inner = InnerEngine::new(&document, &performance, scene)?;
|
||||
|
||||
let inner = Rc::new(RefCell::new(inner));
|
||||
let window = Rc::new(window);
|
||||
let document = Rc::new(document);
|
||||
let performance = Rc::new(performance);
|
||||
let context = Rc::new(context);
|
||||
|
||||
let clone = inner.clone();
|
||||
let cb = Closure::<dyn FnMut(_)>::new(move |event: web_sys::GamepadEvent| {
|
||||
let mut inner = clone.borrow_mut();
|
||||
inner.add_gamepad(&event);
|
||||
});
|
||||
|
||||
(*window).add_event_listener_with_callback("gamepadconnected", cb.as_ref().unchecked_ref());
|
||||
|
||||
cb.forget();
|
||||
|
||||
Ok(Engine {
|
||||
inner: Rc::new(RefCell::new(inner)),
|
||||
inner,
|
||||
window,
|
||||
document,
|
||||
performance,
|
||||
@ -146,7 +157,7 @@ impl Engine {
|
||||
let duration = unwrap!(now.duration_since(inner.after_loop).ok());
|
||||
inner.after_loop = now;
|
||||
|
||||
if (self.document.has_focus()?) {
|
||||
if self.document.has_focus()? {
|
||||
// Manage events
|
||||
while let Some(event) = inner.keyboard.pop() {
|
||||
inner.scene.manage_event(&event);
|
||||
@ -231,6 +242,9 @@ pub struct InnerEngine {
|
||||
/// The keyboard.
|
||||
pub keyboard: Keyboard,
|
||||
|
||||
/// The gamepads.
|
||||
pub gamepads: Vec<GamepadMap>,
|
||||
|
||||
/// The texture manager.
|
||||
pub textures: TextureManager,
|
||||
}
|
||||
@ -246,9 +260,20 @@ impl InnerEngine {
|
||||
scene,
|
||||
after_loop: now(&performance),
|
||||
keyboard: Keyboard::new(document)?,
|
||||
gamepads: vec![],
|
||||
textures: TextureManager::new()?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Adds a gamepad.
|
||||
pub fn add_gamepad(&mut self, gamepad: &web_sys::GamepadEvent) {
|
||||
let gamepad = GamepadMap::from_gamepad(gamepad.gamepad().unwrap());
|
||||
let clone = gamepad.clone();
|
||||
self.gamepads.push(clone);
|
||||
|
||||
let controlable = self.scene.controlable_mut().unwrap();
|
||||
controlable.set_controls(Some(Controls::Gamepad(gamepad)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Our custom drawable trait.
|
||||
|
@ -55,6 +55,16 @@ impl Scene {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the controlable.
|
||||
pub fn controlable_mut(&mut self) -> Option<&mut Character> {
|
||||
for character in &mut self.characters {
|
||||
if character.controls().is_some() {
|
||||
return Some(character);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the right view.
|
||||
pub fn view(&self) -> Option<Bbox> {
|
||||
let view = self.controlable()?.view();
|
||||
@ -109,7 +119,7 @@ impl Scene {
|
||||
c.ground_collision();
|
||||
}
|
||||
|
||||
if (damage) {
|
||||
if damage {
|
||||
c.die();
|
||||
state = State::Finished;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user