Working on rendering
This commit is contained in:
		
							parent
							
								
									888aed8102
								
							
						
					
					
						commit
						4a08afee59
					
				| @ -1,10 +1,4 @@ | ||||
| 25 50 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 30 50 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| @ -18,8 +12,20 @@ | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
| 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | ||||
|  | ||||
| @ -18,7 +18,7 @@ fn main() { | ||||
|     let game_height = 600; | ||||
| 
 | ||||
|     let mut character = Character::with_controls(Controls::new()); | ||||
|     character.set_position((300.0, 200.0)); | ||||
|     character.set_position((10.0, 0.0)); | ||||
| 
 | ||||
|     let mut scene = Scene::new(); | ||||
|     scene.add(character); | ||||
|  | ||||
| @ -6,8 +6,8 @@ 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 { | ||||
| #[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||||
| pub enum CollisionTile { | ||||
|     /// A tile that contains nothing.
 | ||||
|     Empty, | ||||
| 
 | ||||
| @ -15,29 +15,188 @@ pub enum 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), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| impl CollisionTile { | ||||
|     /// Creates a tile from a u8.
 | ||||
|     pub fn from_u8(id: u8) -> Option<Tile> { | ||||
|     pub fn from_u8(id: u8) -> Option<CollisionTile> { | ||||
|         match id { | ||||
|             0 => Some(Tile::Empty), | ||||
|             1 => Some(Tile::Solid), | ||||
|             0 => Some(CollisionTile::Empty), | ||||
|             1 => Some(CollisionTile::Solid), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// This struct represents a renderable tile linking to its part in the tileset texture.
 | ||||
| #[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||||
| pub enum GraphicTile { | ||||
|     /// There is nothing to draw.
 | ||||
|     Hidden, | ||||
| 
 | ||||
|     /// Top left corner of a solid tile.
 | ||||
|     TopLeft, | ||||
| 
 | ||||
|     /// Top of a solid tile.
 | ||||
|     Top, | ||||
| 
 | ||||
|     /// Top right corner of a solid tile.
 | ||||
|     TopRight, | ||||
| 
 | ||||
|     /// Left of a solid tile.
 | ||||
|     Left, | ||||
| 
 | ||||
|     /// Center of a solid tile.
 | ||||
|     Center, | ||||
| 
 | ||||
|     /// Right of a solid tile.
 | ||||
|     Right, | ||||
| 
 | ||||
|     /// Bottom left corner of a solid tile.
 | ||||
|     BottomLeft, | ||||
| 
 | ||||
|     /// Bottom of a solid tile.
 | ||||
|     Bottom, | ||||
| 
 | ||||
|     /// Bottom right corner of a solid tile.
 | ||||
|     BottomRight, | ||||
| } | ||||
| 
 | ||||
| impl GraphicTile { | ||||
| 
 | ||||
|     /// Checks if a graphic tile has a top border.
 | ||||
|     pub fn is_top(&self) -> bool { | ||||
|         match *self { | ||||
|             GraphicTile::TopLeft | GraphicTile::Top | GraphicTile::TopRight => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Checks if a graphic tile has a left border.
 | ||||
|     pub fn is_left(&self) -> bool { | ||||
|         match *self { | ||||
|             GraphicTile::TopLeft | GraphicTile::Left | GraphicTile::BottomLeft => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Checks if a graphic tile has a right border.
 | ||||
|     pub fn is_right(&self) -> bool { | ||||
|         match *self { | ||||
|             GraphicTile::TopRight | GraphicTile::Right | GraphicTile::BottomRight => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Checks if a graphic tile has a bottom border.
 | ||||
|     pub fn is_bottom(&self) -> bool { | ||||
|         match *self { | ||||
|             GraphicTile::BottomLeft | GraphicTile::Bottom | GraphicTile::BottomRight => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     /// Creates a vec containing all the non hidden graphic tiles.
 | ||||
|     pub fn all() -> Vec<GraphicTile> { | ||||
|         vec![ | ||||
|             GraphicTile::TopLeft, | ||||
|             GraphicTile::Top, | ||||
|             GraphicTile::TopRight, | ||||
|             GraphicTile::Left, | ||||
|             GraphicTile::Center, | ||||
|             GraphicTile::Right, | ||||
|             GraphicTile::BottomLeft, | ||||
|             GraphicTile::Bottom, | ||||
|             GraphicTile::BottomRight, | ||||
|         ] | ||||
|     } | ||||
| 
 | ||||
|     /// Creates the correct graphic tile depending on the neighbours.
 | ||||
|     ///
 | ||||
|     /// A none will be considered solid.
 | ||||
|     pub fn from_neighbour_options( | ||||
|         top: Option<CollisionTile>, | ||||
|         left: Option<CollisionTile>, | ||||
|         right: Option<CollisionTile>, | ||||
|         bottom: Option<CollisionTile>) -> GraphicTile { | ||||
| 
 | ||||
|         GraphicTile::from_neighbours( | ||||
|             top.unwrap_or(CollisionTile::Solid), | ||||
|             left.unwrap_or(CollisionTile::Solid), | ||||
|             right.unwrap_or(CollisionTile::Solid), | ||||
|             bottom.unwrap_or(CollisionTile::Solid), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     /// Creates the correct graphic tile depending on the neighbours.
 | ||||
|     pub fn from_neighbours( | ||||
|         top: CollisionTile, | ||||
|         left: CollisionTile, | ||||
|         right: CollisionTile, | ||||
|         bottom: CollisionTile) -> GraphicTile { | ||||
| 
 | ||||
|         let mut all = GraphicTile::all() | ||||
|             .into_iter() | ||||
|             .map(|x| (x, true)) | ||||
|             .collect::<Vec<_>>(); | ||||
| 
 | ||||
|         for (ref mut tile, ref mut possible) in &mut all { | ||||
| 
 | ||||
|             if tile.is_top() == (top == CollisionTile::Solid) { | ||||
|                 *possible = false; | ||||
|             } | ||||
| 
 | ||||
|             if tile.is_left() == (left == CollisionTile::Solid) { | ||||
|                 *possible = false; | ||||
|             } | ||||
| 
 | ||||
|             if tile.is_right() == (right == CollisionTile::Solid) { | ||||
|                 *possible = false; | ||||
|             } | ||||
| 
 | ||||
|             if tile.is_bottom() == (bottom == CollisionTile::Solid) { | ||||
|                 *possible = false; | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         for (tile, possible) in all { | ||||
|             if possible { | ||||
|                 return tile; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         panic!("Did not find a tile, implementation error"); | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the offset to the corresponding graphic tile in the texture.
 | ||||
|     pub fn offset(&self) -> (i32, i32) { | ||||
|         let vertical = match *self { | ||||
|             GraphicTile::TopLeft | GraphicTile::Top | GraphicTile::TopRight => 0, | ||||
|             GraphicTile::Left | GraphicTile::Center | GraphicTile::Right => 16, | ||||
|             GraphicTile::BottomLeft | GraphicTile::Bottom | GraphicTile::BottomRight => 32, | ||||
|             _ => 0, | ||||
|         }; | ||||
| 
 | ||||
|         let horizontal = match *self { | ||||
|             GraphicTile::TopLeft | GraphicTile::Left | GraphicTile::BottomLeft => 0, | ||||
|             GraphicTile::Top | GraphicTile::Center | GraphicTile::Bottom => 16, | ||||
|             GraphicTile::TopRight | GraphicTile::Right | GraphicTile::BottomRight => 32, | ||||
|             _ => 0, | ||||
|         }; | ||||
| 
 | ||||
|         // (horizontal, vertical)
 | ||||
|         (vertical, horizontal) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// A tile and its position.
 | ||||
| pub struct PositionedTile { | ||||
|     /// The tile of the positioned tile.
 | ||||
|     pub tile: Tile, | ||||
|     /// The graphic representation of the positioned tile.
 | ||||
|     pub graphic: GraphicTile, | ||||
| 
 | ||||
|     /// The collision representation of the positioned tile.
 | ||||
|     pub collision: CollisionTile, | ||||
| 
 | ||||
|     /// The position of the positioned tile.
 | ||||
|     pub position: (f32, f32), | ||||
| @ -49,7 +208,7 @@ impl Drawable for PositionedTile { | ||||
|     } | ||||
| 
 | ||||
|     fn texture_rect(&self) -> IntRect { | ||||
|         let offset = self.tile.offset(); | ||||
|         let offset = self.graphic.offset(); | ||||
|         IntRect::new(offset.0, offset.1, 16, 16) | ||||
|     } | ||||
| 
 | ||||
| @ -62,7 +221,7 @@ impl Drawable for PositionedTile { | ||||
| pub struct Map { | ||||
| 
 | ||||
|     /// The tiles contained in the level.
 | ||||
|     tiles: Matrix<Tile>, | ||||
|     tiles: Matrix<(CollisionTile, GraphicTile)>, | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| @ -71,21 +230,19 @@ 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 mut tiles = Matrix::from_size(rows, cols, CollisionTile::Empty); | ||||
|         let rows = tiles.rows(); | ||||
| 
 | ||||
|         for i in 0 .. tiles.cols() { | ||||
|             tiles[(rows - 1, i)] = Tile::Solid; | ||||
|             tiles[(rows - 1, i)] = CollisionTile::Solid; | ||||
|         } | ||||
| 
 | ||||
|         tiles[(25, 12)] = Tile::Solid; | ||||
|         tiles[(25, 13)] = Tile::Solid; | ||||
|         tiles[(25, 14)] = Tile::Solid; | ||||
|         tiles[(25, 15)] = Tile::Solid; | ||||
|         tiles[(25, 12)] = CollisionTile::Solid; | ||||
|         tiles[(25, 13)] = CollisionTile::Solid; | ||||
|         tiles[(25, 14)] = CollisionTile::Solid; | ||||
|         tiles[(25, 15)] = CollisionTile::Solid; | ||||
| 
 | ||||
|         Map { | ||||
|             tiles: tiles, | ||||
|         } | ||||
|         Map::from_collision_tiles(tiles) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| @ -99,23 +256,59 @@ impl Map { | ||||
|             .map(|x| x.parse::<usize>().unwrap()) | ||||
|             .collect::<Vec<_>>(); | ||||
| 
 | ||||
|         let mut tiles = Matrix::from_size(size[0], size[1], Tile::Empty); | ||||
|         let mut tiles = Matrix::from_size(size[0], size[1], CollisionTile::Empty); | ||||
| 
 | ||||
|         for (row, line) in split.iter().skip(1).enumerate() { | ||||
|             for (col, tile) in line.split_whitespace().enumerate() { | ||||
|                 tiles[(row, col)] = Tile::from_u8(tile.parse::<u8>().unwrap()).unwrap(); | ||||
|                 tiles[(row, col)] = CollisionTile::from_u8(tile.parse::<u8>().unwrap()).unwrap(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Ok(Map { | ||||
|             tiles: tiles, | ||||
|         }) | ||||
|         Ok(Map::from_collision_tiles(tiles)) | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a map from its tiles.
 | ||||
|     pub fn from_collision_tiles(tiles: Matrix<CollisionTile>) -> Map { | ||||
|         let rows = tiles.rows(); | ||||
|         let cols = tiles.cols(); | ||||
| 
 | ||||
|         let mut matrix = Matrix::from_size(rows, cols, | ||||
|             (CollisionTile::Empty, GraphicTile::Hidden) | ||||
|         ); | ||||
| 
 | ||||
|         for i in 0 .. rows { | ||||
|             for j in 0 .. cols { | ||||
| 
 | ||||
|                 let graphic = if tiles[(i, j)] == CollisionTile::Solid { | ||||
| 
 | ||||
|                     // TODO This is uggly
 | ||||
|                     // If there is an overflow, we should give None instead
 | ||||
|                     let (i, j) = (i as isize, j as isize); | ||||
| 
 | ||||
|                     GraphicTile::from_neighbour_options( | ||||
|                         tiles.get(((i  ) as usize, (j-1) as usize)).map(|x| *x), | ||||
|                         tiles.get(((i-1) as usize, (j  ) as usize)).map(|x| *x), | ||||
|                         tiles.get(((i+1) as usize, (j  ) as usize)).map(|x| *x), | ||||
|                         tiles.get(((i  ) as usize, (j+1) as usize)).map(|x| *x), | ||||
|                     ) | ||||
|                 } else { | ||||
|                     GraphicTile::Hidden | ||||
|                 }; | ||||
| 
 | ||||
|                 matrix[(i, j)] = (tiles[(i, j)], graphic); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Map { | ||||
|             tiles: matrix, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Returns an iterator to the positioned tiles.
 | ||||
|     pub fn at(&self, row: usize, col: usize) -> PositionedTile { | ||||
|         PositionedTile { | ||||
|             tile: self.tiles[(row, col)], | ||||
|             collision: self.tiles[(row, col)].0, | ||||
|             graphic: self.tiles[(row, col)].1, | ||||
|             position: (col as f32 * 16.0, row as f32 * 16.0), | ||||
|         } | ||||
|     } | ||||
| @ -144,11 +337,15 @@ impl Map { | ||||
|             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 x > 0.0 && y > 0.0 { | ||||
| 
 | ||||
|                 let row = (y / 16.0) as usize + 2; | ||||
|                 let col = (x / 16.0) as usize + 1; | ||||
| 
 | ||||
|                 if let Some((CollisionTile::Solid, _)) = self.tiles.get((row, col)) { | ||||
|                     return Some(y); | ||||
|                 } | ||||
| 
 | ||||
|             if let Some(Tile::Solid) = self.tiles.get((row, col)) { | ||||
|                 return Some(y); | ||||
|             } | ||||
| 
 | ||||
|             y += 16.0; | ||||
|  | ||||
| @ -19,7 +19,7 @@ use sfml::system::{ | ||||
| 
 | ||||
| use engine::texture::{Texture, TextureManager}; | ||||
| use engine::scene::Scene; | ||||
| use engine::map::Tile; | ||||
| use engine::map::GraphicTile; | ||||
| 
 | ||||
| /// Our custom drawable trait.
 | ||||
| pub trait Drawable { | ||||
| @ -101,7 +101,7 @@ impl Renderer { | ||||
|         for i in 0 .. rows { | ||||
|             for j in 0 .. cols { | ||||
|                 let tile = map.at(i,j); | ||||
|                 if tile.tile != Tile::Empty { | ||||
|                 if tile.graphic != GraphicTile::Hidden { | ||||
|                     self.draw(&tile); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user