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) { |  | ||||||
|             dy += 5.0; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         if inner.keyboard.is_key_pressed(Key::ArrowUp) { |     /// 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::ArrowLeft) { |         let source = drawable.texture_rect(); | ||||||
|             dx -= 5.0; |         let mut dest = source.clone(); | ||||||
|         } |         dest.position = drawable.position(); | ||||||
| 
 |  | ||||||
|         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