diff options
-rw-r--r-- | src/entity.rs | 45 | ||||
-rw-r--r-- | src/layer.rs | 5 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/map.rs | 37 | ||||
-rw-r--r-- | src/state.rs | 9 | ||||
-rw-r--r-- | src/tile.rs | 5 | ||||
-rw-r--r-- | src/tileset.rs | 9 |
7 files changed, 103 insertions, 8 deletions
diff --git a/src/entity.rs b/src/entity.rs new file mode 100644 index 0000000..bd29a84 --- /dev/null +++ b/src/entity.rs @@ -0,0 +1,45 @@ +use ggez::graphics::{spritebatch::SpriteBatch, DrawParam, Rect}; +use ggez::nalgebra::{Point2, Vector2}; + +use crate::constants; +use crate::map::Map; +use crate::tileset::Tileset; + +#[derive(Clone)] +pub struct Entity { + position: Point2<f32>, + source: Rect, + spawn: Point2<f32>, +} + +impl Entity { + pub fn new(tileset: &Tileset, spawn: Point2<f32>) -> Entity { + let mut source = tileset.get_tile_by_entity_keyframe("player-top", 0); + source.h += tileset.get_tile_by_entity_keyframe("player-bottom", 0).h; + + Entity { + position: spawn, + source, + spawn, + } + } + + pub fn draw(&self, spritebatch: &mut SpriteBatch) { + let draw_param = DrawParam::default() + .src(self.source) + .dest(self.position) + .scale(Vector2::new(constants::TILE_SCALE, constants::TILE_SCALE)); + + spritebatch.add(draw_param); + } + + pub fn build_entities(tileset: &Tileset, map: &Map) -> Vec<Entity> { + let mut entities = Vec::new(); + + for (_name, position) in map.get_spawns() { + entities.push(Entity::new(tileset, position)); + } + + entities + } +} diff --git a/src/layer.rs b/src/layer.rs index c9f32e8..ae645fb 100644 --- a/src/layer.rs +++ b/src/layer.rs @@ -3,10 +3,11 @@ use ggez::graphics::spritebatch::SpriteBatch; use crate::tile::Tile; use crate::tileset::Tileset; +#[derive(Debug, Clone)] pub struct Layer { pub tiles: Vec<Tile>, - pub width: usize, - pub height: usize, + width: usize, + height: usize, } impl Layer { @@ -1,5 +1,6 @@ pub mod camera; pub mod constants; +pub mod entity; pub mod layer; pub mod map; pub mod math; @@ -1,5 +1,6 @@ use ggez::filesystem::File; use ggez::graphics::spritebatch::SpriteBatch; +use ggez::nalgebra::Point2; use xml::reader::XmlEvent::Characters; use crate::constants; @@ -7,10 +8,12 @@ use crate::layer::Layer; use crate::tileset::Tileset; use crate::xmlelements::XMLElements; +#[derive(Clone)] pub struct Map { - pub width: usize, - pub height: usize, - pub layers: Vec<Layer>, + width: usize, + height: usize, + layers: Vec<Layer>, + spawns: Vec<(String, Point2<f32>)>, } impl Map { @@ -28,7 +31,7 @@ impl Map { .parse() .unwrap(); - let layers = elements + let layers: Vec<Layer> = elements .events .iter() .filter_map(|e| { @@ -40,13 +43,35 @@ impl Map { }) .collect(); + let spawns = Map::get_spawn_points(&layers, tileset.get_spawn_tiles()); + Map { layers, width, height, + spawns, } } + fn get_spawn_points( + layers: &[Layer], + spawn_tiles: Vec<(String, usize)>, + ) -> Vec<(String, Point2<f32>)> { + let mut spawn_points = Vec::new(); + + for layer in layers.iter() { + for tile in layer.tiles.iter() { + for spawn_tile in spawn_tiles.iter() { + if spawn_tile.1 == tile.id { + spawn_points.push((spawn_tile.0.clone(), tile.destination)); + } + } + } + } + + spawn_points + } + pub fn draw(&self, spritebatch: &mut SpriteBatch) { for layer in self.layers.iter() { layer.draw(spritebatch); @@ -59,6 +84,10 @@ impl Map { } } + pub fn get_spawns(&self) -> Vec<(String, Point2<f32>)> { + self.spawns.clone() + } + pub fn get_dimensions(&self) -> (f32, f32) { ( (constants::TILE_WIDTH * constants::TILE_SCALE) * self.width as f32, diff --git a/src/state.rs b/src/state.rs index 077917b..1eb5e17 100644 --- a/src/state.rs +++ b/src/state.rs @@ -3,6 +3,7 @@ use ggez::graphics::{self, spritebatch::SpriteBatch, DrawParam, FilterMode, Imag use ggez::{filesystem, Context, GameResult}; use crate::camera::Camera; +use crate::entity::Entity; use crate::map::Map; use crate::player::Player; use crate::tileset::Tileset; @@ -12,6 +13,7 @@ pub struct State { spritebatch: SpriteBatch, camera: Camera, player: Player, + entities: Vec<Entity>, } impl State { @@ -26,10 +28,11 @@ impl State { let map_dimensions = map.get_dimensions(); Ok(State { - map, + map: map.clone(), spritebatch: SpriteBatch::new(image), camera: Camera::new(context, map_dimensions), player: Player::new(&tileset, map_dimensions), + entities: Entity::build_entities(&tileset, &map), }) } } @@ -48,6 +51,10 @@ impl EventHandler for State { self.map.draw(&mut self.spritebatch); self.player.draw(&mut self.spritebatch); + for entity in &self.entities { + entity.draw(&mut self.spritebatch); + } + graphics::draw( context, &self.spritebatch, diff --git a/src/tile.rs b/src/tile.rs index 45b8b3e..1f3c2f7 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -6,11 +6,13 @@ use crate::constants; use crate::math::{convert_angle_to_rad, flip, next_source}; use crate::tileset::Tileset; +#[derive(Clone, Debug)] pub struct Tile { + pub id: usize, source: Rect, animation: Vec<(usize, Rect)>, timer: Instant, - destination: Point2<f32>, + pub destination: Point2<f32>, rotation: f32, } @@ -50,6 +52,7 @@ impl Tile { ); Tile { + id, source, animation: tileset.get_animation(id), timer: Instant::now(), diff --git a/src/tileset.rs b/src/tileset.rs index df7045d..0595186 100644 --- a/src/tileset.rs +++ b/src/tileset.rs @@ -74,6 +74,15 @@ impl Tileset { *self.tiles.get(&id).unwrap() } + pub fn get_spawn_tiles(&self) -> Vec<(String, usize)> { + self.properties + .clone() + .into_iter() + .filter(|p| p.spawn.is_some()) + .map(|p| (p.spawn.unwrap(), p.tile_id)) + .collect() + } + pub fn get_animation(&self, tile_id: usize) -> Vec<(usize, Rect)> { if let Some(property) = self.properties.iter().find(|p| p.tile_id == tile_id) { self.properties |