diff options
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 25 | ||||
-rw-r--r-- | src/map.rs | 75 | ||||
-rw-r--r-- | src/tileset.rs | 59 |
4 files changed, 96 insertions, 64 deletions
@@ -1,2 +1,3 @@ pub mod constants; pub mod map; +pub mod tileset; diff --git a/src/main.rs b/src/main.rs index bb85c0a..953d326 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,8 @@ use ggez::graphics::{self, spritebatch::SpriteBatch, DrawParam, FilterMode, Imag use ggez::nalgebra::{Point2, Vector2}; use ggez::{Context, ContextBuilder, GameResult}; use pax_romana::constants; -use pax_romana::map::{Map, Tileset}; +use pax_romana::map::Map; +use pax_romana::tileset::Tileset; struct State { map: Map, @@ -34,17 +35,19 @@ impl EventHandler for State { fn draw(&mut self, context: &mut Context) -> GameResult { graphics::clear(context, graphics::BLACK); - for x in 0..self.map.width { - for y in 0..self.map.height { - let draw_param = DrawParam::default() - .src(self.tileset.tiles[self.map.data[x + (y * self.map.height)]]) - .dest(Point2::new( - self.tileset.tile_width * constants::TILE_SCALE * x as f32, - self.tileset.tile_height * constants::TILE_SCALE * y as f32, - )) - .scale(Vector2::new(constants::TILE_SCALE, constants::TILE_SCALE)); + for layer in self.map.layers.iter() { + for x in 0..self.map.width { + for y in 0..self.map.height { + let draw_param = DrawParam::default() + .src(self.tileset.tiles[layer.data[x + (y * self.map.height)]]) + .dest(Point2::new( + self.tileset.tile_width * constants::TILE_SCALE * x as f32, + self.tileset.tile_height * constants::TILE_SCALE * y as f32, + )) + .scale(Vector2::new(constants::TILE_SCALE, constants::TILE_SCALE)); - self.spritebatch.add(draw_param); + self.spritebatch.add(draw_param); + } } } @@ -1,19 +1,36 @@ use ggez::filesystem::File; -use ggez::graphics::Rect; use std::io::BufReader; use xml::reader::{EventReader, XmlEvent}; +pub struct Layer { + pub id: usize, + pub data: Vec<usize>, +} + +impl Layer { + pub fn new(text: String, id: usize) -> Layer { + Layer { + id, + data: text + .replace("\n", "") + .split(',') + .map(|s| s.parse().unwrap()) + .collect(), + } + } +} + pub struct Map { pub width: usize, pub height: usize, - pub data: Vec<usize>, + pub layers: Vec<Layer>, } impl Map { pub fn new(file: File) -> Map { let mut width = None; let mut height = None; - let mut data: Option<Vec<usize>> = None; + let mut layers = Vec::new(); for e in EventReader::new(BufReader::new(file)) { if let Ok(XmlEvent::StartElement { @@ -30,63 +47,15 @@ impl Map { } } } else if let Ok(XmlEvent::Characters(text)) = e { - data = Some( - text.replace("\n", "") - .split(',') - .map(|s| s.parse().unwrap()) - .collect(), - ); + layers.push(Layer::new(text, layers.len() + 1)); } } Map { - data: data.unwrap(), + layers, width: width.unwrap(), height: height.unwrap(), } } } -pub struct Tileset { - pub tiles: Vec<Rect>, - pub tile_width: f32, - pub tile_height: f32, -} - -impl Tileset { - pub fn new(file: File) -> Tileset { - let mut tile_width = None; - let mut tile_height = None; - let mut columns = None; - - for e in EventReader::new(BufReader::new(file)) { - if let Ok(XmlEvent::StartElement { attributes, .. }) = e { - for attribute in attributes { - match attribute.name.local_name.as_str() { - "columns" => columns = Some(attribute.value.parse::<usize>().unwrap()), - "tilewidth" => tile_width = Some(attribute.value.parse::<f32>().unwrap()), - "tileheight" => tile_height = Some(attribute.value.parse::<f32>().unwrap()), - _ => (), - } - } - } - } - - let columns = columns.unwrap(); - - let mut tiles = Vec::new(); - tiles.push(Rect::zero()); - - for c in 0..columns { - let x = c as f32 / columns as f32; - let w = (c as f32 + 1.0) / columns as f32; - tiles.push(Rect::new(x, 0.0, w, 1.0)); - } - - Tileset { - tiles, - tile_height: tile_height.unwrap(), - tile_width: tile_width.unwrap(), - } - } -} diff --git a/src/tileset.rs b/src/tileset.rs new file mode 100644 index 0000000..21e31d1 --- /dev/null +++ b/src/tileset.rs @@ -0,0 +1,59 @@ +use ggez::filesystem::File; +use ggez::graphics::Rect; +use std::io::BufReader; +use xml::reader::{EventReader, XmlEvent}; + +pub struct Tileset { + pub tiles: Vec<Rect>, + pub tile_width: f32, + pub tile_height: f32, +} + +impl Tileset { + pub fn new(file: File) -> Tileset { + let mut tile_width = None; + let mut tile_height = None; + let mut columns = None; + let mut height = None; + + for e in EventReader::new(BufReader::new(file)) { + if let Ok(XmlEvent::StartElement { attributes, .. }) = e { + for attribute in attributes { + match attribute.name.local_name.as_str() { + "columns" => columns = Some(attribute.value.parse::<usize>().unwrap()), + "tilewidth" => tile_width = Some(attribute.value.parse::<f32>().unwrap()), + "tileheight" => tile_height = Some(attribute.value.parse::<f32>().unwrap()), + "height" => height = Some(attribute.value.parse::<usize>().unwrap()), + _ => (), + } + } + } + } + + let columns = columns.unwrap(); + let tile_height = tile_height.unwrap(); + let tile_width = tile_width.unwrap(); + let height = height.unwrap(); + + let rows = height / (tile_height as usize); + + let mut tiles = Vec::new(); + tiles.push(Rect::zero()); + + for r in 0..rows { + for c in 0..columns { + let x = c as f32 / columns as f32; + let y = r as f32 / rows as f32; + let w = (c as f32 + 1.0) / columns as f32; + let h = (r as f32 + 1.0) / rows as f32; + tiles.push(Rect::new(x, y, w, h)); + } + } + + Tileset { + tiles, + tile_height, + tile_width, + } + } +} |