From a4b5a735aeac215b3098f839d71f5dd7f1347581 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Sat, 6 Oct 2018 10:16:38 +0200 Subject: [PATCH] Preparing for better collision --- src/engine/map/mod.rs | 90 ++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/src/engine/map/mod.rs b/src/engine/map/mod.rs index 351c72c..5a4a564 100644 --- a/src/engine/map/mod.rs +++ b/src/engine/map/mod.rs @@ -5,23 +5,42 @@ 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. +/// This struct represents the different sides from which a collision can occur. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum CollisionTile { - /// A tile that contains nothing. - Empty, +pub struct CollisionTile { + + /// If the character comes from the top, it will collide if this bool is true. + pub from_top: bool, + + /// If the character comes from the left, it will collide if this bool is true. + pub from_left: bool, + + /// If the character comes from the right, it will collide if this bool is true. + pub from_right: bool, + + /// If the character comes from the bottom, it will collide if this bool is true. + pub from_bottom: bool, - /// A solid tile. - Solid } impl CollisionTile { - /// Creates a tile from a u8. - pub fn from_u8(id: u8) -> Option { - match id { - 0 => Some(CollisionTile::Empty), - 1 => Some(CollisionTile::Solid), - _ => None, + /// Creates a collision tile that does not collide. + pub fn empty() -> CollisionTile { + CollisionTile { + from_top: false, + from_left: false, + from_right: false, + from_bottom: false, + } + } + + /// Creates a collision tile that collides from every side. + pub fn full() -> CollisionTile { + CollisionTile { + from_top: true, + from_left: true, + from_right: true, + from_bottom: true, } } } @@ -121,10 +140,10 @@ impl GraphicTile { bottom: Option) -> GraphicTile { GraphicTile::from_neighbours( - top.unwrap_or(CollisionTile::Solid), - left.unwrap_or(CollisionTile::Solid), - right.unwrap_or(CollisionTile::Solid), - bottom.unwrap_or(CollisionTile::Solid), + top.unwrap_or(CollisionTile::full()), + left.unwrap_or(CollisionTile::full()), + right.unwrap_or(CollisionTile::full()), + bottom.unwrap_or(CollisionTile::full()), ) } @@ -142,19 +161,19 @@ impl GraphicTile { for (ref mut tile, ref mut possible) in &mut all { - if tile.is_top() == (top == CollisionTile::Solid) { + if tile.is_top() == (top == CollisionTile::full()) { *possible = false; } - if tile.is_left() == (left == CollisionTile::Solid) { + if tile.is_left() == (left == CollisionTile::full()) { *possible = false; } - if tile.is_right() == (right == CollisionTile::Solid) { + if tile.is_right() == (right == CollisionTile::full()) { *possible = false; } - if tile.is_bottom() == (bottom == CollisionTile::Solid) { + if tile.is_bottom() == (bottom == CollisionTile::full()) { *possible = false; } @@ -230,17 +249,17 @@ 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, CollisionTile::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)] = CollisionTile::Solid; + tiles[(rows - 1, i)] = CollisionTile::full(); } - tiles[(25, 12)] = CollisionTile::Solid; - tiles[(25, 13)] = CollisionTile::Solid; - tiles[(25, 14)] = CollisionTile::Solid; - tiles[(25, 15)] = CollisionTile::Solid; + tiles[(25, 12)] = CollisionTile::full(); + tiles[(25, 13)] = CollisionTile::full(); + tiles[(25, 14)] = CollisionTile::full(); + tiles[(25, 15)] = CollisionTile::full(); Map::from_collision_tiles(tiles) @@ -256,11 +275,16 @@ impl Map { .map(|x| x.parse::().unwrap()) .collect::>(); - let mut tiles = Matrix::from_size(size[0], size[1], CollisionTile::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)] = CollisionTile::from_u8(tile.parse::().unwrap()).unwrap(); + let num = tile.parse::().unwrap(); + match num { + 0 => (), + 1 => tiles[(row, col)] = CollisionTile::full(), + _ => panic!("Expecting 0 or 1 in level files"), + } } } @@ -273,13 +297,13 @@ impl Map { let cols = tiles.cols(); let mut matrix = Matrix::from_size(rows, cols, - (CollisionTile::Empty, GraphicTile::Hidden) + (CollisionTile::empty(), GraphicTile::Hidden) ); for i in 0 .. rows { for j in 0 .. cols { - let graphic = if tiles[(i, j)] == CollisionTile::Solid { + let graphic = if tiles[(i, j)] == CollisionTile::full() { // TODO This is uggly // If there is an overflow, we should give None instead @@ -342,8 +366,10 @@ impl Map { 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, _)) = self.tiles.get((row, col)) { + if tile.from_top { + return Some(y); + } } }