Gamepad controls start working

This commit is contained in:
Thomas Forgione 2022-08-02 15:35:10 +02:00
parent db8fa3ebc8
commit 10934b6209
5 changed files with 80 additions and 21 deletions

View File

@ -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;
}

View File

@ -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,
},
}
}
}

View File

@ -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));
}
}
}

View File

@ -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();

View File

@ -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);
}