Start to do collisions
This commit is contained in:
		
							parent
							
								
									3e8ae2d496
								
							
						
					
					
						commit
						6b098f6cde
					
				
							
								
								
									
										
											BIN
										
									
								
								assets/textures/overworld-raw.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/textures/overworld-raw.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 56 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/textures/overworld.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/textures/overworld.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.4 KiB | 
							
								
								
									
										128
									
								
								src/engine/map/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/engine/map/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | ||||
| use sfml::system::Vector2; | ||||
| use sfml::graphics::IntRect; | ||||
| 
 | ||||
| use engine::texture::Texture; | ||||
| use engine::renderer::Drawable; | ||||
| use engine::math::Matrix; | ||||
| 
 | ||||
| /// This struct represents the different type of tiles that can exist in our maps.
 | ||||
| #[derive(Copy, Clone, PartialEq, Eq)] | ||||
| pub enum Tile { | ||||
|     /// A tile that contains nothing.
 | ||||
|     Empty, | ||||
| 
 | ||||
|     /// A solid tile.
 | ||||
|     Solid | ||||
| } | ||||
| 
 | ||||
| impl Tile { | ||||
|     /// Returns the offset to the tile in the texture.
 | ||||
|     pub fn offset(&self) -> (i32, i32) { | ||||
|         match *self { | ||||
|             Tile::Empty => (0, 0), | ||||
|             Tile::Solid => (16, 0), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// A tile and its position.
 | ||||
| pub struct PositionedTile { | ||||
|     /// The tile of the positioned tile.
 | ||||
|     pub tile: Tile, | ||||
| 
 | ||||
|     /// The position of the positioned tile.
 | ||||
|     pub position: (f32, f32), | ||||
| } | ||||
| 
 | ||||
| impl Drawable for PositionedTile { | ||||
|     fn texture(&self) -> Texture { | ||||
|         Texture::Overworld | ||||
|     } | ||||
| 
 | ||||
|     fn texture_rect(&self) -> IntRect { | ||||
|         let offset = self.tile.offset(); | ||||
|         IntRect::new(offset.0, offset.1, 16, 16) | ||||
|     } | ||||
| 
 | ||||
|     fn position(&self) -> Vector2<f32> { | ||||
|         self.position.into() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// The map represents the tiles contained in a level.
 | ||||
| pub struct Map { | ||||
| 
 | ||||
|     /// The tiles contained in the level.
 | ||||
|     tiles: Matrix<Tile>, | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| impl Map { | ||||
| 
 | ||||
|     /// Creates a map full of nothing, with a ground at the bottom.
 | ||||
|     pub fn new(rows: usize, cols: usize) -> Map { | ||||
| 
 | ||||
|         let mut tiles = Matrix::from_size(rows, cols, Tile::Empty); | ||||
|         let rows = tiles.rows(); | ||||
| 
 | ||||
|         for i in 0 .. tiles.cols() { | ||||
|             tiles[(rows - 1, i)] = Tile::Solid; | ||||
|         } | ||||
| 
 | ||||
|         tiles[(25, 12)] = Tile::Solid; | ||||
|         tiles[(25, 13)] = Tile::Solid; | ||||
|         tiles[(25, 14)] = Tile::Solid; | ||||
|         tiles[(25, 15)] = Tile::Solid; | ||||
| 
 | ||||
|         Map { | ||||
|             tiles: tiles, | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// Returns an iterator to the positioned tiles.
 | ||||
|     pub fn at(&self, row: usize, col: usize) -> PositionedTile { | ||||
|         PositionedTile { | ||||
|             tile: self.tiles[(row, col)], | ||||
|             position: (col as f32 * 16.0, row as f32 * 16.0), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the number of rows of the map.
 | ||||
|     pub fn rows(&self) -> usize { | ||||
|         self.tiles.rows() | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the number of columns of the map.
 | ||||
|     pub fn cols(&self) -> usize { | ||||
|         self.tiles.cols() | ||||
|     } | ||||
| 
 | ||||
|     /// Checks whether the vector (old, new) collides with an element of the map.
 | ||||
|     ///
 | ||||
|     /// Returns the height of the collision if any.
 | ||||
|     pub fn collides(&self, old: Vector2<f32>, new: Vector2<f32>) -> Option<f32> { | ||||
| 
 | ||||
|         let height = new.y - old.y; | ||||
|         let mut y = (old.y / 16.0).ceil() * 16.0; | ||||
| 
 | ||||
|         while y < new.y { | ||||
| 
 | ||||
|             let current_height = y - old.y; | ||||
|             let x = old.x + (new.x - old.x) * current_height / height; | ||||
| 
 | ||||
|             // Find tile on x, y
 | ||||
|             let row = (y / 16.0) as usize + 2; | ||||
|             let col = (x / 16.0) as usize + 1; | ||||
| 
 | ||||
|             if let Some(Tile::Solid) = self.tiles.get((row, col)) { | ||||
|                 return Some(y); | ||||
|             } | ||||
| 
 | ||||
|             y += 16.0; | ||||
|         } | ||||
| 
 | ||||
|         None | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -45,7 +45,7 @@ impl<T> Matrix<T> where T: Clone { | ||||
| impl<T> Matrix<T> { | ||||
|     /// Converts an a pair corresponding to the row and columns into an integer.
 | ||||
|     pub fn to_usize(&self, (row, col): (usize, usize)) -> usize { | ||||
|         self.cols * col + row | ||||
|         self.rows * col + row | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the number of rows.
 | ||||
| @ -57,6 +57,15 @@ impl<T> Matrix<T> { | ||||
|     pub fn cols(&self) -> usize { | ||||
|         self.cols | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the tile if any, none otherwise.
 | ||||
|     pub fn get(&self, (row, col): (usize, usize)) -> Option<&T> { | ||||
|         if row < self.rows && col < self.cols { | ||||
|             Some(&self[(row, col)]) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T> Index<(usize, usize)> for Matrix<T> { | ||||
|  | ||||
| @ -19,3 +19,6 @@ pub mod renderer; | ||||
| 
 | ||||
| /// This module contains everything related to physics.
 | ||||
| pub mod physics; | ||||
| 
 | ||||
| /// This module contains the map structure.
 | ||||
| pub mod map; | ||||
|  | ||||
| @ -93,6 +93,16 @@ impl Renderer { | ||||
| 
 | ||||
|     /// Draws a scene on the window.
 | ||||
|     pub fn draw_scene(&mut self, scene: &Scene) { | ||||
|         let map = scene.map(); | ||||
|         let rows = map.rows(); | ||||
|         let cols = map.cols(); | ||||
| 
 | ||||
|         for i in 0 .. rows { | ||||
|             for j in 0 .. cols { | ||||
|                 self.draw(&map.at(i, j)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for c in scene.characters() { | ||||
|             self.draw(c); | ||||
|         } | ||||
|  | ||||
| @ -3,6 +3,7 @@ use std::time::Duration; | ||||
| use sfml::window::Event; | ||||
| 
 | ||||
| use engine::character::Character; | ||||
| use engine::map::Map; | ||||
| 
 | ||||
| /// Contains everything needed to play.
 | ||||
| pub struct Scene { | ||||
| @ -10,6 +11,9 @@ pub struct Scene { | ||||
|     /// The characters contained in the scene.
 | ||||
|     characters: Vec<Character>, | ||||
| 
 | ||||
|     /// The map of the scene.
 | ||||
|     map: Map, | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| impl Scene { | ||||
| @ -18,6 +22,7 @@ impl Scene { | ||||
|     pub fn new() -> Scene { | ||||
|         Scene { | ||||
|             characters: vec![], | ||||
|             map: Map::new(30, 30), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -30,10 +35,12 @@ impl Scene { | ||||
|     pub fn update(&mut self, duration: &Duration) { | ||||
| 
 | ||||
|         for c in &mut self.characters { | ||||
|             let old = c.position; | ||||
|             c.update(duration); | ||||
| 
 | ||||
|             if c.position.y > 500.0 { | ||||
|                 c.position.y = 500.0; | ||||
| 
 | ||||
|             if let Some(height) = self.map.collides(old, c.position) { | ||||
|                 c.position.y = height; | ||||
|                 c.speed.y = 0.0; | ||||
|                 c.ground_collision(); | ||||
|             } | ||||
| @ -52,6 +59,11 @@ impl Scene { | ||||
|         &self.characters | ||||
|     } | ||||
| 
 | ||||
|     /// Returns a reference to the map.
 | ||||
|     pub fn map(&self) -> &Map { | ||||
|         &self.map | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /// Trait that needs to be implemented for everything that can be updatable.
 | ||||
|  | ||||
| @ -58,6 +58,7 @@ macro_rules! make_textures { | ||||
| 
 | ||||
| make_textures!( | ||||
|     Mario, mario, make_mario_texture, "../../../assets/textures/mario.png", | ||||
|     Overworld, overworld, make_overworld_texture, "../../../assets/textures/overworld.png", | ||||
| ); | ||||
| 
 | ||||
| impl TextureManager { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user