Direction now works
This commit is contained in:
parent
4cfe15de77
commit
908ae11393
@ -4,7 +4,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|||||||
|
|
||||||
use crate::engine::bbox::Bbox;
|
use crate::engine::bbox::Bbox;
|
||||||
use crate::engine::controls::Controls;
|
use crate::engine::controls::Controls;
|
||||||
use crate::engine::input::{Action, Button};
|
use crate::engine::input::{Action, Button, InputManager};
|
||||||
use crate::engine::math::{clamp, duration_as_f64, duration_as_frame};
|
use crate::engine::math::{clamp, duration_as_f64, duration_as_frame};
|
||||||
use crate::engine::physics;
|
use crate::engine::physics;
|
||||||
use crate::engine::scene::Updatable;
|
use crate::engine::scene::Updatable;
|
||||||
@ -152,11 +152,11 @@ impl Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Updatable for Character {
|
impl Updatable for Character {
|
||||||
fn update(&mut self, now: SystemTime, duration: Duration) {
|
fn update(&mut self, now: SystemTime, duration: Duration, inputs: &InputManager) {
|
||||||
let mut force = Vector::new(0.0, 0.0);
|
let mut force = Vector::new(0.0, 0.0);
|
||||||
|
|
||||||
if let Some(ref controls) = self.controls {
|
if let Some(ref controls) = self.controls {
|
||||||
// force += controls.direction();
|
force += controls.main_direction(inputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(side) = Side::from_force(force) {
|
if let Some(side) = Side::from_force(force) {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
//! This module helps to deal with controls.
|
//! This module helps to deal with controls.
|
||||||
|
|
||||||
use crate::engine::input::{Action, Button, Event, Key};
|
use crate::engine::input::{Action, Button, Event, InputManager, Key};
|
||||||
|
use crate::engine::vector::Vector;
|
||||||
|
|
||||||
/// The different types of controls.
|
/// The different types of controls.
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum Controls {
|
pub enum Controls {
|
||||||
/// Default keyboard controls.
|
/// Default keyboard controls.
|
||||||
Keyboard,
|
Keyboard,
|
||||||
@ -12,6 +14,31 @@ pub enum Controls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Controls {
|
impl Controls {
|
||||||
|
/// Returns the main direction held by the user.
|
||||||
|
pub fn main_direction(&self, input: &InputManager) -> Vector {
|
||||||
|
match self {
|
||||||
|
Controls::Keyboard => {
|
||||||
|
let mut dir = Vector::new(0.0, 0.0);
|
||||||
|
if input.is_key_pressed(Key::ArrowLeft) {
|
||||||
|
dir.x -= 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.is_key_pressed(Key::ArrowRight) {
|
||||||
|
dir.x += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir
|
||||||
|
}
|
||||||
|
Controls::Gamepad(id) => {
|
||||||
|
if let Some(gamepad) = input.gamepad(*id) {
|
||||||
|
gamepad.main_direction()
|
||||||
|
} else {
|
||||||
|
Vector::new(0.0, 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts an event into an action if it corresponds to an action.
|
/// Converts an event into an action if it corresponds to an action.
|
||||||
pub fn convert(&self, event: Event) -> Option<Action> {
|
pub fn convert(&self, event: Event) -> Option<Action> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -7,6 +7,8 @@ use std::rc::Rc;
|
|||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
|
use crate::engine::vector::Vector;
|
||||||
|
|
||||||
use crate::{log, Result};
|
use crate::{log, Result};
|
||||||
|
|
||||||
/// The different events that can be triggered.
|
/// The different events that can be triggered.
|
||||||
@ -29,8 +31,20 @@ pub enum Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The different keyboard keys we support.
|
/// The different keyboard keys we support.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
|
/// The left arrow key.
|
||||||
|
ArrowLeft,
|
||||||
|
|
||||||
|
/// The right arrow key.
|
||||||
|
ArrowRight,
|
||||||
|
|
||||||
|
/// The up arrow key.
|
||||||
|
ArrowUp,
|
||||||
|
|
||||||
|
/// The down arrow key.
|
||||||
|
ArrowDown,
|
||||||
|
|
||||||
/// The space key.
|
/// The space key.
|
||||||
Space,
|
Space,
|
||||||
}
|
}
|
||||||
@ -75,6 +89,9 @@ pub enum Button {
|
|||||||
|
|
||||||
/// This structure holds what button are pressed or released, and stores the events.
|
/// This structure holds what button are pressed or released, and stores the events.
|
||||||
pub struct InputManager {
|
pub struct InputManager {
|
||||||
|
/// The state of the keyboard.
|
||||||
|
keyboard: HashMap<Key, bool>,
|
||||||
|
|
||||||
/// All the connected gamepads.
|
/// All the connected gamepads.
|
||||||
gamepads: Vec<Gamepad>,
|
gamepads: Vec<Gamepad>,
|
||||||
|
|
||||||
@ -86,14 +103,24 @@ impl InputManager {
|
|||||||
/// Creates a new input manager.
|
/// Creates a new input manager.
|
||||||
pub fn new() -> InputManager {
|
pub fn new() -> InputManager {
|
||||||
InputManager {
|
InputManager {
|
||||||
|
keyboard: HashMap::new(),
|
||||||
gamepads: vec![],
|
gamepads: vec![],
|
||||||
events: VecDeque::new(),
|
events: VecDeque::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the gamepad from its id.
|
||||||
|
pub fn gamepad(&self, id: u32) -> Option<&Gamepad> {
|
||||||
|
self.gamepads.iter().find(|x| x.inner.index() == id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses a keyboard event to the key.
|
/// Parses a keyboard event to the key.
|
||||||
pub fn key(event: web_sys::KeyboardEvent) -> Option<Key> {
|
pub fn key(event: web_sys::KeyboardEvent) -> Option<Key> {
|
||||||
match event.code().as_str() {
|
match event.code().as_str() {
|
||||||
|
"ArrowDown" => Some(Key::ArrowDown),
|
||||||
|
"ArrowUp" => Some(Key::ArrowUp),
|
||||||
|
"ArrowLeft" => Some(Key::ArrowLeft),
|
||||||
|
"ArrowRight" => Some(Key::ArrowRight),
|
||||||
"Space" => Some(Key::Space),
|
"Space" => Some(Key::Space),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -102,6 +129,7 @@ impl InputManager {
|
|||||||
/// Adds a key pressed event to the list of events.
|
/// Adds a key pressed event to the list of events.
|
||||||
pub fn key_pressed_event(&mut self, event: web_sys::KeyboardEvent) {
|
pub fn key_pressed_event(&mut self, event: web_sys::KeyboardEvent) {
|
||||||
if let Some(key) = InputManager::key(event) {
|
if let Some(key) = InputManager::key(event) {
|
||||||
|
self.keyboard.insert(key, true);
|
||||||
self.events.push_back(Event::KeyPressed(key));
|
self.events.push_back(Event::KeyPressed(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,6 +137,7 @@ impl InputManager {
|
|||||||
/// Adds a key released event to the list of events.
|
/// Adds a key released event to the list of events.
|
||||||
pub fn key_released_event(&mut self, event: web_sys::KeyboardEvent) {
|
pub fn key_released_event(&mut self, event: web_sys::KeyboardEvent) {
|
||||||
if let Some(key) = InputManager::key(event) {
|
if let Some(key) = InputManager::key(event) {
|
||||||
|
self.keyboard.insert(key, false);
|
||||||
self.events.push_back(Event::KeyReleased(key));
|
self.events.push_back(Event::KeyReleased(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +156,11 @@ impl InputManager {
|
|||||||
gamepad.update(&mut self.events);
|
gamepad.update(&mut self.events);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if a specific key is pressed.
|
||||||
|
pub fn is_key_pressed(&self, key: Key) -> bool {
|
||||||
|
*self.keyboard.get(&key).unwrap_or(&false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Holds the gamepad information.
|
/// Holds the gamepad information.
|
||||||
@ -135,8 +169,21 @@ pub struct Gamepad {
|
|||||||
/// The javascript gamepad object.
|
/// The javascript gamepad object.
|
||||||
inner: web_sys::Gamepad,
|
inner: web_sys::Gamepad,
|
||||||
|
|
||||||
|
/// The main joystick.
|
||||||
|
main_joystick: Joystick,
|
||||||
|
|
||||||
/// What buttons are pressed or released.
|
/// What buttons are pressed or released.
|
||||||
state: HashMap<Button, bool>,
|
buttons: HashMap<Button, bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The joysticks.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Joystick {
|
||||||
|
/// The id of the X axis of the joystick.
|
||||||
|
pub x_id: u32,
|
||||||
|
|
||||||
|
/// The id of the Y axis of the joystick.
|
||||||
|
pub y_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gamepad {
|
impl Gamepad {
|
||||||
@ -144,10 +191,19 @@ impl Gamepad {
|
|||||||
pub fn new(inner: web_sys::Gamepad) -> Gamepad {
|
pub fn new(inner: web_sys::Gamepad) -> Gamepad {
|
||||||
Gamepad {
|
Gamepad {
|
||||||
inner,
|
inner,
|
||||||
state: HashMap::new(),
|
main_joystick: Joystick { x_id: 0, y_id: 1 },
|
||||||
|
buttons: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the direction of the main joystick.
|
||||||
|
pub fn main_direction(&self) -> Vector {
|
||||||
|
let axes = self.inner.axes();
|
||||||
|
let x = axes.get(self.main_joystick.x_id).as_f64().unwrap();
|
||||||
|
let y = axes.get(self.main_joystick.y_id).as_f64().unwrap();
|
||||||
|
Vector::new(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the state of the gamepad and adds the corresponding events to the deque.
|
/// Updates the state of the gamepad and adds the corresponding events to the deque.
|
||||||
pub fn update(&mut self, events: &mut VecDeque<Event>) {
|
pub fn update(&mut self, events: &mut VecDeque<Event>) {
|
||||||
const BUTTONS: [Button; 4] = [
|
const BUTTONS: [Button; 4] = [
|
||||||
@ -162,7 +218,7 @@ impl Gamepad {
|
|||||||
let is_pressed = self.is_js_pressed(button);
|
let is_pressed = self.is_js_pressed(button);
|
||||||
|
|
||||||
// Updates the map and returns the old state of the button
|
// Updates the map and returns the old state of the button
|
||||||
let was_pressed = self.state.insert(button, is_pressed).unwrap_or(false);
|
let was_pressed = self.buttons.insert(button, is_pressed).unwrap_or(false);
|
||||||
|
|
||||||
if was_pressed && !is_pressed {
|
if was_pressed && !is_pressed {
|
||||||
// Button was released
|
// Button was released
|
||||||
@ -178,7 +234,7 @@ impl Gamepad {
|
|||||||
|
|
||||||
/// Checks if a button is pressed.
|
/// Checks if a button is pressed.
|
||||||
pub fn is_pressed(&self, button: Button) -> bool {
|
pub fn is_pressed(&self, button: Button) -> bool {
|
||||||
*self.state.get(&button).unwrap_or(&false)
|
*self.buttons.get(&button).unwrap_or(&false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Utility function to really check the state of the button.
|
/// Utility function to really check the state of the button.
|
||||||
@ -199,7 +255,7 @@ impl Gamepad {
|
|||||||
|
|
||||||
/// A helper to easily deal with inputs.
|
/// A helper to easily deal with inputs.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Inputs(Rc<RefCell<InputManager>>);
|
pub struct Inputs(pub Rc<RefCell<InputManager>>);
|
||||||
|
|
||||||
impl Inputs {
|
impl Inputs {
|
||||||
/// Creates a new inputs object.
|
/// Creates a new inputs object.
|
||||||
|
@ -204,11 +204,22 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// let keyboard = inner.keyboard.clone();
|
// let keyboard = inner.keyboard.clone();
|
||||||
if self.scene.update(now, duration) == State::Finished {
|
let input_manager = self.inputs.0.borrow();
|
||||||
|
if self.scene.update(now, duration, &input_manager) == State::Finished {
|
||||||
|
let controls = self
|
||||||
|
.scene
|
||||||
|
.controlable()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.controls()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
|
||||||
let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap();
|
let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap();
|
||||||
let mut scene = Scene::from_map(map);
|
let mut scene = Scene::from_map(map);
|
||||||
|
|
||||||
let character = Character::new();
|
let character = Character::with_controls(controls);
|
||||||
scene.add(character);
|
scene.add(character);
|
||||||
|
|
||||||
self.scene = scene;
|
self.scene = scene;
|
||||||
|
@ -5,6 +5,7 @@ use std::time::{Duration, SystemTime};
|
|||||||
use crate::engine::bbox::Bbox;
|
use crate::engine::bbox::Bbox;
|
||||||
use crate::engine::character::Character;
|
use crate::engine::character::Character;
|
||||||
use crate::engine::input::Action;
|
use crate::engine::input::Action;
|
||||||
|
use crate::engine::input::InputManager;
|
||||||
use crate::engine::map::Map;
|
use crate::engine::map::Map;
|
||||||
use crate::engine::texture::SPRITE_SIZE;
|
use crate::engine::texture::SPRITE_SIZE;
|
||||||
|
|
||||||
@ -95,7 +96,7 @@ impl Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the whole scene.
|
/// Updates the whole scene.
|
||||||
pub fn update(&mut self, now: SystemTime, duration: Duration) -> State {
|
pub fn update(&mut self, now: SystemTime, duration: Duration, inputs: &InputManager) -> State {
|
||||||
let mut state = State::Running;
|
let mut state = State::Running;
|
||||||
|
|
||||||
for c in &mut self.characters {
|
for c in &mut self.characters {
|
||||||
@ -107,7 +108,7 @@ impl Scene {
|
|||||||
// Compute the offset between position and bbox
|
// Compute the offset between position and bbox
|
||||||
let offset = old.position - c.position;
|
let offset = old.position - c.position;
|
||||||
|
|
||||||
c.update(now, duration);
|
c.update(now, duration, inputs);
|
||||||
|
|
||||||
if let Some((axis, position, damage)) = self.map.collides_bbox(old, c.bbox()) {
|
if let Some((axis, position, damage)) = self.map.collides_bbox(old, c.bbox()) {
|
||||||
c.position = position - offset;
|
c.position = position - offset;
|
||||||
@ -153,7 +154,7 @@ impl Scene {
|
|||||||
/// Trait that needs to be implemented for everything that can be updatable.
|
/// Trait that needs to be implemented for everything that can be updatable.
|
||||||
pub trait Updatable {
|
pub trait Updatable {
|
||||||
/// Updates the thing depending on the duration since last frame.
|
/// Updates the thing depending on the duration since last frame.
|
||||||
fn update(&mut self, now: SystemTime, duration: Duration);
|
fn update(&mut self, now: SystemTime, duration: Duration, inputs: &InputManager);
|
||||||
|
|
||||||
/// Called when an action arrives.
|
/// Called when an action arrives.
|
||||||
fn manage_action(&mut self, action: Action);
|
fn manage_action(&mut self, action: Action);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user