summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map.rs12
-rw-r--r--src/tile.rs12
-rw-r--r--src/tileset.rs38
-rw-r--r--src/xmlelements.rs112
4 files changed, 155 insertions, 19 deletions
diff --git a/src/map.rs b/src/map.rs
index 38fb326..dc50116 100644
--- a/src/map.rs
+++ b/src/map.rs
@@ -17,8 +17,16 @@ impl Map {
pub fn new(file: File, tileset: &Tileset) -> Map {
let elements = XMLElements::new(file);
- let width = elements.get_element_attribute("map", "width").unwrap();
- let height = elements.get_element_attribute("map", "height").unwrap();
+ let width = elements
+ .get_element_attribute("map", "width")
+ .unwrap()
+ .parse()
+ .unwrap();
+ let height = elements
+ .get_element_attribute("map", "height")
+ .unwrap()
+ .parse()
+ .unwrap();
let layers = elements
.events
diff --git a/src/tile.rs b/src/tile.rs
index 5667b92..dc9987c 100644
--- a/src/tile.rs
+++ b/src/tile.rs
@@ -27,15 +27,15 @@ impl Tile {
};
let (source, rotation) = match (flip_d, flip_h, flip_v) {
- (true, true, true) => (Tile::flip(tileset.tiles[id]), convert_angle_to_rad(90.0)),
- (true, true, false) => (tileset.tiles[id], convert_angle_to_rad(90.0)),
- (true, false, true) => (tileset.tiles[id], convert_angle_to_rad(270.0)),
+ (true, true, true) => (Tile::flip(tileset.get(id)), convert_angle_to_rad(90.0)),
+ (true, true, false) => (tileset.get(id), convert_angle_to_rad(90.0)),
+ (true, false, true) => (tileset.get(id), convert_angle_to_rad(270.0)),
//(true, false, false) => (),
- (false, true, true) => (tileset.tiles[id], convert_angle_to_rad(180.0)),
- (false, true, false) => (Tile::flip(tileset.tiles[id]), 0.0),
+ (false, true, true) => (tileset.get(id), convert_angle_to_rad(180.0)),
+ (false, true, false) => (Tile::flip(tileset.get(id)), 0.0),
//(false, false, true) => (),
//(false, false, false) => (),
- _ => (tileset.tiles[id], 0.0),
+ _ => (tileset.get(id), 0.0),
};
let x = i as f32 % width as f32;
diff --git a/src/tileset.rs b/src/tileset.rs
index ae65097..a5c00af 100644
--- a/src/tileset.rs
+++ b/src/tileset.rs
@@ -1,37 +1,61 @@
use ggez::filesystem::File;
use ggez::graphics::Rect;
+use std::collections::HashMap;
use crate::constants;
-use crate::xmlelements::XMLElements;
+use crate::xmlelements::{XMLElements, Property};
pub struct Tileset {
- pub tiles: Vec<Rect>,
+ tiles: HashMap<usize, Rect>,
+ properties: HashMap<usize, Property>,
}
impl Tileset {
pub fn new(file: File) -> Tileset {
let elements = XMLElements::new(file);
- let height = elements.get_element_attribute("image", "height").unwrap();
+ let height = elements
+ .get_element_attribute("image", "height")
+ .unwrap()
+ .parse::<usize>()
+ .unwrap();
let columns = elements
.get_element_attribute("tileset", "columns")
+ .unwrap()
+ .parse::<usize>()
.unwrap();
let rows = height / (constants::TILE_HEIGHT as usize);
- let mut tiles = Vec::new();
- tiles.push(Rect::zero());
+ let mut tiles = HashMap::new();
+ tiles.insert(0, Rect::zero());
let w = 1.0 / columns as f32;
let h = 1.0 / rows as f32;
+ let mut key = 1;
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;
- tiles.push(Rect::new(x, y, w, h));
+ tiles.insert(key, Rect::new(x, y, w, h));
+ key += 1;
}
}
- Tileset { tiles }
+ let mut properties = HashMap::new();
+
+ for tile_element in elements.get_elements("tile") {
+ let tile_id = XMLElements::get_attribute(&tile_element, "id").unwrap().parse().unwrap();
+
+ let property_elements = elements.get_children(&tile_element, "property");
+
+ properties.insert(tile_id, Property::new(property_elements));
+ }
+
+ Tileset { tiles, properties }
+ }
+
+ pub fn get(&self, id: usize) -> Rect {
+ *self.tiles.get(&id).unwrap()
}
}
diff --git a/src/xmlelements.rs b/src/xmlelements.rs
index 86d7c77..bf9a213 100644
--- a/src/xmlelements.rs
+++ b/src/xmlelements.rs
@@ -2,9 +2,32 @@ use ggez::filesystem::File;
use std::io::BufReader;
use xml::reader::{
EventReader,
- XmlEvent::{self, StartElement},
+ XmlEvent::{self, EndElement, StartElement},
};
+#[derive(Debug)]
+pub struct Property {
+ entity: String,
+ keyframe: usize,
+ delay: usize,
+}
+
+impl Property {
+ pub fn new(property_elements: Vec<XmlEvent>) -> Property {
+
+ let entity = XMLElements::get_attribute_value(&property_elements, "entity").unwrap().parse().unwrap();
+ let keyframe =
+ XMLElements::get_attribute_value(&property_elements, "keyframe").unwrap().parse().unwrap();
+ let delay = XMLElements::get_attribute_value(&property_elements, "delay").unwrap().parse().unwrap();
+
+ Property {
+ entity,
+ keyframe,
+ delay,
+ }
+ }
+}
+
pub struct XMLElements {
pub events: Vec<XmlEvent>,
}
@@ -33,20 +56,101 @@ impl XMLElements {
.unwrap()
}
+ pub fn get_children(&self, element: &XmlEvent, children_name: &str) -> Vec<XmlEvent> {
+ let start_index = self.events.iter().position(|e| e == element).unwrap();
+
+ let element_name = if let StartElement { name, .. } = element {
+ &name.local_name
+ } else {
+ ""
+ };
+
+ let end_index = self.events[start_index..]
+ .iter()
+ .position(|e| {
+ if let EndElement { name } = e {
+ element_name == name.local_name
+ } else {
+ false
+ }
+ })
+ .unwrap()
+ + start_index;
+
+ self.events[start_index..end_index]
+ .iter()
+ .cloned()
+ .filter(|e| {
+ if let StartElement { name, .. } = e {
+ name.local_name == children_name
+ } else {
+ false
+ }
+ })
+ .collect()
+ }
+
+ pub fn get_elements(&self, element_name: &str) -> Vec<XmlEvent> {
+ self.events
+ .clone()
+ .into_iter()
+ .filter(|e| {
+ if let StartElement { name, .. } = e {
+ name.local_name == element_name
+ } else {
+ false
+ }
+ })
+ .collect()
+ }
+
pub fn get_element_attribute(
&self,
element_name: &str,
attribute_name: &str,
- ) -> Result<usize, ()> {
+ ) -> Result<String, ()> {
let element = self.get_element(element_name);
+ XMLElements::get_attribute(&element, attribute_name)
+ }
+
+ pub fn get_attribute(element: &XmlEvent, attribute_name: &str) -> Result<String, ()> {
if let StartElement { attributes, .. } = element {
Ok(attributes
.iter()
.find(|a| a.name.local_name == attribute_name)
.unwrap()
.value
- .parse()
- .unwrap())
+ .clone())
+ } else {
+ Err(())
+ }
+ }
+
+ pub fn get_attribute_value(
+ elements: &Vec<XmlEvent>,
+ attribute_name: &str,
+ ) -> Result<String, ()> {
+ let element = elements
+ .iter()
+ .find(|e| {
+ if let StartElement { attributes, .. } = e {
+ attributes
+ .iter()
+ .find(|a| a.value == attribute_name)
+ .is_some()
+ } else {
+ false
+ }
+ })
+ .unwrap();
+
+ if let StartElement { attributes, .. } = element {
+ Ok(attributes
+ .iter()
+ .find(|a| a.name.local_name == "value")
+ .unwrap()
+ .value
+ .clone())
} else {
Err(())
}