Starting to get something
This commit is contained in:
parent
abe9b4ca38
commit
6360cd3bee
@ -8,7 +8,10 @@ use crate::engine::event::{Event, Keyboard};
|
|||||||
use crate::engine::math::{clamp, duration_as_f64};
|
use crate::engine::math::{clamp, duration_as_f64};
|
||||||
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::vector::Vector;
|
use crate::engine::vector::Vector;
|
||||||
|
use crate::engine::Drawable;
|
||||||
|
use crate::log;
|
||||||
|
|
||||||
/// The different sides a character can face.
|
/// The different sides a character can face.
|
||||||
pub enum Side {
|
pub enum Side {
|
||||||
@ -67,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: Instant,
|
animation_timer: Duration,
|
||||||
|
|
||||||
/// Whether the character is walking or not.
|
/// Whether the character is walking or not.
|
||||||
walking: bool,
|
walking: bool,
|
||||||
@ -86,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: Instant::now(),
|
animation_timer: Duration::from_millis(0),
|
||||||
can_jump: true,
|
can_jump: true,
|
||||||
walking: false,
|
walking: false,
|
||||||
}
|
}
|
||||||
@ -124,7 +127,7 @@ impl Character {
|
|||||||
|
|
||||||
/// Makes the player die.
|
/// Makes the player die.
|
||||||
pub fn die(&self) {
|
pub fn die(&self) {
|
||||||
panic!();
|
log!("dead");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the controls.
|
/// Returns a reference to the controls.
|
||||||
@ -153,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 = Instant::now();
|
self.animation_timer = Duration::from_millis(0);
|
||||||
}
|
}
|
||||||
self.walking = true;
|
self.walking = true;
|
||||||
self.side = side;
|
self.side = side;
|
||||||
} else {
|
} else {
|
||||||
if self.walking {
|
if self.walking {
|
||||||
self.animation_timer = Instant::now();
|
self.animation_timer = Duration::from_millis(0);
|
||||||
}
|
}
|
||||||
self.walking = false;
|
self.walking = false;
|
||||||
}
|
}
|
||||||
@ -210,18 +213,18 @@ impl Updatable for Character {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Drawable for Character {
|
impl Drawable for Character {
|
||||||
// fn texture(&self) -> Texture {
|
fn texture(&self) -> Texture {
|
||||||
// Texture::Rusty
|
Texture::Rusty
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// fn texture_rect(&self) -> IntRect {
|
fn texture_rect(&self) -> Bbox {
|
||||||
// let frame = duration_as_frame(&Instant::now().duration_since(self.animation_timer), 4);
|
let frame = 0.0; // duration_as_frame(&Instant::now().duration_since(self.animation_timer), 4);
|
||||||
// let offset = if self.walking { 64 } else { 0 };
|
let offset = if self.walking { 64.0 } else { 0.0 };
|
||||||
// IntRect::new(self.side.offset() + offset, frame * 32, 32, 32)
|
Bbox::new(self.side.offset() as f64 + offset, frame * 32.0, 32.0, 32.0)
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// fn position(&self) -> Vector<f32> {
|
fn position(&self) -> Vector {
|
||||||
// self.position
|
self.position
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use crate::engine::event::{Event, Key, Keyboard};
|
use crate::engine::event::{Event, Key, Keyboard};
|
||||||
use crate::engine::vector::Vector;
|
use crate::engine::vector::Vector;
|
||||||
|
use crate::log;
|
||||||
|
|
||||||
/// The different actions that a user can do.
|
/// The different actions that a user can do.
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
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::SPRITE_SIZE;
|
use crate::engine::texture::SPRITE_SIZE;
|
||||||
use crate::engine::vector::Vector;
|
use crate::engine::vector::Vector;
|
||||||
|
use crate::engine::Drawable;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
/// Converts the byte with bits corresponding to the neighbours to the offset on the generated
|
/// Converts the byte with bits corresponding to the neighbours to the offset on the generated
|
||||||
@ -62,7 +64,7 @@ pub fn byte_to_index(byte: u8) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This enum represents if the collision happens on the X axis or the Y axis.
|
/// This enum represents if the collision happens on the X axis or the Y axis.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum CollisionAxis {
|
pub enum CollisionAxis {
|
||||||
/// The X axis.
|
/// The X axis.
|
||||||
X,
|
X,
|
||||||
@ -226,20 +228,20 @@ pub struct PositionedTile {
|
|||||||
pub position: Vector,
|
pub position: Vector,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Drawable for PositionedTile {
|
impl Drawable for PositionedTile {
|
||||||
// fn texture(&self) -> Texture {
|
fn texture(&self) -> Texture {
|
||||||
// Texture::Overworld
|
Texture::Overworld
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// fn texture_rect(&self) -> Bbox {
|
fn texture_rect(&self) -> Bbox {
|
||||||
// let offset = self.graphic.offset();
|
let offset = self.graphic.offset();
|
||||||
// Bbox::new(offset.x, offset.x, SPRITE_SIZE, SPRITE_SIZE)
|
Bbox::new(offset.0 as f64, offset.0 as f64, SPRITE_SIZE, SPRITE_SIZE)
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// fn position(&self) -> Vector {
|
fn position(&self) -> Vector {
|
||||||
// self.position
|
self.position
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
/// The map represents the tiles contained in a level.
|
/// The map represents the tiles contained in a level.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -18,10 +18,14 @@ use std::time::Duration;
|
|||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
|
use crate::engine::bbox::Bbox;
|
||||||
|
use crate::engine::character::Character;
|
||||||
|
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::scene::{Scene, State};
|
use crate::engine::scene::{Scene, State};
|
||||||
use crate::engine::texture::TextureManager;
|
use crate::engine::texture::{Texture, TextureManager};
|
||||||
|
use crate::engine::vector::Vector;
|
||||||
use crate::{error_js, log, Result};
|
use crate::{error_js, log, Result};
|
||||||
|
|
||||||
macro_rules! unwrap {
|
macro_rules! unwrap {
|
||||||
@ -41,6 +45,9 @@ pub struct Engine {
|
|||||||
/// We need Rc<RefCell> in order to deal with events.
|
/// We need Rc<RefCell> in order to deal with events.
|
||||||
pub inner: Rc<RefCell<InnerEngine>>,
|
pub inner: Rc<RefCell<InnerEngine>>,
|
||||||
|
|
||||||
|
/// The web page window.
|
||||||
|
pub window: Rc<web_sys::Window>,
|
||||||
|
|
||||||
/// The web page document.
|
/// The web page document.
|
||||||
pub document: Rc<web_sys::Document>,
|
pub document: Rc<web_sys::Document>,
|
||||||
|
|
||||||
@ -61,20 +68,24 @@ impl Engine {
|
|||||||
canvas.set_width(1920);
|
canvas.set_width(1920);
|
||||||
canvas.set_height(1080);
|
canvas.set_height(1080);
|
||||||
|
|
||||||
let context = canvas
|
let context =
|
||||||
.get_context("2d")?
|
unwrap!(canvas.get_context("2d")?).dyn_into::<web_sys::CanvasRenderingContext2d>()?;
|
||||||
.unwrap()
|
|
||||||
.dyn_into::<web_sys::CanvasRenderingContext2d>()?;
|
|
||||||
|
|
||||||
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 scene = Scene::from_map(map);
|
let mut scene = Scene::from_map(map);
|
||||||
|
|
||||||
|
let character = Character::with_controls(Controls::default_keyboard());
|
||||||
|
scene.add(character);
|
||||||
|
|
||||||
let inner = InnerEngine::new(&document, scene)?;
|
let inner = InnerEngine::new(&document, scene)?;
|
||||||
|
|
||||||
|
let window = Rc::new(window);
|
||||||
let document = Rc::new(document);
|
let document = Rc::new(document);
|
||||||
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,
|
||||||
document,
|
document,
|
||||||
context,
|
context,
|
||||||
})
|
})
|
||||||
@ -89,10 +100,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
web_sys::window()
|
(*self.window).request_animation_frame(cb.as_ref().unchecked_ref())?;
|
||||||
.unwrap()
|
|
||||||
.request_animation_frame(cb.as_ref().unchecked_ref())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
cb.forget();
|
cb.forget();
|
||||||
|
|
||||||
@ -115,10 +123,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
web_sys::window()
|
(*self.window).request_animation_frame(cb.as_ref().unchecked_ref())?;
|
||||||
.unwrap()
|
|
||||||
.request_animation_frame(cb.as_ref().unchecked_ref())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
cb.forget();
|
cb.forget();
|
||||||
|
|
||||||
@ -142,29 +147,19 @@ impl Engine {
|
|||||||
// running = false;
|
// running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform update
|
Ok(())
|
||||||
let mut dx = 0.0;
|
}
|
||||||
let mut dy = 0.0;
|
|
||||||
|
|
||||||
if inner.keyboard.is_key_pressed(Key::ArrowDown) {
|
/// Draw a drawable.
|
||||||
dy += 5.0;
|
pub fn draw<D: Drawable>(&self, drawable: &D) -> Result<()> {
|
||||||
}
|
let inner = self.inner.borrow();
|
||||||
|
let image = inner.textures.get(drawable.texture());
|
||||||
|
|
||||||
if inner.keyboard.is_key_pressed(Key::ArrowUp) {
|
let source = drawable.texture_rect();
|
||||||
dy -= 5.0;
|
let mut dest = source.clone();
|
||||||
}
|
dest.position = drawable.position();
|
||||||
|
|
||||||
if inner.keyboard.is_key_pressed(Key::ArrowLeft) {
|
|
||||||
dx -= 5.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if inner.keyboard.is_key_pressed(Key::ArrowRight) {
|
|
||||||
dx += 5.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inner.x += dx;
|
|
||||||
inner.y += dy;
|
|
||||||
|
|
||||||
|
image.render(source, dest, &self.context)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,12 +167,32 @@ impl Engine {
|
|||||||
pub fn render(&self) -> Result<()> {
|
pub fn render(&self) -> Result<()> {
|
||||||
let inner = self.inner.borrow();
|
let inner = self.inner.borrow();
|
||||||
|
|
||||||
// Perform render
|
// Clear render
|
||||||
self.context.clear_rect(0.0, 0.0, 1920.0, 1080.0);
|
self.context.clear_rect(0.0, 0.0, 1920.0, 1080.0);
|
||||||
inner
|
self.context
|
||||||
.textures
|
.set_fill_style(&JsValue::from_str("rgb(135, 206, 235)"));
|
||||||
.rusty
|
self.context.fill_rect(0.0, 0.0, 1920.0, 1080.0);
|
||||||
.render(inner.x, inner.y, &self.context)?;
|
|
||||||
|
// Draw the scene
|
||||||
|
let map = inner.scene.map();
|
||||||
|
let rows = map.rows();
|
||||||
|
let cols = map.cols();
|
||||||
|
|
||||||
|
for i in 0..rows {
|
||||||
|
for j in 0..cols {
|
||||||
|
let tile = map.at(i, j);
|
||||||
|
if tile.graphic.is_visible() {
|
||||||
|
self.draw(&tile)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw characters
|
||||||
|
for c in inner.scene.characters() {
|
||||||
|
if true {
|
||||||
|
self.draw(c)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -185,12 +200,6 @@ impl Engine {
|
|||||||
|
|
||||||
/// The data contained in our engine.
|
/// The data contained in our engine.
|
||||||
pub struct InnerEngine {
|
pub struct InnerEngine {
|
||||||
/// The x position of the drawing.
|
|
||||||
pub x: f64,
|
|
||||||
|
|
||||||
/// The y position of the drawing.
|
|
||||||
pub y: f64,
|
|
||||||
|
|
||||||
/// The scene of the engine.
|
/// The scene of the engine.
|
||||||
pub scene: Scene,
|
pub scene: Scene,
|
||||||
|
|
||||||
@ -204,13 +213,22 @@ 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, scene: Scene) -> Result<InnerEngine> {
|
||||||
log!("sup");
|
|
||||||
Ok(InnerEngine {
|
Ok(InnerEngine {
|
||||||
x: 0.0,
|
|
||||||
y: 0.0,
|
|
||||||
scene,
|
scene,
|
||||||
keyboard: Keyboard::new(document)?,
|
keyboard: Keyboard::new(document)?,
|
||||||
textures: TextureManager::new()?,
|
textures: TextureManager::new()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Our custom drawable trait.
|
||||||
|
pub trait Drawable {
|
||||||
|
/// Returns the texture of the drawable.
|
||||||
|
fn texture(&self) -> Texture;
|
||||||
|
|
||||||
|
/// Returns the coordinates to use on the texture.
|
||||||
|
fn texture_rect(&self) -> Bbox;
|
||||||
|
|
||||||
|
/// Returns the position on which the drawable should be drawn.
|
||||||
|
fn position(&self) -> Vector;
|
||||||
|
}
|
||||||
|
@ -108,7 +108,7 @@ impl Scene {
|
|||||||
c.ground_collision();
|
c.ground_collision();
|
||||||
}
|
}
|
||||||
|
|
||||||
c.die();
|
// c.die();
|
||||||
} else {
|
} else {
|
||||||
c.fall_off();
|
c.fall_off();
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ use wasm_bindgen::JsCast;
|
|||||||
|
|
||||||
use web_sys::HtmlImageElement;
|
use web_sys::HtmlImageElement;
|
||||||
|
|
||||||
|
use crate::engine::bbox::Bbox;
|
||||||
use crate::{log, Result};
|
use crate::{log, Result};
|
||||||
|
|
||||||
/// The size of sprites.
|
/// The size of sprites.
|
||||||
@ -68,28 +69,61 @@ impl Image {
|
|||||||
/// Renders the image on a context.
|
/// Renders the image on a context.
|
||||||
pub fn render(
|
pub fn render(
|
||||||
&self,
|
&self,
|
||||||
x: f64,
|
source: Bbox,
|
||||||
y: f64,
|
dest: Bbox,
|
||||||
context: &web_sys::CanvasRenderingContext2d,
|
context: &web_sys::CanvasRenderingContext2d,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
context.draw_image_with_html_image_element(&self.inner.borrow().inner, x, y)?;
|
context.draw_image_with_html_image_element_and_sw_and_sh_and_dx_and_dy_and_dw_and_dh(
|
||||||
|
&self.inner.borrow().inner,
|
||||||
|
source.position.x,
|
||||||
|
source.position.y,
|
||||||
|
source.size.x,
|
||||||
|
source.size.y,
|
||||||
|
dest.position.x,
|
||||||
|
dest.position.y,
|
||||||
|
dest.size.x,
|
||||||
|
dest.size.y,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The list of all our textures.
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub enum Texture {
|
||||||
|
/// The main character sprite.
|
||||||
|
Rusty,
|
||||||
|
|
||||||
|
/// The sprites from the overworld.
|
||||||
|
Overworld,
|
||||||
|
}
|
||||||
|
|
||||||
/// Our texture manager.
|
/// Our texture manager.
|
||||||
///
|
///
|
||||||
/// It holds all our resources.
|
/// It holds all our resources.
|
||||||
pub struct TextureManager {
|
pub struct TextureManager {
|
||||||
/// The main character sprite.
|
/// The main character sprite.
|
||||||
pub rusty: Image,
|
pub rusty: Image,
|
||||||
|
|
||||||
|
/// The sprites from the overworld.
|
||||||
|
pub overworld: Image,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureManager {
|
impl TextureManager {
|
||||||
/// Creates and start the loading of all our textures.
|
/// Creates and start the loading of all our textures.
|
||||||
pub fn new() -> Result<TextureManager> {
|
pub fn new() -> Result<TextureManager> {
|
||||||
let rusty = Image::new("static/textures/rusty.png")?;
|
Ok(TextureManager {
|
||||||
Ok(TextureManager { rusty })
|
rusty: Image::new("static/textures/rusty.png")?,
|
||||||
|
overworld: Image::new("static/textures/overworld.png")?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the image corresponding to a certain texture.
|
||||||
|
pub fn get(&self, texture: Texture) -> &Image {
|
||||||
|
match texture {
|
||||||
|
Texture::Rusty => &self.rusty,
|
||||||
|
Texture::Overworld => &self.overworld,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! A module for basic maths.
|
//! A module for basic maths.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
|
||||||
|
|
||||||
/// A 2 dimensional vector.
|
/// A 2 dimensional vector.
|
||||||
@ -79,3 +80,9 @@ impl Mul<Vector> for f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Vector {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(fmt, "({}, {})", self.x, self.y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BIN
static/textures/overworld.png
Normal file
BIN
static/textures/overworld.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
Loading…
x
Reference in New Issue
Block a user