From d591fbe6938601e8b7961de2fab170e2ef0714f4 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Tue, 2 Aug 2022 15:45:38 +0200 Subject: [PATCH] Work on keyboard controls --- src/engine/controls.rs | 10 ++++++++- src/engine/input.rs | 51 +++++++++++++++++++++++++++++++++++++++++- src/engine/mod.rs | 2 +- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/engine/controls.rs b/src/engine/controls.rs index d8b4129..46c1fbc 100644 --- a/src/engine/controls.rs +++ b/src/engine/controls.rs @@ -1,9 +1,12 @@ //! This module helps to deal with controls. -use crate::engine::input::{Action, Event}; +use crate::engine::input::{Action, Button, Event, Key}; /// The different types of controls. pub enum Controls { + /// Default keyboard controls. + Keyboard, + /// A gamepad controls the scene. Gamepad(u32), } @@ -12,6 +15,11 @@ impl Controls { /// Converts an event into an action if it corresponds to an action. pub fn convert(&self, event: Event) -> Option { match self { + Controls::Keyboard => match event { + Event::KeyPressed(Key::Space) => Some(Action::ButtonPressed(Button::Button1)), + Event::KeyReleased(Key::Space) => Some(Action::ButtonReleased(Button::Button1)), + _ => None, + }, Controls::Gamepad(ig) => match event { Event::ButtonPressed(ie, button) if *ig == ie => { Some(Action::ButtonPressed(button)) diff --git a/src/engine/input.rs b/src/engine/input.rs index 3eb25f3..198d304 100644 --- a/src/engine/input.rs +++ b/src/engine/input.rs @@ -12,6 +12,12 @@ use crate::{log, Result}; /// The different events that can be triggered. #[derive(Debug, Copy, Clone)] pub enum Event { + /// A key has been pressed. + KeyPressed(Key), + + /// A key has been released. + KeyReleased(Key), + /// A gamepad has been connected. GamepadConnected(u32), @@ -22,6 +28,13 @@ pub enum Event { ButtonReleased(u32, Button), } +/// The different keyboard keys we support. +#[derive(Debug, Copy, Clone)] +pub enum Key { + /// The space key. + Space, +} + /// The different actions a user can do. #[derive(Debug, Copy, Clone)] pub enum Action { @@ -78,6 +91,28 @@ impl InputManager { } } + /// Parses a keyboard event to the key. + pub fn key(event: web_sys::KeyboardEvent) -> Option { + match event.code().as_str() { + "Space" => Some(Key::Space), + _ => None, + } + } + + /// Adds a key pressed event to the list of events. + pub fn key_pressed_event(&mut self, event: web_sys::KeyboardEvent) { + if let Some(key) = InputManager::key(event) { + self.events.push_back(Event::KeyPressed(key)); + } + } + + /// Adds a key released event to the list of events. + pub fn key_released_event(&mut self, event: web_sys::KeyboardEvent) { + if let Some(key) = InputManager::key(event) { + self.events.push_back(Event::KeyReleased(key)); + } + } + /// Adds a gamepad to the input manager. pub fn add_gamepad(&mut self, gamepad: web_sys::Gamepad) { log!("Gamepad added {}", gamepad.id()); @@ -176,9 +211,23 @@ impl Inputs { let mut inner = clone.0.borrow_mut(); inner.add_gamepad(event.gamepad().unwrap()); }); - window.add_event_listener_with_callback("gamepadconnected", cb.as_ref().unchecked_ref())?; + cb.forget(); + let clone = inputs.clone(); + let cb = Closure::::new(move |event: web_sys::KeyboardEvent| { + let mut inner = clone.0.borrow_mut(); + inner.key_pressed_event(event); + }); + window.add_event_listener_with_callback("keydown", cb.as_ref().unchecked_ref())?; + cb.forget(); + + let clone = inputs.clone(); + let cb = Closure::::new(move |event: web_sys::KeyboardEvent| { + let mut inner = clone.0.borrow_mut(); + inner.key_released_event(event); + }); + window.add_event_listener_with_callback("keyup", cb.as_ref().unchecked_ref())?; cb.forget(); Ok(inputs) diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 859bf2b..0aed3e0 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -162,7 +162,7 @@ impl Engine { let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap(); let mut scene = Scene::from_map(map); - let character = Character::new(); + let character = Character::with_controls(Controls::Keyboard); scene.add(character); Ok(Engine {