Implement automatic tile creation
This commit is contained in:
		
							parent
							
								
									c296c8cd08
								
							
						
					
					
						commit
						7bab06b2b6
					
				
							
								
								
									
										2
									
								
								build.rs
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								build.rs
									
									
									
									
									
								
							| @ -140,7 +140,7 @@ fn main() { | ||||
|     let image_197 = superpose(&image_4, &image_193); | ||||
|     vec.push(&image_197); | ||||
| 
 | ||||
|     let image_199 = rotate90(&image_127); | ||||
|     let image_199 = rotate270(&image_31); | ||||
|     vec.push(&image_199); | ||||
| 
 | ||||
|     let image_209 = rotate90(&image_116); | ||||
|  | ||||
| @ -6,7 +6,8 @@ use sfml::window::mouse::Button; | ||||
| use sfml::graphics::{RectangleShape, RenderTarget, Transformable, Color, Shape}; | ||||
| 
 | ||||
| use rusty::engine::renderer::Renderer; | ||||
| use rusty::engine::map::{GraphicTile, CollisionTile, Map}; | ||||
| use rusty::engine::map::{CollisionTile, Map}; | ||||
| use rusty::engine::texture::SPRITE_SIZE_I32; | ||||
| 
 | ||||
| fn main() { | ||||
|     let _ = App::new("Rusty Editor") | ||||
| @ -17,7 +18,7 @@ fn main() { | ||||
| 
 | ||||
|     let mut running = true; | ||||
| 
 | ||||
|     let mut map = Map::load("./assets/levels/level2.lvl").unwrap(); | ||||
|     let mut map = Map::new(50, 50);//;Map::load("./assets/levels/level2.lvl").unwrap();
 | ||||
| 
 | ||||
|     loop { | ||||
|         let top_panel_size = Vector2::new(renderer.window().size().x as f32, 50.0); | ||||
| @ -39,8 +40,8 @@ fn main() { | ||||
|                     button: Button::Left, x, y, | ||||
|                 } => { | ||||
|                     if x as f32 >= left_panel_size.x && y as f32 >= top_panel_size.y { | ||||
|                         let x = ((x - left_panel_size.x as i32) / 16) as usize; | ||||
|                         let y = ((y - top_panel_size.y as i32) / 16) as usize; | ||||
|                         let x = ((x - left_panel_size.x as i32) / SPRITE_SIZE_I32) as usize; | ||||
|                         let y = ((y - top_panel_size.y as i32) / SPRITE_SIZE_I32) as usize; | ||||
| 
 | ||||
|                         if let Some(tile) = map.tile(y, x) { | ||||
|                             if tile == CollisionTile::empty() { | ||||
| @ -74,7 +75,7 @@ fn main() { | ||||
|         for i in 0 .. map.rows() { | ||||
|             for j in 0 .. map.cols() { | ||||
|                 let tile = map.at(i, j); | ||||
|                 if tile.graphic != GraphicTile::Hidden { | ||||
|                 if tile.graphic.is_visible() { | ||||
|                     renderer.translate_and_draw(&tile, (left_panel_size.x, top_panel_size.y)); | ||||
|                 } | ||||
|             } | ||||
| @ -82,7 +83,10 @@ fn main() { | ||||
| 
 | ||||
|         // Draw the border of the map
 | ||||
|         let mut border = RectangleShape::new(); | ||||
|         border.set_size(((map.cols() * 16) as f32, (map.rows() * 16) as f32)); | ||||
|         border.set_size((( | ||||
|             map.cols() * SPRITE_SIZE_I32 as usize) as f32, | ||||
|             (map.rows() * SPRITE_SIZE_I32 as usize) as f32 | ||||
|         )); | ||||
|         border.set_position((left_panel_size.x, top_panel_size.y)); | ||||
|         border.set_fill_color(&Color::rgba(0, 0, 0, 0)); | ||||
|         border.set_outline_color(&Color::rgb(0, 0, 0)); | ||||
|  | ||||
| @ -12,7 +12,7 @@ use sfml::system::Vector2; | ||||
| use crate::{Error, Result}; | ||||
| use crate::engine::math::{clamp, Matrix}; | ||||
| use crate::engine::renderer::Drawable; | ||||
| use crate::engine::texture::Texture; | ||||
| use crate::engine::texture::{Texture, byte_to_index, SPRITE_SIZE_F32, SPRITE_SIZE_I32}; | ||||
| use crate::engine::character::Damage; | ||||
| 
 | ||||
| /// This enum represents if the collision happens on the X axis or the Y axis.
 | ||||
| @ -86,172 +86,104 @@ impl CollisionTile { | ||||
| 
 | ||||
| /// This struct represents a renderable tile linking to its part in the tileset texture.
 | ||||
| #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] | ||||
| 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, | ||||
| } | ||||
| pub struct GraphicTile(Option<i32>); | ||||
| 
 | ||||
| impl GraphicTile { | ||||
| 
 | ||||
|     /// Returns a graphic tile from a collision tile.
 | ||||
|     ///
 | ||||
|     /// This might be ugly for the moment.
 | ||||
|     pub fn from_collision_tile(collision: CollisionTile) -> GraphicTile { | ||||
|         if collision == CollisionTile::empty() { | ||||
|             GraphicTile::Hidden | ||||
|         } else { | ||||
|             GraphicTile::Center | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// 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_left: Option<CollisionTile>, | ||||
|         top: Option<CollisionTile>, | ||||
|         left: Option<CollisionTile>, | ||||
|         top_right: Option<CollisionTile>, | ||||
|         right: Option<CollisionTile>, | ||||
|         bottom_right: Option<CollisionTile>, | ||||
|         bottom: Option<CollisionTile>, | ||||
|         bottom_left: Option<CollisionTile>, | ||||
|         left: Option<CollisionTile>, | ||||
|     ) -> GraphicTile { | ||||
|         GraphicTile::from_neighbours( | ||||
|             top_left.unwrap_or_else(CollisionTile::full), | ||||
|             top.unwrap_or_else(CollisionTile::full), | ||||
|             left.unwrap_or_else(CollisionTile::full), | ||||
|             top_right.unwrap_or_else(CollisionTile::full), | ||||
|             right.unwrap_or_else(CollisionTile::full), | ||||
|             bottom_right.unwrap_or_else(CollisionTile::full), | ||||
|             bottom.unwrap_or_else(CollisionTile::full), | ||||
|             bottom_left.unwrap_or_else(CollisionTile::full), | ||||
|             left.unwrap_or_else(CollisionTile::full), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     /// Creates the correct graphic tile depending on the neighbours.
 | ||||
|     pub fn from_neighbours( | ||||
|         top_left: CollisionTile, | ||||
|         top: CollisionTile, | ||||
|         left: CollisionTile, | ||||
|         top_right: CollisionTile, | ||||
|         right: CollisionTile, | ||||
|         bottom_right: CollisionTile, | ||||
|         bottom: CollisionTile, | ||||
|         bottom_left: CollisionTile, | ||||
|         left: 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::full()) { | ||||
|                 *possible = false; | ||||
|             } | ||||
|         let mut byte = 0; | ||||
| 
 | ||||
|             if tile.is_left() == (left == CollisionTile::full()) { | ||||
|                 *possible = false; | ||||
|             } | ||||
| 
 | ||||
|             if tile.is_right() == (right == CollisionTile::full()) { | ||||
|                 *possible = false; | ||||
|             } | ||||
| 
 | ||||
|             if tile.is_bottom() == (bottom == CollisionTile::full()) { | ||||
|                 *possible = false; | ||||
|             } | ||||
|         if top_left != CollisionTile::full() || | ||||
|            left     != CollisionTile::full() || | ||||
|            top      != CollisionTile::full() { | ||||
|             byte += 1; | ||||
|         } | ||||
| 
 | ||||
|         for (tile, possible) in all { | ||||
|             if possible { | ||||
|                 return tile; | ||||
|             } | ||||
|         if top != CollisionTile::full() { | ||||
|             byte += 2; | ||||
|         } | ||||
| 
 | ||||
|         GraphicTile::Center | ||||
|         if top_right != CollisionTile::full() || | ||||
|            top       != CollisionTile::full() || | ||||
|            right     != CollisionTile::full() { | ||||
|             byte += 4; | ||||
|         } | ||||
| 
 | ||||
|         if right != CollisionTile::full() { | ||||
|             byte += 8; | ||||
|         } | ||||
| 
 | ||||
|         if bottom_right != CollisionTile::full() || | ||||
|            bottom       != CollisionTile::full() || | ||||
|            right        != CollisionTile::full() { | ||||
|             byte += 16; | ||||
|         } | ||||
| 
 | ||||
|         if bottom != CollisionTile::full() { | ||||
|             byte += 32; | ||||
|         } | ||||
| 
 | ||||
|         if bottom_left != CollisionTile::full() || | ||||
|            bottom      != CollisionTile::full() || | ||||
|            left        != CollisionTile::full() { | ||||
|             byte += 64; | ||||
|         } | ||||
| 
 | ||||
|         if left != CollisionTile::full() { | ||||
|             byte += 128; | ||||
|         } | ||||
| 
 | ||||
|         GraphicTile(Some(byte_to_index(byte))) | ||||
|     } | ||||
| 
 | ||||
|     /// 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, | ||||
|         }; | ||||
|         match self.0 { | ||||
|             None => (0, 0), | ||||
|             Some(v) => (32 * v, 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) | ||||
|     /// Returns true if the tile is visible.
 | ||||
|     pub fn is_visible(&self) -> bool { | ||||
|         self.0.is_some() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -274,7 +206,7 @@ impl Drawable for PositionedTile { | ||||
| 
 | ||||
|     fn texture_rect(&self) -> IntRect { | ||||
|         let offset = self.graphic.offset(); | ||||
|         IntRect::new(offset.0, offset.1, 16, 16) | ||||
|         IntRect::new(offset.0, offset.1, SPRITE_SIZE_I32, SPRITE_SIZE_I32) | ||||
|     } | ||||
| 
 | ||||
|     fn position(&self) -> Vector2<f32> { | ||||
| @ -336,7 +268,7 @@ impl Map { | ||||
|         let cols = tiles.cols(); | ||||
| 
 | ||||
|         let mut matrix = | ||||
|             Matrix::from_size(rows, cols, (CollisionTile::empty(), GraphicTile::Hidden)); | ||||
|             Matrix::from_size(rows, cols, (CollisionTile::empty(), GraphicTile(None))); | ||||
| 
 | ||||
|         for i in 0..rows { | ||||
|             for j in 0..cols { | ||||
| @ -346,13 +278,17 @@ impl Map { | ||||
|                     let (i, j) = (i as isize, j as isize); | ||||
| 
 | ||||
|                     GraphicTile::from_neighbour_options( | ||||
|                         tiles.get(((i) as usize, (j - 1) as usize)).cloned(), | ||||
|                         tiles.get(((i - 1) as usize, (j) as usize)).cloned(), | ||||
|                         tiles.get(((i + 1) as usize, (j) as usize)).cloned(), | ||||
|                         tiles.get(((i) as usize, (j + 1) as usize)).cloned(), | ||||
|                         tiles.get(((i - 1) as usize, (j - 1) as usize)).cloned(), | ||||
|                         tiles.get(((i    ) as usize, (j - 1) as usize)).cloned(), | ||||
|                         tiles.get(((i + 1) as usize, (j - 1) as usize)).cloned(), | ||||
|                         tiles.get(((i + 1) as usize, (j    ) as usize)).cloned(), | ||||
|                         tiles.get(((i + 1) as usize, (j + 1) as usize)).cloned(), | ||||
|                         tiles.get(((i    ) as usize, (j + 1) as usize)).cloned(), | ||||
|                         tiles.get(((i - 1) as usize, (j + 1) as usize)).cloned(), | ||||
|                         tiles.get(((i - 1) as usize, (j    ) as usize)).cloned(), | ||||
|                     ) | ||||
|                 } else { | ||||
|                     GraphicTile::Hidden | ||||
|                     GraphicTile(None) | ||||
|                 }; | ||||
| 
 | ||||
|                 matrix[(i, j)] = (tiles[(i, j)], graphic); | ||||
| @ -365,6 +301,24 @@ impl Map { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the graphic tile corresponding to the collision tiles.
 | ||||
|     pub fn graphic_tile(&self, i: usize, j: usize) -> GraphicTile { | ||||
|         if self.tiles[(i, j)].0 == CollisionTile::full() { | ||||
|             GraphicTile::from_neighbour_options( | ||||
|                 self.tiles.get(((i - 1) as usize, (j - 1) as usize)).map(|x| x.0), | ||||
|                 self.tiles.get(((i - 1) as usize, (j    ) as usize)).map(|x| x.0), | ||||
|                 self.tiles.get(((i - 1) as usize, (j + 1) as usize)).map(|x| x.0), | ||||
|                 self.tiles.get(((i    ) as usize, (j + 1) as usize)).map(|x| x.0), | ||||
|                 self.tiles.get(((i + 1) as usize, (j + 1) as usize)).map(|x| x.0), | ||||
|                 self.tiles.get(((i + 1) as usize, (j    ) as usize)).map(|x| x.0), | ||||
|                 self.tiles.get(((i + 1) as usize, (j - 1) as usize)).map(|x| x.0), | ||||
|                 self.tiles.get(((i    ) as usize, (j - 1) as usize)).map(|x| x.0), | ||||
|             ) | ||||
|         } else { | ||||
|             GraphicTile(None) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Returns a tile of the map.
 | ||||
|     pub fn tile(&self, i: usize, j: usize) -> Option<CollisionTile> { | ||||
|         self.tiles.get((i, j)).map(|x| x.0) | ||||
| @ -372,7 +326,14 @@ impl Map { | ||||
| 
 | ||||
|     /// Changes a tile of the map.
 | ||||
|     pub fn set_tile(&mut self, i: usize, j: usize, tile: CollisionTile) { | ||||
|         self.tiles[(i, j)] = (tile, GraphicTile::from_collision_tile(tile)); | ||||
|         self.tiles[(i, j)] = (tile, GraphicTile(None)); | ||||
|         for i in (i - 1) ..= (i + 1) { | ||||
|             for j in (j - 1) ..= (j + 1) { | ||||
|                 if self.tiles.get((i, j)).is_some() { | ||||
|                     self.tiles[(i, j)].1 = self.graphic_tile(i, j); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Finds a possible entrance.
 | ||||
| @ -390,7 +351,7 @@ impl Map { | ||||
|         PositionedTile { | ||||
|             collision: self.tiles[(row, col)].0, | ||||
|             graphic: self.tiles[(row, col)].1, | ||||
|             position: (col as f32 * 16.0, row as f32 * 16.0), | ||||
|             position: (col as f32 * SPRITE_SIZE_F32, row as f32 * SPRITE_SIZE_F32), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -418,11 +379,11 @@ impl Map { | ||||
|         let cols = self.tiles.cols() - 1; | ||||
|         let rows = self.tiles.rows() - 1; | ||||
| 
 | ||||
|         let min_col = clamp(new.left / 16.0, 0.0, cols as f32) as usize; | ||||
|         let min_row = clamp(new.top / 16.0, 0.0, rows as f32) as usize; | ||||
|         let min_col = clamp(new.left / SPRITE_SIZE_F32, 0.0, cols as f32) as usize; | ||||
|         let min_row = clamp(new.top / SPRITE_SIZE_F32, 0.0, rows as f32) as usize; | ||||
| 
 | ||||
|         let max_col = clamp((new.left + new.width) / 16.0, 0.0, cols as f32) as usize; | ||||
|         let max_row = clamp((new.top + new.height) / 16.0, 0.0, rows as f32) as usize; | ||||
|         let max_col = clamp((new.left + new.width) / SPRITE_SIZE_F32, 0.0, cols as f32) as usize; | ||||
|         let max_row = clamp((new.top + new.height) / SPRITE_SIZE_F32, 0.0, rows as f32) as usize; | ||||
| 
 | ||||
|         let mut collision_x = false; | ||||
|         let mut collision_y = false; | ||||
| @ -430,10 +391,10 @@ impl Map { | ||||
| 
 | ||||
|         for col in min_col..=max_col { | ||||
|             for row in min_row..=max_row { | ||||
|                 let tile_left = col as f32 * 16.0; | ||||
|                 let tile_top = row as f32 * 16.0; | ||||
|                 let tile_left = col as f32 * SPRITE_SIZE_F32; | ||||
|                 let tile_top = row as f32 * SPRITE_SIZE_F32; | ||||
| 
 | ||||
|                 let tile = FloatRect::new(tile_left, tile_top, 16.0, 16.0); | ||||
|                 let tile = FloatRect::new(tile_left, tile_top, SPRITE_SIZE_F32, SPRITE_SIZE_F32); | ||||
| 
 | ||||
|                 if !overlap(new, tile) { | ||||
|                     continue; | ||||
| @ -467,11 +428,11 @@ impl Map { | ||||
| 
 | ||||
|                 // Collisions between left and left wall
 | ||||
|                 if self.tiles[(row, col)].0.from_right | ||||
|                     && old.left >= tile_left + 16.0 | ||||
|                     && new.left <= tile_left + 16.0 | ||||
|                     && old.left >= tile_left + SPRITE_SIZE_F32 | ||||
|                     && new.left <= tile_left + SPRITE_SIZE_F32 | ||||
|                 { | ||||
|                     collision_x = true; | ||||
|                     new.left = tile_left + 16.0; | ||||
|                     new.left = tile_left + SPRITE_SIZE_F32; | ||||
|                 } | ||||
| 
 | ||||
|                 if !overlap(new, tile) { | ||||
| @ -480,11 +441,11 @@ impl Map { | ||||
| 
 | ||||
|                 // Collisions between head and roof
 | ||||
|                 if self.tiles[(row, col)].0.from_bottom | ||||
|                     && old.top >= tile_top + 16.0 | ||||
|                     && new.top <= tile_top + 16.0 | ||||
|                     && old.top >= tile_top + SPRITE_SIZE_F32 | ||||
|                     && new.top <= tile_top + SPRITE_SIZE_F32 | ||||
|                 { | ||||
|                     collision_y = true; | ||||
|                     new.top = tile_top + 16.0; | ||||
|                     new.top = tile_top + SPRITE_SIZE_F32; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -496,14 +457,14 @@ impl Map { | ||||
|         } | ||||
| 
 | ||||
|         // Collision between the player and right border of the level
 | ||||
|         if new.left > cols as f32 * 16.0 { | ||||
|             new.left = cols as f32 * 16.0; | ||||
|         if new.left > cols as f32 * SPRITE_SIZE_F32 { | ||||
|             new.left = cols as f32 * SPRITE_SIZE_F32; | ||||
|             collision_x = true; | ||||
|         } | ||||
| 
 | ||||
|         // Collision between the player and the void
 | ||||
|         if new.top > self.tiles.rows() as f32 * 16.0 { | ||||
|             new.top = self.tiles.rows() as f32 * 16.0; | ||||
|         if new.top > self.tiles.rows() as f32 * SPRITE_SIZE_F32 { | ||||
|             new.top = self.tiles.rows() as f32 * SPRITE_SIZE_F32; | ||||
|             collision_y = true; | ||||
|             damage = Damage::Death; | ||||
|         } | ||||
|  | ||||
| @ -6,7 +6,6 @@ use sfml::window::{Event, Style}; | ||||
| 
 | ||||
| use sfml::system::Vector2; | ||||
| 
 | ||||
| use crate::engine::map::GraphicTile; | ||||
| use crate::engine::scene::Scene; | ||||
| use crate::engine::texture::{Texture, TextureManager}; | ||||
| 
 | ||||
| @ -101,7 +100,7 @@ impl Renderer { | ||||
|         for i in 0..rows { | ||||
|             for j in 0..cols { | ||||
|                 let tile = map.at(i, j); | ||||
|                 if tile.graphic != GraphicTile::Hidden { | ||||
|                 if tile.graphic.is_visible() { | ||||
|                     self.draw(&tile); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -4,6 +4,7 @@ use sfml::graphics::View; | ||||
| use sfml::system::Vector2; | ||||
| use sfml::window::Event; | ||||
| 
 | ||||
| use crate::engine::texture::SPRITE_SIZE_F32; | ||||
| use crate::engine::character::Character; | ||||
| use crate::engine::map::Map; | ||||
| 
 | ||||
| @ -38,8 +39,8 @@ impl Scene { | ||||
|     /// Adds a character to the scene.
 | ||||
|     pub fn add(&mut self, character: Character) { | ||||
|         let mut character = character; | ||||
|         character.position.x = self.map.entrance().1 as f32 * 16.0; | ||||
|         character.position.y = self.map.entrance().0 as f32 * 16.0; | ||||
|         character.position.x = self.map.entrance().1 as f32 * SPRITE_SIZE_F32; | ||||
|         character.position.y = self.map.entrance().0 as f32 * SPRITE_SIZE_F32; | ||||
| 
 | ||||
|         self.characters.push(character); | ||||
|     } | ||||
| @ -69,8 +70,8 @@ impl Scene { | ||||
|             center.y = size.y / 2.0; | ||||
|         } | ||||
| 
 | ||||
|         let right_limit = self.map.cols() as f32 * 16.0; | ||||
|         let bottom_limit = self.map.rows() as f32 * 16.0; | ||||
|         let right_limit = self.map.cols() as f32 * SPRITE_SIZE_F32; | ||||
|         let bottom_limit = self.map.rows() as f32 * SPRITE_SIZE_F32; | ||||
| 
 | ||||
|         if center.x + size.x / 2.0 > right_limit { | ||||
|             center.x = right_limit - size.x / 2.0; | ||||
|  | ||||
| @ -1,11 +1,74 @@ | ||||
| use sfml::graphics::{IntRect, Texture as SfTexture}; | ||||
| 
 | ||||
| /// The number of pixels of a sprite.
 | ||||
| pub const SPRITE_SIZE_I32: i32 = 32; | ||||
| 
 | ||||
| /// The number of pixels of a sprite.
 | ||||
| pub const SPRITE_SIZE_F32: f32 = 32.0; | ||||
| 
 | ||||
| /// Converts the byte with bits corresponding to the neighbours to the offset on the generated
 | ||||
| /// tileset.
 | ||||
| pub fn byte_to_index(byte: u8) -> i32 { | ||||
|     match byte { | ||||
|         0   => 0, | ||||
|         1   => 1, | ||||
|         4   => 2, | ||||
|         5   => 3, | ||||
|         7   => 4, | ||||
|         16  => 5, | ||||
|         17  => 6, | ||||
|         20  => 7, | ||||
|         21  => 8, | ||||
|         23  => 9, | ||||
|         28  => 10, | ||||
|         29  => 11, | ||||
|         31  => 12, | ||||
|         64  => 13, | ||||
|         65  => 14, | ||||
|         68  => 15, | ||||
|         69  => 16, | ||||
|         71  => 17, | ||||
|         80  => 18, | ||||
|         81  => 19, | ||||
|         84  => 20, | ||||
|         85  => 21, | ||||
|         87  => 22, | ||||
|         92  => 23, | ||||
|         93  => 24, | ||||
|         95  => 25, | ||||
|         112 => 26, | ||||
|         113 => 27, | ||||
|         116 => 28, | ||||
|         117 => 29, | ||||
|         119 => 30, | ||||
|         124 => 31, | ||||
|         125 => 32, | ||||
|         127 => 33, | ||||
|         193 => 34, | ||||
|         197 => 35, | ||||
|         199 => 36, | ||||
|         209 => 37, | ||||
|         213 => 38, | ||||
|         215 => 39, | ||||
|         221 => 40, | ||||
|         223 => 41, | ||||
|         241 => 42, | ||||
|         245 => 43, | ||||
|         247 => 44, | ||||
|         253 => 45, | ||||
|         255 => 46, | ||||
|         _ => panic!("Incorrect byte {}", byte), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| macro_rules! make_textures { | ||||
|     ( $( | ||||
|         $enum_name: ident, | ||||
|         $texture_name: ident, | ||||
|         $function_name: ident, | ||||
|         $texture_path: tt, ) | ||||
|         $texture_path: tt, | ||||
|         $width: expr, | ||||
|         $height: expr, ) | ||||
|     *) => { | ||||
| 
 | ||||
|         /// Describes all the textures that will be used in this game.
 | ||||
| @ -39,7 +102,7 @@ macro_rules! make_textures { | ||||
|                 /// Creates the texture.
 | ||||
|                 fn $function_name() -> SfTexture { | ||||
|                     let bytes = include_bytes!($texture_path).to_vec(); | ||||
|                     TextureManager::make_texture_from_bytes(bytes) | ||||
|                     TextureManager::make_texture_from_bytes(bytes, $width, $height) | ||||
|                 } | ||||
|             )* | ||||
| 
 | ||||
| @ -61,16 +124,20 @@ make_textures!( | ||||
|     mario, | ||||
|     make_mario_texture, | ||||
|     "../../../assets/textures/mario.png", | ||||
|     256, | ||||
|     256, | ||||
|     Overworld, | ||||
|     overworld, | ||||
|     make_overworld_texture, | ||||
|     "../../../assets/textures/overworld.png", | ||||
|     "../../../assets/textures-generated/grass.png", | ||||
|     32 * 47, | ||||
|     32, | ||||
| ); | ||||
| 
 | ||||
| impl TextureManager { | ||||
|     /// Creates a textures from an array of bytes.
 | ||||
|     fn make_texture_from_bytes(bytes: Vec<u8>) -> SfTexture { | ||||
|         SfTexture::from_memory(&bytes, &IntRect::new(0, 0, 256, 256)) | ||||
|     fn make_texture_from_bytes(bytes: Vec<u8>, width: i32, height: i32) -> SfTexture { | ||||
|         SfTexture::from_memory(&bytes, &IntRect::new(0, 0, width, height)) | ||||
|             .expect("Failed to create texture") | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user