Time starts working

This commit is contained in:
Thomas Forgione 2022-07-30 17:13:50 +02:00
parent 6360cd3bee
commit e08e348433
7 changed files with 76 additions and 49 deletions

48
Cargo.lock generated
View File

@ -25,19 +25,13 @@ dependencies = [
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.58" version = "0.3.59"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.17"
@ -48,10 +42,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "proc-macro2" name = "once_cell"
version = "1.0.40" version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "proc-macro2"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -84,9 +84,9 @@ checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@ -94,13 +94,13 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static",
"log", "log",
"once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -109,9 +109,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -119,9 +119,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -132,15 +132,15 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.58" version = "0.3.59"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",

View File

@ -22,4 +22,5 @@ features = [
'HtmlCanvasElement', 'HtmlCanvasElement',
'HtmlImageElement', 'HtmlImageElement',
'Window', 'Window',
'Performance',
] ]

View File

@ -1,11 +1,11 @@
//! This module helps us dealing with characters. //! This module helps us dealing with characters.
use std::time::{Duration, Instant}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
use crate::engine::bbox::Bbox; use crate::engine::bbox::Bbox;
use crate::engine::controls::{Action, Controls}; use crate::engine::controls::{Action, Controls};
use crate::engine::event::{Event, Keyboard}; use crate::engine::event::{Event, Keyboard};
use crate::engine::math::{clamp, duration_as_f64}; 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;
use crate::engine::texture::Texture; use crate::engine::texture::Texture;
@ -70,7 +70,7 @@ pub struct Character {
max_jump: usize, max_jump: usize,
/// The timer of the character's animation. /// The timer of the character's animation.
animation_timer: Duration, animation_timer: SystemTime,
/// Whether the character is walking or not. /// Whether the character is walking or not.
walking: bool, walking: bool,
@ -89,7 +89,7 @@ impl Character {
side: Side::Right, side: Side::Right,
jump_counter: 1, jump_counter: 1,
max_jump: 1, max_jump: 1,
animation_timer: Duration::from_millis(0), animation_timer: UNIX_EPOCH,
can_jump: true, can_jump: true,
walking: false, walking: false,
} }
@ -147,7 +147,7 @@ impl Character {
} }
impl Updatable for Character { impl Updatable for Character {
fn update(&mut self, duration: &Duration, keyboard: &Keyboard) { fn update(&mut self, now: SystemTime, duration: Duration, keyboard: &Keyboard) {
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 {
@ -156,13 +156,13 @@ impl Updatable for Character {
if let Some(side) = Side::from_force(force) { if let Some(side) = Side::from_force(force) {
if !self.walking { if !self.walking {
self.animation_timer = Duration::from_millis(0); self.animation_timer = now;
} }
self.walking = true; self.walking = true;
self.side = side; self.side = side;
} else { } else {
if self.walking { if self.walking {
self.animation_timer = Duration::from_millis(0); self.animation_timer = now;
} }
self.walking = false; self.walking = false;
} }
@ -218,8 +218,8 @@ impl Drawable for Character {
Texture::Rusty Texture::Rusty
} }
fn texture_rect(&self) -> Bbox { fn texture_rect(&self, now: SystemTime) -> Bbox {
let frame = 0.0; // duration_as_frame(&Instant::now().duration_since(self.animation_timer), 4); let frame = duration_as_frame(now.duration_since(self.animation_timer).unwrap(), 4) as f64;
let offset = if self.walking { 64.0 } else { 0.0 }; let offset = if self.walking { 64.0 } else { 0.0 };
Bbox::new(self.side.offset() as f64 + offset, frame * 32.0, 32.0, 32.0) Bbox::new(self.side.offset() as f64 + offset, frame * 32.0, 32.0, 32.0)
} }

View File

@ -1,5 +1,7 @@
//! This module contains everything related to maps. //! This module contains everything related to maps.
use std::time::SystemTime;
use crate::engine::bbox::Bbox; use crate::engine::bbox::Bbox;
use crate::engine::math::{clamp, Matrix}; use crate::engine::math::{clamp, Matrix};
use crate::engine::texture::Texture; use crate::engine::texture::Texture;
@ -233,9 +235,9 @@ impl Drawable for PositionedTile {
Texture::Overworld Texture::Overworld
} }
fn texture_rect(&self) -> Bbox { fn texture_rect(&self, _now: SystemTime) -> Bbox {
let offset = self.graphic.offset(); let offset = self.graphic.offset();
Bbox::new(offset.0 as f64, offset.0 as f64, SPRITE_SIZE, SPRITE_SIZE) Bbox::new(offset.0 as f64, offset.1 as f64, SPRITE_SIZE, SPRITE_SIZE)
} }
fn position(&self) -> Vector { fn position(&self) -> Vector {

View File

@ -1,7 +1,14 @@
//! This module contains useful math tools. //! This module contains useful math tools.
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use std::time::Duration; use std::time::{Duration, SystemTime, UNIX_EPOCH};
pub fn now(performance: &web_sys::Performance) -> SystemTime {
let now = performance.now();
let secs = (now as u64) / 1_000;
let nanos = (((now as u64) % 1_000) as u32) * 1_000_000;
UNIX_EPOCH + Duration::new(secs, nanos)
}
/// Clamp a number between two boundaries. /// Clamp a number between two boundaries.
pub fn clamp(number: f64, min: f64, max: f64) -> f64 { pub fn clamp(number: f64, min: f64, max: f64) -> f64 {
@ -15,14 +22,14 @@ pub fn clamp(number: f64, min: f64, max: f64) -> f64 {
} }
/// Converts a duration into an animation frame number. /// Converts a duration into an animation frame number.
pub fn duration_as_frame(duration: &Duration, total: usize) -> i32 { pub fn duration_as_frame(duration: Duration, total: usize) -> i32 {
let secs = duration_as_f64(duration); let secs = duration_as_f64(duration);
(secs * 10.0) as i32 % total as i32 (secs * 10.0) as i32 % total as i32
} }
/// Converts a duration into its number of seconds. /// Converts a duration into its number of seconds.
pub fn duration_as_f64(duration: &Duration) -> f64 { pub fn duration_as_f64(duration: Duration) -> f64 {
duration.as_secs() as f64 + duration.subsec_nanos() as f64 / 1_000_000_000.0 duration.as_secs() as f64 + duration.subsec_nanos() as f64 / 1_000_000_000.0
} }

View File

@ -13,7 +13,7 @@ pub mod vector;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::time::Duration; use std::time::{Duration, SystemTime};
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
@ -23,6 +23,7 @@ use crate::engine::character::Character;
use crate::engine::controls::Controls; use crate::engine::controls::Controls;
use crate::engine::event::{Key, Keyboard}; use crate::engine::event::{Key, Keyboard};
use crate::engine::map::Map; use crate::engine::map::Map;
use crate::engine::math::now;
use crate::engine::scene::{Scene, State}; use crate::engine::scene::{Scene, State};
use crate::engine::texture::{Texture, TextureManager}; use crate::engine::texture::{Texture, TextureManager};
use crate::engine::vector::Vector; use crate::engine::vector::Vector;
@ -55,6 +56,9 @@ pub struct Engine {
/// ///
/// We keep a reference so that we can easily render things. /// We keep a reference so that we can easily render things.
pub context: Rc<web_sys::CanvasRenderingContext2d>, pub context: Rc<web_sys::CanvasRenderingContext2d>,
/// The performance object.
pub performance: Rc<web_sys::Performance>,
} }
impl Engine { impl Engine {
@ -62,6 +66,7 @@ impl Engine {
pub fn new() -> Result<Engine> { pub fn new() -> Result<Engine> {
let window = unwrap!(web_sys::window()); let window = unwrap!(web_sys::window());
let document = unwrap!(window.document()); let document = unwrap!(window.document());
let performance = unwrap!(window.performance());
let canvas = unwrap!(document.get_element_by_id("canvas")); let canvas = unwrap!(document.get_element_by_id("canvas"));
let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::<web_sys::HtmlCanvasElement>()?; let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::<web_sys::HtmlCanvasElement>()?;
@ -77,16 +82,18 @@ impl Engine {
let character = Character::with_controls(Controls::default_keyboard()); let character = Character::with_controls(Controls::default_keyboard());
scene.add(character); scene.add(character);
let inner = InnerEngine::new(&document, scene)?; let inner = InnerEngine::new(&document, &performance, scene)?;
let window = Rc::new(window); let window = Rc::new(window);
let document = Rc::new(document); let document = Rc::new(document);
let performance = Rc::new(performance);
let context = Rc::new(context); let context = Rc::new(context);
Ok(Engine { Ok(Engine {
inner: Rc::new(RefCell::new(inner)), inner: Rc::new(RefCell::new(inner)),
window, window,
document, document,
performance,
context, context,
}) })
} }
@ -140,10 +147,12 @@ impl Engine {
} }
// Manage the physics // Manage the physics
let duration = Duration::from_millis(60); let now = now(&self.performance);
let duration = unwrap!(now.duration_since(inner.after_loop).ok());
inner.after_loop = now;
let keyboard = inner.keyboard.clone(); let keyboard = inner.keyboard.clone();
if inner.scene.update(&duration, &keyboard) == State::Finished { if inner.scene.update(now, duration, &keyboard) == State::Finished {
// running = false; // running = false;
} }
@ -155,7 +164,7 @@ impl Engine {
let inner = self.inner.borrow(); let inner = self.inner.borrow();
let image = inner.textures.get(drawable.texture()); let image = inner.textures.get(drawable.texture());
let source = drawable.texture_rect(); let source = drawable.texture_rect(inner.after_loop);
let mut dest = source.clone(); let mut dest = source.clone();
dest.position = drawable.position(); dest.position = drawable.position();
@ -203,6 +212,9 @@ pub struct InnerEngine {
/// The scene of the engine. /// The scene of the engine.
pub scene: Scene, pub scene: Scene,
/// The time when the loop is done.
pub after_loop: SystemTime,
/// The keyboard. /// The keyboard.
pub keyboard: Keyboard, pub keyboard: Keyboard,
@ -212,9 +224,14 @@ pub struct InnerEngine {
impl InnerEngine { impl InnerEngine {
/// Initializes the engine. /// Initializes the engine.
pub fn new(document: &web_sys::Document, scene: Scene) -> Result<InnerEngine> { pub fn new(
document: &web_sys::Document,
performance: &web_sys::Performance,
scene: Scene,
) -> Result<InnerEngine> {
Ok(InnerEngine { Ok(InnerEngine {
scene, scene,
after_loop: now(&performance),
keyboard: Keyboard::new(document)?, keyboard: Keyboard::new(document)?,
textures: TextureManager::new()?, textures: TextureManager::new()?,
}) })
@ -227,7 +244,7 @@ pub trait Drawable {
fn texture(&self) -> Texture; fn texture(&self) -> Texture;
/// Returns the coordinates to use on the texture. /// Returns the coordinates to use on the texture.
fn texture_rect(&self) -> Bbox; fn texture_rect(&self, now: SystemTime) -> Bbox;
/// Returns the position on which the drawable should be drawn. /// Returns the position on which the drawable should be drawn.
fn position(&self) -> Vector; fn position(&self) -> Vector;

View File

@ -1,6 +1,6 @@
//! This module contains the scene struct which holds everything needed during a game. //! This module contains the scene struct which holds everything needed during a game.
use std::time::Duration; use std::time::{Duration, SystemTime};
use crate::engine::character::Character; use crate::engine::character::Character;
use crate::engine::event::{Event, Keyboard}; use crate::engine::event::{Event, Keyboard};
@ -84,7 +84,7 @@ impl Scene {
// } // }
/// Updates the whole scene. /// Updates the whole scene.
pub fn update(&mut self, duration: &Duration, keyboard: &Keyboard) -> State { pub fn update(&mut self, now: SystemTime, duration: Duration, keyboard: &Keyboard) -> State {
let mut state = State::Finished; let mut state = State::Finished;
for c in &mut self.characters { for c in &mut self.characters {
@ -96,7 +96,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(duration, keyboard); c.update(now, duration, keyboard);
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;
@ -144,7 +144,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, duration: &Duration, keyboard: &Keyboard); fn update(&mut self, now: SystemTime, duration: Duration, keyboard: &Keyboard);
/// Called when an event arrives. /// Called when an event arrives.
fn manage_event(&mut self, event: &Event); fn manage_event(&mut self, event: &Event);