From 2308428a5e87ae8de8946c62961ceb6cba9162ec Mon Sep 17 00:00:00 2001 From: Ian Eldred Pudney Date: Thu, 28 Apr 2022 08:29:12 -0500 Subject: [PATCH] Add support for some Tiled features: class properties and object alignment Class properties: These are properties in Tiled that are themselves dicts of additional properties. However, a basic dict cannot be used bec ause class properties also have a "type" that is not a field. Object alignment: Where the positioning and rotation anchor for a tile object is located. --- pytiled_parser/parsers/tmx/properties.py | 9 ++++++++- pytiled_parser/parsers/tmx/tiled_map.py | 5 +++-- pytiled_parser/parsers/tmx/tileset.py | 1 + pytiled_parser/properties.py | 7 ++++++- pytiled_parser/tileset.py | 1 + 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pytiled_parser/parsers/tmx/properties.py b/pytiled_parser/parsers/tmx/properties.py index 173463b..6495076 100644 --- a/pytiled_parser/parsers/tmx/properties.py +++ b/pytiled_parser/parsers/tmx/properties.py @@ -2,7 +2,7 @@ import xml.etree.ElementTree as etree from pathlib import Path from typing import List, Union, cast -from pytiled_parser.properties import Properties, Property +from pytiled_parser.properties import Properties, Property, ClassProperty from pytiled_parser.util import parse_color @@ -14,6 +14,13 @@ def parse(raw_properties: etree.Element) -> Properties: for raw_property in raw_properties.findall("property"): type_ = raw_property.attrib.get("type") + if type_ == "class": + children_nodes = raw_property.find("./properties") + x = ClassProperty( + raw_property.attrib["propertytype"], parse(children_nodes) if children_nodes is not None else {}) + final[raw_property.attrib["name"]] = x + continue + value_ = raw_property.attrib["value"] if type_ == "file": value = Path(value_) diff --git a/pytiled_parser/parsers/tmx/tiled_map.py b/pytiled_parser/parsers/tmx/tiled_map.py index f12c6e2..5b6087c 100644 --- a/pytiled_parser/parsers/tmx/tiled_map.py +++ b/pytiled_parser/parsers/tmx/tiled_map.py @@ -22,7 +22,8 @@ def parse(file: Path) -> TiledMap: TiledMap: A parsed TiledMap. """ with open(file) as map_file: - raw_map = etree.parse(map_file).getroot() + tree = etree.parse(map_file) + raw_map = tree.getroot() parent_dir = file.parent @@ -60,7 +61,7 @@ def parse(file: Path) -> TiledMap: ) layers = [] - for element in raw_map.iter(): + for element in raw_map.getchildren(): if element.tag in ["layer", "objectgroup", "imagelayer", "group"]: layers.append(parse_layer(element, parent_dir)) diff --git a/pytiled_parser/parsers/tmx/tileset.py b/pytiled_parser/parsers/tmx/tileset.py index 712d1cf..55df89a 100644 --- a/pytiled_parser/parsers/tmx/tileset.py +++ b/pytiled_parser/parsers/tmx/tileset.py @@ -121,6 +121,7 @@ def parse( tile_height=int(raw_tileset.attrib["tileheight"]), columns=int(raw_tileset.attrib["columns"]), firstgid=firstgid, + alignment=raw_tileset.attrib.get("objectalignment", "bottomleft"), ) if raw_tileset.attrib.get("version") is not None: diff --git a/pytiled_parser/properties.py b/pytiled_parser/properties.py index f8bc0ac..53350fb 100644 --- a/pytiled_parser/properties.py +++ b/pytiled_parser/properties.py @@ -13,6 +13,11 @@ from typing import Dict, Union from .common_types import Color -Property = Union[float, Path, str, bool, Color] +class ClassProperty(dict): + def __init__(self, propertytype:str, *args, **kwargs): + self.propertytype = propertytype or '' + dict.__init__(self, *args, **kwargs) + +Property = Union[float, Path, str, bool, Color, ClassProperty] Properties = Dict[str, Property] diff --git a/pytiled_parser/tileset.py b/pytiled_parser/tileset.py index de48013..edbb409 100644 --- a/pytiled_parser/tileset.py +++ b/pytiled_parser/tileset.py @@ -150,3 +150,4 @@ class Tileset: properties: Optional[properties_.Properties] = None tiles: Optional[Dict[int, Tile]] = None wang_sets: Optional[List[WangSet]] = None + alignment: Optional[str] = None