diff --git a/assets/tiled_image_layers.tmx b/assets/tiled_image_layers.tmx new file mode 100644 index 0000000000000000000000000000000000000000..e7dc7f3fc99c6732b44e214d9208e2111c070a1a --- /dev/null +++ b/assets/tiled_image_layers.tmx @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<map version="1.0" tiledversion="1.0.3" orientation="orthogonal" renderorder="right-down" width="100" height="100" tilewidth="32" tileheight="32" nextobjectid="1"> + <tileset firstgid="1" name="tilesheet" tilewidth="32" tileheight="32" tilecount="84" columns="14"> + <image source="tilesheet.png" width="448" height="192"/> + </tileset> + <imagelayer name="Image Layer 1"/> + <imagelayer name="Image Layer 2"> + <image source="tilesheet.png" width="448" height="192"/> + </imagelayer> +</map> diff --git a/src/lib.rs b/src/lib.rs index 5f91dcb7336b9cb587f02adb25be4b35b7799c62..f48223d7feb984efa721f8230bfc4357f524a606 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,6 +228,7 @@ pub struct Map { pub tile_height: u32, pub tilesets: Vec<Tileset>, pub layers: Vec<Layer>, + pub image_layers: Vec<ImageLayer>, pub object_groups: Vec<ObjectGroup>, pub properties: Properties, pub background_colour: Option<Colour>, @@ -248,6 +249,7 @@ impl Map { let mut tilesets = Vec::new(); let mut layers = Vec::new(); + let mut image_layers = Vec::new(); let mut properties = HashMap::new(); let mut object_groups = Vec::new(); parse_tag!(parser, "map", @@ -259,6 +261,10 @@ impl Map { layers.push(try!(Layer::new(parser, attrs, w))); Ok(()) }, + "imagelayer" => |attrs| { + image_layers.push(try!(ImageLayer::new(parser, attrs))); + Ok(()) + }, "properties" => |_| { properties = try!(parse_properties(parser)); Ok(()) @@ -270,8 +276,11 @@ impl Map { Ok(Map {version: v, orientation: o, width: w, height: h, tile_width: tw, tile_height: th, - tilesets: tilesets, layers: layers, object_groups: object_groups, - properties: properties, + tilesets, + layers, + image_layers, + object_groups, + properties, background_colour: c,}) } @@ -520,6 +529,53 @@ impl Layer { } } +#[derive(Debug, PartialEq, Clone)] +pub struct ImageLayer { + pub name: String, + pub opacity: f32, + pub visible: bool, + pub offset_x: f32, + pub offset_y: f32, + pub image: Option<Image>, + pub properties: Properties +} + +impl ImageLayer { + fn new<R: Read>(parser: &mut EventReader<R>, attrs: Vec<OwnedAttribute>) + -> Result<ImageLayer, TiledError> { + let ((o, v, ox, oy), n) = get_attrs!( + attrs, + optionals: [("opacity", opacity, |v:String| v.parse().ok()), + ("visible", visible, |v:String| v.parse().ok().map(|x:i32| x == 1)), + ("offset_x", offset_x, |v:String| v.parse().ok()), + ("offset_y", offset_y, |v:String| v.parse().ok())], + required: [("name", name, |v| Some(v))], + TiledError::MalformedAttributes("layer must have a name".to_string())); + let mut properties = HashMap::new(); + let mut image: Option<Image> = None; + parse_tag!(parser, "imagelayer", + "image" => |attrs| { + image = Some(Image::new(parser, attrs)?); + Ok(()) + }, + "properties" => |_| { + properties = parse_properties(parser)?; + Ok(()) + }); + Ok(ImageLayer { + name: n, + opacity: o.unwrap_or(1.0), + visible: v.unwrap_or(true), + offset_x: ox.unwrap_or(0.0), + offset_y: oy.unwrap_or(0.0), + image, + properties, + }) + } +} + + + #[derive(Debug, PartialEq, Clone)] pub struct ObjectGroup { pub name: String, diff --git a/tests/lib.rs b/tests/lib.rs index 7da63c8fe49d2418009707e793d083adaf35d7b6..8e2c2c77bd8c94e41dad0700362ac844778062c0 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -38,6 +38,26 @@ fn test_just_tileset() { assert_eq!(r.tilesets[0], t); } +#[test] +fn test_image_layers() { + let r = read_from_file(&Path::new("assets/tiled_image_layers.tmx")).unwrap(); + assert_eq!(r.image_layers.len(), 2); + { + let first = &r.image_layers[0]; + assert_eq!(first.name, "Image Layer 1"); + assert!(first.image.is_none(), "{}'s image should be None", first.name); + } + { + let second = &r.image_layers[1]; + assert_eq!(second.name, "Image Layer 2"); + let image = second.image.as_ref().expect(&format!("{}'s image shouldn't be None", second.name)); + assert_eq!(image.source, "tilesheet.png"); + assert_eq!(image.width, 448); + assert_eq!(image.height, 192); + } +} + + #[test] fn test_tile_property() { let r = read_from_file(&Path::new("assets/tiled_base64.tmx")).unwrap();