Preparing for massive refactoring
This commit is contained in:
parent
c771d1ccea
commit
6a1cc8876f
@ -3,8 +3,8 @@
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::controls::{Action, Controls};
|
||||
use crate::engine::event::{Event, Keyboard};
|
||||
use crate::engine::controls::Controls;
|
||||
use crate::engine::event::Action;
|
||||
use crate::engine::math::{clamp, duration_as_f64, duration_as_frame};
|
||||
use crate::engine::physics;
|
||||
use crate::engine::scene::Updatable;
|
||||
@ -74,9 +74,6 @@ pub struct Character {
|
||||
|
||||
/// Whether the character is walking or not.
|
||||
walking: bool,
|
||||
|
||||
/// Indicates that the player has released the jump button.
|
||||
can_jump: bool,
|
||||
}
|
||||
|
||||
impl Character {
|
||||
@ -90,7 +87,6 @@ impl Character {
|
||||
jump_counter: 1,
|
||||
max_jump: 1,
|
||||
animation_timer: UNIX_EPOCH,
|
||||
can_jump: true,
|
||||
walking: false,
|
||||
}
|
||||
}
|
||||
@ -107,7 +103,7 @@ impl Character {
|
||||
|
||||
/// Makes the character jump.
|
||||
pub fn jump(&mut self) {
|
||||
if self.can_jump && self.jump_counter > 0 {
|
||||
if self.jump_counter > 0 {
|
||||
self.jump_counter -= 1;
|
||||
self.speed.y = physics::JUMP_SPEED.y;
|
||||
}
|
||||
@ -152,11 +148,11 @@ impl Character {
|
||||
}
|
||||
|
||||
impl Updatable for Character {
|
||||
fn update(&mut self, now: SystemTime, duration: Duration, keyboard: &Keyboard) {
|
||||
fn update(&mut self, now: SystemTime, duration: Duration) {
|
||||
let mut force = Vector::new(0.0, 0.0);
|
||||
|
||||
if let Some(ref controls) = self.controls {
|
||||
force += controls.direction(keyboard);
|
||||
// force += controls.direction();
|
||||
}
|
||||
|
||||
if let Some(side) = Side::from_force(force) {
|
||||
@ -186,7 +182,7 @@ impl Updatable for Character {
|
||||
}
|
||||
|
||||
let limit = match self.controls {
|
||||
Some(ref controls) if controls.is_running() => physics::MAXIMUM_RUNNING_SPEED,
|
||||
// Some(ref controls) if controls.is_running() => physics::MAXIMUM_RUNNING_SPEED,
|
||||
_ => physics::MAXIMUM_WALKING_SPEED,
|
||||
};
|
||||
|
||||
@ -196,21 +192,11 @@ impl Updatable for Character {
|
||||
self.position += self.speed * duration;
|
||||
}
|
||||
|
||||
fn manage_event(&mut self, event: &Event) {
|
||||
let action = if let Some(ref controls) = self.controls {
|
||||
controls.convert(event)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
/// An action was asked to the character.
|
||||
fn manage_action(&mut self, action: Action) {
|
||||
match action {
|
||||
Some(Action::Jump(true)) => {
|
||||
Action::Button1 => {
|
||||
self.jump();
|
||||
self.can_jump = false;
|
||||
}
|
||||
|
||||
Some(Action::Jump(false)) => {
|
||||
self.can_jump = true;
|
||||
}
|
||||
|
||||
_ => (),
|
||||
|
@ -1,179 +1,4 @@
|
||||
//! This module helps to deal with controls.
|
||||
|
||||
use crate::engine::event::{Event, Key, Keyboard};
|
||||
use crate::engine::vector::Vector;
|
||||
use crate::log;
|
||||
|
||||
/// The different actions that a user can do.
|
||||
pub enum Action {
|
||||
/// The jump button.
|
||||
///
|
||||
/// A bool at true means that the button was pressed,
|
||||
/// A bool at false means that the button was released.
|
||||
Jump(bool),
|
||||
}
|
||||
|
||||
pub enum Controls {
|
||||
/// A keyboard controller.
|
||||
Keyboard(KeyboardMap),
|
||||
|
||||
/// A gamepad controller.
|
||||
Gamepad(GamepadMap),
|
||||
}
|
||||
|
||||
impl Controls {
|
||||
/// Returns the default keyboard controls.
|
||||
pub fn default_keyboard() -> Controls {
|
||||
Controls::Keyboard(KeyboardMap::default())
|
||||
}
|
||||
|
||||
/// Returns the default gamepad controls from id.
|
||||
///
|
||||
/// Returns None if the gamepad corresponding to the id is not connected.
|
||||
pub fn default_gamepad(gamepad: web_sys::Gamepad) -> Controls {
|
||||
Controls::Gamepad(GamepadMap::from_gamepad(gamepad))
|
||||
}
|
||||
|
||||
// /// Returns the default gamepad controls from id.
|
||||
// ///
|
||||
// /// Returns None if the gamepad corresponding to the id is not connected.
|
||||
// pub fn all_gamepads() -> Vec<Controls> {
|
||||
// GamepadMap::all()
|
||||
// .into_iter()
|
||||
// .map(|x| Controls::Gamepad(x))
|
||||
// .collect()
|
||||
// }
|
||||
|
||||
/// Converts an event and depending on the config, returns the corresponding action.
|
||||
pub fn convert(&self, event: &Event) -> Option<Action> {
|
||||
match self {
|
||||
Controls::Keyboard(ref map) => map.convert(event),
|
||||
Controls::Gamepad(ref map) => map.convert(event),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the direction of the controls.
|
||||
pub fn direction(&self, keyboard: &Keyboard) -> Vector {
|
||||
match self {
|
||||
Controls::Keyboard(ref map) => map.direction(keyboard),
|
||||
Controls::Gamepad(ref map) => map.direction(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the running key is pressed.
|
||||
pub fn is_running(&self) -> bool {
|
||||
false
|
||||
// match self {
|
||||
// Controls::Keyboard(ref map) => map.is_running(),
|
||||
// Controls::Gamepad(ref map) => map.is_running(),
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/// A map between keyboard keys and actions.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct KeyboardMap {
|
||||
/// The key corresponding to the jump button.
|
||||
jump_key: Key,
|
||||
|
||||
/// The key corresponding to the run button.
|
||||
run_key: Key,
|
||||
|
||||
/// The key corresponding to the left button.
|
||||
left_key: Key,
|
||||
|
||||
/// The key corresponding to the right button.
|
||||
right_key: Key,
|
||||
}
|
||||
|
||||
impl KeyboardMap {
|
||||
/// Creates the default keyboard config.
|
||||
pub fn default() -> KeyboardMap {
|
||||
KeyboardMap {
|
||||
jump_key: Key::Space,
|
||||
run_key: Key::ArrowUp,
|
||||
left_key: Key::ArrowLeft,
|
||||
right_key: Key::ArrowRight,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts an event and depending on the config, returns the corresponding action.
|
||||
pub fn convert(&self, event: &Event) -> Option<Action> {
|
||||
match event {
|
||||
Event::KeyPressed(code) if *code == self.jump_key => Some(Action::Jump(true)),
|
||||
Event::KeyReleased(code) if *code == self.jump_key => Some(Action::Jump(false)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the direction of the keys.
|
||||
pub fn direction(&self, keyboard: &Keyboard) -> Vector {
|
||||
let mut ret = Vector::new(0.0, 0.0);
|
||||
const RIGHT: Vector = Vector { x: 1.0, y: 0.0 };
|
||||
|
||||
if keyboard.is_key_pressed(self.right_key) {
|
||||
ret += RIGHT;
|
||||
}
|
||||
if keyboard.is_key_pressed(self.left_key) {
|
||||
ret -= RIGHT;
|
||||
}
|
||||
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)
|
||||
// }
|
||||
}
|
||||
/// The different types of controls.
|
||||
pub enum Controls {}
|
||||
|
@ -9,146 +9,30 @@ use wasm_bindgen::JsCast;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
/// The state of the keyboard.
|
||||
#[derive(Clone)]
|
||||
pub struct Keyboard {
|
||||
/// The inner keyboard.
|
||||
inner: Rc<RefCell<InnerKeyboard>>,
|
||||
}
|
||||
|
||||
impl Keyboard {
|
||||
/// Checks wether a key is pressed or not.
|
||||
pub fn is_key_pressed(&self, key: Key) -> bool {
|
||||
let mut b = self.inner.borrow_mut();
|
||||
*b.keys.entry(key).or_insert(false)
|
||||
}
|
||||
|
||||
/// Receives and treats an event.
|
||||
pub fn manage_event(&self, event: Event) {
|
||||
let mut b = self.inner.borrow_mut();
|
||||
match event {
|
||||
Event::KeyPressed(x) => *b.keys.entry(x).or_insert(true) = true,
|
||||
Event::KeyReleased(x) => *b.keys.entry(x).or_insert(false) = false,
|
||||
}
|
||||
|
||||
b.events.push_back(event);
|
||||
}
|
||||
|
||||
/// Gets an event from the event stack.
|
||||
pub fn pop(&self) -> Option<Event> {
|
||||
self.inner.borrow_mut().events.pop_front()
|
||||
}
|
||||
}
|
||||
|
||||
impl Keyboard {
|
||||
/// Initializes the keyboard.
|
||||
pub fn new(document: &web_sys::Document) -> Result<Keyboard> {
|
||||
let inner = Rc::new(RefCell::new(InnerKeyboard::new()));
|
||||
|
||||
let clone = Keyboard {
|
||||
inner: inner.clone(),
|
||||
};
|
||||
|
||||
let down_cb = Closure::<dyn FnMut(_)>::new(move |event: web_sys::KeyboardEvent| {
|
||||
if let Some(event) = Event::from_js(true, event) {
|
||||
clone.manage_event(event);
|
||||
}
|
||||
});
|
||||
|
||||
document.set_onkeydown(Some(down_cb.as_ref().unchecked_ref()));
|
||||
down_cb.forget();
|
||||
|
||||
let clone = Keyboard {
|
||||
inner: inner.clone(),
|
||||
};
|
||||
|
||||
let up_cb = Closure::<dyn FnMut(_)>::new(move |event: web_sys::KeyboardEvent| {
|
||||
if let Some(event) = Event::from_js(false, event) {
|
||||
clone.manage_event(event);
|
||||
}
|
||||
});
|
||||
|
||||
document.set_onkeyup(Some(up_cb.as_ref().unchecked_ref()));
|
||||
up_cb.forget();
|
||||
|
||||
Ok(Keyboard { inner })
|
||||
}
|
||||
}
|
||||
|
||||
/// The state of the keyboard.
|
||||
#[derive(Clone)]
|
||||
pub struct InnerKeyboard {
|
||||
/// Holds the state of the keys.
|
||||
keys: HashMap<Key, bool>,
|
||||
|
||||
/// The list of events to be processed.
|
||||
events: VecDeque<Event>,
|
||||
}
|
||||
|
||||
impl InnerKeyboard {
|
||||
/// Creates a new inner arrowboard.
|
||||
pub fn new() -> InnerKeyboard {
|
||||
InnerKeyboard {
|
||||
keys: HashMap::new(),
|
||||
events: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The different events that can occur.
|
||||
/// The different actions that a user can do.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Event {
|
||||
/// A key was pressed down.
|
||||
KeyPressed(Key),
|
||||
pub enum Action {
|
||||
/// The user asks to go to the left.
|
||||
GoLeft,
|
||||
|
||||
/// A key was released.
|
||||
KeyReleased(Key),
|
||||
}
|
||||
|
||||
/// The different key we cant to support.
|
||||
#[derive(Hash, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Key {
|
||||
/// The left arrow key.
|
||||
ArrowLeft,
|
||||
|
||||
/// The right arrow key.
|
||||
ArrowRight,
|
||||
|
||||
/// The up arrow key.
|
||||
ArrowUp,
|
||||
|
||||
/// The bottom arrow key.
|
||||
ArrowDown,
|
||||
|
||||
/// The space key.
|
||||
Space,
|
||||
}
|
||||
|
||||
impl Key {
|
||||
/// Tries and converts a javascript key to our key type.
|
||||
pub fn from_str(string: &str) -> Option<Key> {
|
||||
match string {
|
||||
"ArrowLeft" => Some(Key::ArrowLeft),
|
||||
"ArrowRight" => Some(Key::ArrowRight),
|
||||
"ArrowUp" => Some(Key::ArrowUp),
|
||||
"ArrowDown" => Some(Key::ArrowDown),
|
||||
"Space" => Some(Key::Space),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Event {
|
||||
/// Tries and converts a javacript event to our event type.
|
||||
pub fn from_js(down: bool, event: web_sys::KeyboardEvent) -> Option<Event> {
|
||||
let key = Key::from_str(&event.code())?;
|
||||
|
||||
let event = if down {
|
||||
Some(Event::KeyPressed(key))
|
||||
} else {
|
||||
Some(Event::KeyReleased(key))
|
||||
};
|
||||
|
||||
event
|
||||
}
|
||||
/// The user asks to go to the right.
|
||||
GoRight,
|
||||
|
||||
/// The user asks to go up.
|
||||
GoUp,
|
||||
|
||||
/// The user asks to go down.
|
||||
GoDown,
|
||||
|
||||
/// The user asks to do the main action or validate.
|
||||
Button1,
|
||||
|
||||
/// The user asks to do the secondary action.
|
||||
Button2,
|
||||
|
||||
/// The user asks to do the tertiary action.
|
||||
Button3,
|
||||
|
||||
/// The user asks to do the 4th action or cancel.
|
||||
Button4,
|
||||
}
|
||||
|
@ -20,8 +20,7 @@ use wasm_bindgen::JsCast;
|
||||
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::character::Character;
|
||||
use crate::engine::controls::{Controls, GamepadMap};
|
||||
use crate::engine::event::{Key, Keyboard};
|
||||
use crate::engine::controls::Controls;
|
||||
use crate::engine::map::Map;
|
||||
use crate::engine::math::now;
|
||||
use crate::engine::scene::{Scene, State};
|
||||
@ -79,7 +78,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::with_controls(Controls::default_keyboard());
|
||||
let character = Character::new();
|
||||
scene.add(character);
|
||||
|
||||
let inner = InnerEngine::new(&document, &performance, scene)?;
|
||||
@ -159,20 +158,20 @@ impl Engine {
|
||||
|
||||
if self.document.has_focus()? {
|
||||
// Manage events
|
||||
while let Some(event) = inner.keyboard.pop() {
|
||||
inner.scene.manage_event(&event);
|
||||
}
|
||||
// while let Some(event) = inner.keyboard.pop() {
|
||||
// inner.scene.manage_action(&action);
|
||||
// }
|
||||
|
||||
let keyboard = inner.keyboard.clone();
|
||||
if inner.scene.update(now, duration, &keyboard) == State::Finished {
|
||||
let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap();
|
||||
let mut scene = Scene::from_map(map);
|
||||
// let keyboard = inner.keyboard.clone();
|
||||
// if inner.scene.update(now, duration) == State::Finished {
|
||||
// let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap();
|
||||
// let mut scene = Scene::from_map(map);
|
||||
|
||||
let character = Character::with_controls(Controls::default_keyboard());
|
||||
scene.add(character);
|
||||
// let character = Character::with_controls(Controls::default_keyboard());
|
||||
// scene.add(character);
|
||||
|
||||
inner.scene = scene;
|
||||
}
|
||||
// inner.scene = scene;
|
||||
// }
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -239,12 +238,6 @@ pub struct InnerEngine {
|
||||
/// The time when the loop is done.
|
||||
pub after_loop: SystemTime,
|
||||
|
||||
/// The keyboard.
|
||||
pub keyboard: Keyboard,
|
||||
|
||||
/// The gamepads.
|
||||
pub gamepads: Vec<GamepadMap>,
|
||||
|
||||
/// The texture manager.
|
||||
pub textures: TextureManager,
|
||||
}
|
||||
@ -259,20 +252,18 @@ impl InnerEngine {
|
||||
Ok(InnerEngine {
|
||||
scene,
|
||||
after_loop: now(&performance),
|
||||
keyboard: Keyboard::new(document)?,
|
||||
gamepads: vec![],
|
||||
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 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)));
|
||||
// let controlable = self.scene.controlable_mut().unwrap();
|
||||
// controlable.set_controls(Some(Controls::Gamepad(gamepad)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ use std::time::{Duration, SystemTime};
|
||||
|
||||
use crate::engine::bbox::Bbox;
|
||||
use crate::engine::character::Character;
|
||||
use crate::engine::event::{Event, Keyboard};
|
||||
use crate::engine::event::Action;
|
||||
use crate::engine::map::Map;
|
||||
use crate::engine::texture::SPRITE_SIZE;
|
||||
|
||||
@ -95,7 +95,7 @@ impl Scene {
|
||||
}
|
||||
|
||||
/// Updates the whole scene.
|
||||
pub fn update(&mut self, now: SystemTime, duration: Duration, keyboard: &Keyboard) -> State {
|
||||
pub fn update(&mut self, now: SystemTime, duration: Duration) -> State {
|
||||
let mut state = State::Running;
|
||||
|
||||
for c in &mut self.characters {
|
||||
@ -107,7 +107,7 @@ impl Scene {
|
||||
// Compute the offset between position and bbox
|
||||
let offset = old.position - c.position;
|
||||
|
||||
c.update(now, duration, keyboard);
|
||||
c.update(now, duration);
|
||||
|
||||
if let Some((axis, position, damage)) = self.map.collides_bbox(old, c.bbox()) {
|
||||
c.position = position - offset;
|
||||
@ -132,10 +132,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,8 +153,8 @@ impl Scene {
|
||||
/// Trait that needs to be implemented for everything that can be updatable.
|
||||
pub trait Updatable {
|
||||
/// Updates the thing depending on the duration since last frame.
|
||||
fn update(&mut self, now: SystemTime, duration: Duration, keyboard: &Keyboard);
|
||||
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