Skip to content
Snippets Groups Projects
Commit 6da58bd0 authored by Victor Sergienko's avatar Victor Sergienko
Browse files

There is only one image per Tile OR per Tileset. Added columns field.

parent 9fc0b742
No related branches found
No related tags found
No related merge requests found
......@@ -14,7 +14,7 @@ use crate::{
#[derive(Debug, PartialEq, Clone)]
pub struct Tile {
pub id: u32,
pub images: Vec<Image>,
pub image: Option<Image>,
pub properties: Properties,
pub objectgroup: Option<ObjectGroup>,
pub animation: Option<Vec<Frame>>,
......@@ -39,13 +39,13 @@ impl Tile {
TiledError::MalformedAttributes("tile must have an id with the correct type".to_string())
);
let mut images = Vec::new();
let mut image = Option::None;
let mut properties = HashMap::new();
let mut objectgroup = None;
let mut animation = None;
parse_tag!(parser, "tile", {
"image" => |attrs| {
images.push(Image::new(parser, attrs)?);
image = Some(Image::new(parser, attrs)?);
Ok(())
},
"properties" => |_| {
......@@ -63,7 +63,7 @@ impl Tile {
});
Ok(Tile {
id,
images,
image: image,
properties,
objectgroup,
animation,
......
......@@ -24,9 +24,14 @@ pub struct Tileset {
pub spacing: u32,
pub margin: u32,
pub tilecount: Option<u32>,
/// The Tiled spec says that a tileset can have mutliple images so a `Vec`
/// is used. Usually you will only use one.
pub images: Vec<Image>,
pub columns: u32,
/// A tileset can either:
/// * have a single spritesheet `image` in `tileset` ("regular" tileset);
/// * have zero images in `tileset` and one `image` per `tile` ("image collection" tileset).
///
/// - Source: [tiled issue #2117](https://github.com/mapeditor/tiled/issues/2117)
/// - Source: [`columns` documentation](https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#tileset)
pub image: Option<Image>,
pub tiles: Vec<Tile>,
pub properties: Properties,
}
......@@ -54,12 +59,13 @@ impl Tileset {
parser: &mut EventReader<R>,
attrs: &Vec<OwnedAttribute>,
) -> Result<Tileset, TiledError> {
let ((spacing, margin, tilecount), (first_gid, name, width, height)) = get_attrs!(
let ((spacing, margin, tilecount, columns), (first_gid, name, width, height)) = get_attrs!(
attrs,
optionals: [
("spacing", spacing, |v:String| v.parse().ok()),
("margin", margin, |v:String| v.parse().ok()),
("tilecount", tilecount, |v:String| v.parse().ok()),
("columns", columns, |v:String| v.parse().ok()),
],
required: [
("firstgid", first_gid, |v:String| v.parse().ok()),
......@@ -70,12 +76,12 @@ impl Tileset {
TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string())
);
let mut images = Vec::new();
let mut image = Option::None;
let mut tiles = Vec::new();
let mut properties = HashMap::new();
parse_tag!(parser, "tileset", {
"image" => |attrs| {
images.push(Image::new(parser, attrs)?);
image = Some(Image::new(parser, attrs)?);
Ok(())
},
"properties" => |_| {
......@@ -88,6 +94,15 @@ impl Tileset {
},
});
let columns = match columns {
Some(col) => col,
None => match &image {
None => return Err(TiledError::MalformedAttributes(
"No <image> and no <columns> in <tileset>".to_string())),
Some(image) => image.width as u32 / width,
},
};
Ok(Tileset {
tile_width: width,
tile_height: height,
......@@ -96,7 +111,8 @@ impl Tileset {
first_gid,
name,
tilecount,
images,
columns,
image,
tiles,
properties,
})
......@@ -159,12 +175,13 @@ impl Tileset {
parser: &mut EventReader<R>,
attrs: &Vec<OwnedAttribute>,
) -> Result<Tileset, TiledError> {
let ((spacing, margin, tilecount), (name, width, height)) = get_attrs!(
let ((spacing, margin, tilecount, columns), (name, width, height)) = get_attrs!(
attrs,
optionals: [
("spacing", spacing, |v:String| v.parse().ok()),
("margin", margin, |v:String| v.parse().ok()),
("tilecount", tilecount, |v:String| v.parse().ok()),
("columns", columns, |v:String| v.parse().ok()),
],
required: [
("name", name, |v| Some(v)),
......@@ -174,24 +191,33 @@ impl Tileset {
TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string())
);
let mut images = Vec::new();
let mut image = Option::None;
let mut tiles = Vec::new();
let mut properties = HashMap::new();
parse_tag!(parser, "tileset", {
"image" => |attrs| {
images.push(Image::new(parser, attrs)?);
Ok(())
},
"tile" => |attrs| {
tiles.push(Tile::new(parser, attrs)?);
image = Some(Image::new(parser, attrs)?);
Ok(())
},
"properties" => |_| {
properties = parse_properties(parser)?;
Ok(())
},
"tile" => |attrs| {
tiles.push(Tile::new(parser, attrs)?);
Ok(())
},
});
let columns = match columns {
Some(col) => col,
None => match &image {
None => return Err(TiledError::MalformedAttributes(
"No <image> and no <columns> in <tileset>".to_string())),
Some(image) => image.width as u32 / width,
},
};
Ok(Tileset {
first_gid: first_gid,
name: name,
......@@ -199,8 +225,9 @@ impl Tileset {
tile_height: height,
spacing: spacing.unwrap_or(0),
margin: margin.unwrap_or(0),
tilecount: tilecount,
images: images,
columns,
tilecount,
image,
tiles: tiles,
properties,
})
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment