Gamepad controls start working
This commit is contained in:
parent
db8fa3ebc8
commit
10934b6209
@ -4,7 +4,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::controls::Controls;
|
||||
use crate::engine::input::{Button, Event};
|
||||
use crate::engine::input::{Action, Button};
|
||||
use crate::engine::math::{clamp, duration_as_f64, duration_as_frame};
|
||||
use crate::engine::physics;
|
||||
use crate::engine::scene::Updatable;
|
||||
@ -196,15 +196,15 @@ impl Updatable for Character {
|
||||
self.position += self.speed * duration;
|
||||
}
|
||||
|
||||
/// An event was asked to the character.
|
||||
fn manage_event(&mut self, event: Event) {
|
||||
match event {
|
||||
Event::ButtonPressed(Button::Button1) => {
|
||||
/// An action was asked to the character.
|
||||
fn manage_action(&mut self, action: Action) {
|
||||
match action {
|
||||
Action::ButtonPressed(Button::Button1) => {
|
||||
self.jump();
|
||||
self.can_jump = false;
|
||||
}
|
||||
|
||||
Event::ButtonReleased(Button::Button1) => {
|
||||
Action::ButtonReleased(Button::Button1) => {
|
||||
self.can_jump = true;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,26 @@
|
||||
//! This module helps to deal with controls.
|
||||
|
||||
use crate::engine::input::{Action, Event};
|
||||
|
||||
/// The different types of controls.
|
||||
pub enum Controls {}
|
||||
pub enum Controls {
|
||||
/// A gamepad controls the scene.
|
||||
Gamepad(u32),
|
||||
}
|
||||
|
||||
impl Controls {
|
||||
/// Converts an event into an action if it corresponds to an action.
|
||||
pub fn convert(&self, event: Event) -> Option<Action> {
|
||||
match self {
|
||||
Controls::Gamepad(ig) => match event {
|
||||
Event::ButtonPressed(ie, button) if *ig == ie => {
|
||||
Some(Action::ButtonPressed(button))
|
||||
}
|
||||
Event::ButtonReleased(ie, button) if *ig == ie => {
|
||||
Some(Action::ButtonReleased(button))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,26 @@ use wasm_bindgen::JsCast;
|
||||
|
||||
use crate::{log, Result};
|
||||
|
||||
/// The different actions that a user can do.
|
||||
/// The different events that can be triggered.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Event {
|
||||
/// A button has been pressed.
|
||||
/// A gamepad has been connected.
|
||||
GamepadConnected(u32),
|
||||
|
||||
/// A button has been pressed on a certain gamepad.
|
||||
ButtonPressed(u32, Button),
|
||||
|
||||
/// A button has been released on a certain gamepad.
|
||||
ButtonReleased(u32, Button),
|
||||
}
|
||||
|
||||
/// The different actions a user can do.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Action {
|
||||
/// A certain button has been pressed.
|
||||
ButtonPressed(Button),
|
||||
|
||||
/// A button has been released.
|
||||
/// A certain button has been released.
|
||||
ButtonReleased(Button),
|
||||
}
|
||||
|
||||
@ -68,6 +81,8 @@ impl InputManager {
|
||||
/// Adds a gamepad to the input manager.
|
||||
pub fn add_gamepad(&mut self, gamepad: web_sys::Gamepad) {
|
||||
log!("Gamepad added {}", gamepad.id());
|
||||
self.events
|
||||
.push_back(Event::GamepadConnected(gamepad.index()));
|
||||
self.gamepads.push(Gamepad::new(gamepad));
|
||||
}
|
||||
|
||||
@ -116,12 +131,12 @@ impl Gamepad {
|
||||
|
||||
if was_pressed && !is_pressed {
|
||||
// Button was released
|
||||
events.push_back(Event::ButtonReleased(button));
|
||||
events.push_back(Event::ButtonReleased(self.inner.index(), button));
|
||||
}
|
||||
|
||||
if is_pressed && !was_pressed {
|
||||
// Button was pressed
|
||||
events.push_back(Event::ButtonPressed(button));
|
||||
events.push_back(Event::ButtonPressed(self.inner.index(), button));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use wasm_bindgen::JsCast;
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::character::Character;
|
||||
use crate::engine::controls::Controls;
|
||||
use crate::engine::input::Inputs;
|
||||
use crate::engine::input::{Event, Inputs};
|
||||
use crate::engine::map::Map;
|
||||
use crate::engine::math::now;
|
||||
use crate::engine::scene::{Scene, State};
|
||||
@ -38,6 +38,15 @@ macro_rules! unwrap {
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! unwrap_or_continue {
|
||||
($t: expr) => {{
|
||||
match $t {
|
||||
Some(x) => x,
|
||||
None => continue,
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Our game engine.
|
||||
#[derive(Clone)]
|
||||
pub struct Game(Rc<RefCell<Engine>>);
|
||||
@ -181,7 +190,17 @@ impl Engine {
|
||||
if self.document.has_focus()? {
|
||||
// Manage events
|
||||
while let Some(event) = self.inputs.next() {
|
||||
self.scene.manage_event(event);
|
||||
// Convert events into actions
|
||||
let mut controlable = unwrap_or_continue!(self.scene.controlable_mut());
|
||||
|
||||
// If gamepad connected, make it control the character
|
||||
if let Event::GamepadConnected(id) = event {
|
||||
controlable.set_controls(Some(Controls::Gamepad(id)));
|
||||
}
|
||||
|
||||
let controls = unwrap_or_continue!(controlable.controls());
|
||||
let action = unwrap_or_continue!(controls.convert(event));
|
||||
self.scene.manage_action(action);
|
||||
}
|
||||
|
||||
// let keyboard = inner.keyboard.clone();
|
||||
|
@ -4,7 +4,7 @@ use std::time::{Duration, SystemTime};
|
||||
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::character::Character;
|
||||
use crate::engine::input::Event;
|
||||
use crate::engine::input::Action;
|
||||
use crate::engine::map::Map;
|
||||
use crate::engine::texture::SPRITE_SIZE;
|
||||
|
||||
@ -46,7 +46,7 @@ impl Scene {
|
||||
}
|
||||
|
||||
/// Returns the controlable.
|
||||
fn controlable(&self) -> Option<&Character> {
|
||||
pub fn controlable(&self) -> Option<&Character> {
|
||||
// TODO fix this
|
||||
return Some(&self.characters[0]);
|
||||
|
||||
@ -60,6 +60,9 @@ impl Scene {
|
||||
|
||||
/// Returns the controlable.
|
||||
pub fn controlable_mut(&mut self) -> Option<&mut Character> {
|
||||
// TODO fix this
|
||||
return Some(&mut self.characters[0]);
|
||||
|
||||
for character in &mut self.characters {
|
||||
if character.controls().is_some() {
|
||||
return Some(character);
|
||||
@ -135,10 +138,10 @@ impl Scene {
|
||||
state
|
||||
}
|
||||
|
||||
/// Transfers an event to the elements contained in the scene that should receive events.
|
||||
pub fn manage_event(&mut self, event: Event) {
|
||||
/// Transfers an action to the elements contained in the scene that should receive actions.
|
||||
pub fn manage_action(&mut self, action: Action) {
|
||||
for c in &mut self.characters {
|
||||
c.manage_event(event);
|
||||
c.manage_action(action);
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +161,6 @@ pub trait Updatable {
|
||||
/// Updates the thing depending on the duration since last frame.
|
||||
fn update(&mut self, now: SystemTime, duration: Duration);
|
||||
|
||||
/// Called when an event arrives.
|
||||
fn manage_event(&mut self, event: Event);
|
||||
/// Called when an action arrives.
|
||||
fn manage_action(&mut self, action: Action);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user