Working on gamepads
This commit is contained in:
parent
2858e3d5ec
commit
c771d1ccea
@ -23,4 +23,6 @@ features = [
|
|||||||
'HtmlImageElement',
|
'HtmlImageElement',
|
||||||
'Window',
|
'Window',
|
||||||
'Performance',
|
'Performance',
|
||||||
|
'Gamepad',
|
||||||
|
'GamepadEvent',
|
||||||
]
|
]
|
||||||
|
@ -135,6 +135,11 @@ impl Character {
|
|||||||
&self.controls
|
&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.
|
/// Returns a view that looks at the character.
|
||||||
pub fn view(&self) -> Bbox {
|
pub fn view(&self) -> Bbox {
|
||||||
Bbox::from_center_and_size(self.position, Vector::new(24.0 * 16.0, 24.0 * 9.0))
|
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 {
|
pub enum Controls {
|
||||||
/// A keyboard controller.
|
/// A keyboard controller.
|
||||||
Keyboard(KeyboardMap),
|
Keyboard(KeyboardMap),
|
||||||
|
|
||||||
|
/// A gamepad controller.
|
||||||
|
Gamepad(GamepadMap),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Controls {
|
impl Controls {
|
||||||
@ -24,15 +27,12 @@ impl Controls {
|
|||||||
Controls::Keyboard(KeyboardMap::default())
|
Controls::Keyboard(KeyboardMap::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// Returns the default gamepad controls from id.
|
/// Returns the default gamepad controls from id.
|
||||||
// ///
|
///
|
||||||
// /// Returns None if the gamepad corresponding to the id is not connected.
|
/// Returns None if the gamepad corresponding to the id is not connected.
|
||||||
// pub fn default_gamepad_from_id(id: u32) -> Option<Controls> {
|
pub fn default_gamepad(gamepad: web_sys::Gamepad) -> Controls {
|
||||||
// match GamepadMap::from_id(id) {
|
Controls::Gamepad(GamepadMap::from_gamepad(gamepad))
|
||||||
// Some(map) => Some(Controls::Gamepad(map)),
|
}
|
||||||
// None => None,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Returns the default gamepad controls from id.
|
// /// Returns the default gamepad controls from id.
|
||||||
// ///
|
// ///
|
||||||
@ -48,7 +48,7 @@ impl Controls {
|
|||||||
pub fn convert(&self, event: &Event) -> Option<Action> {
|
pub fn convert(&self, event: &Event) -> Option<Action> {
|
||||||
match self {
|
match self {
|
||||||
Controls::Keyboard(ref map) => map.convert(event),
|
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 {
|
pub fn direction(&self, keyboard: &Keyboard) -> Vector {
|
||||||
match self {
|
match self {
|
||||||
Controls::Keyboard(ref map) => map.direction(keyboard),
|
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
|
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::bbox::Bbox;
|
||||||
use crate::engine::character::Character;
|
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::event::{Key, Keyboard};
|
||||||
use crate::engine::map::Map;
|
use crate::engine::map::Map;
|
||||||
use crate::engine::math::now;
|
use crate::engine::math::now;
|
||||||
@ -84,13 +84,24 @@ impl Engine {
|
|||||||
|
|
||||||
let inner = InnerEngine::new(&document, &performance, scene)?;
|
let inner = InnerEngine::new(&document, &performance, scene)?;
|
||||||
|
|
||||||
|
let inner = Rc::new(RefCell::new(inner));
|
||||||
let window = Rc::new(window);
|
let window = Rc::new(window);
|
||||||
let document = Rc::new(document);
|
let document = Rc::new(document);
|
||||||
let performance = Rc::new(performance);
|
let performance = Rc::new(performance);
|
||||||
let context = Rc::new(context);
|
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 {
|
Ok(Engine {
|
||||||
inner: Rc::new(RefCell::new(inner)),
|
inner,
|
||||||
window,
|
window,
|
||||||
document,
|
document,
|
||||||
performance,
|
performance,
|
||||||
@ -146,7 +157,7 @@ impl Engine {
|
|||||||
let duration = unwrap!(now.duration_since(inner.after_loop).ok());
|
let duration = unwrap!(now.duration_since(inner.after_loop).ok());
|
||||||
inner.after_loop = now;
|
inner.after_loop = now;
|
||||||
|
|
||||||
if (self.document.has_focus()?) {
|
if self.document.has_focus()? {
|
||||||
// Manage events
|
// Manage events
|
||||||
while let Some(event) = inner.keyboard.pop() {
|
while let Some(event) = inner.keyboard.pop() {
|
||||||
inner.scene.manage_event(&event);
|
inner.scene.manage_event(&event);
|
||||||
@ -231,6 +242,9 @@ pub struct InnerEngine {
|
|||||||
/// The keyboard.
|
/// The keyboard.
|
||||||
pub keyboard: Keyboard,
|
pub keyboard: Keyboard,
|
||||||
|
|
||||||
|
/// The gamepads.
|
||||||
|
pub gamepads: Vec<GamepadMap>,
|
||||||
|
|
||||||
/// The texture manager.
|
/// The texture manager.
|
||||||
pub textures: TextureManager,
|
pub textures: TextureManager,
|
||||||
}
|
}
|
||||||
@ -246,9 +260,20 @@ impl InnerEngine {
|
|||||||
scene,
|
scene,
|
||||||
after_loop: now(&performance),
|
after_loop: now(&performance),
|
||||||
keyboard: Keyboard::new(document)?,
|
keyboard: Keyboard::new(document)?,
|
||||||
|
gamepads: vec![],
|
||||||
textures: TextureManager::new()?,
|
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.
|
/// Our custom drawable trait.
|
||||||
|
@ -55,6 +55,16 @@ impl Scene {
|
|||||||
None
|
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.
|
/// Returns the right view.
|
||||||
pub fn view(&self) -> Option<Bbox> {
|
pub fn view(&self) -> Option<Bbox> {
|
||||||
let view = self.controlable()?.view();
|
let view = self.controlable()?.view();
|
||||||
@ -109,7 +119,7 @@ impl Scene {
|
|||||||
c.ground_collision();
|
c.ground_collision();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damage) {
|
if damage {
|
||||||
c.die();
|
c.die();
|
||||||
state = State::Finished;
|
state = State::Finished;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user