More 2.0/tmx parsing work. TMX is nearly done

This commit is contained in:
Darren Eberly
2021-12-19 01:43:42 -05:00
parent 65bfc2a498
commit 2395dd32ca
7 changed files with 93 additions and 58 deletions

View File

@@ -38,8 +38,8 @@ class Layer:
"""
name: str
opacity: float
visible: bool
opacity: float = 1
visible: bool = True
coordinates: OrderedPair = OrderedPair(0, 0)
parallax_factor: OrderedPair = OrderedPair(1, 1)

View File

@@ -144,12 +144,19 @@ def _parse_common(raw_layer: etree.Element) -> Layer:
Returns:
Layer: The attributes in common of all layer types
"""
if raw_layer.attrib.get("name") is None:
raw_layer.attrib["name"] = ""
common = Layer(
name=raw_layer.attrib["name"],
opacity=float(raw_layer.attrib["opacity"]),
visible=bool(int(raw_layer.attrib["visible"])),
)
if raw_layer.attrib.get("opacity") is not None:
common.opacity = float(raw_layer.attrib["opacity"])
if raw_layer.attrib.get("visible") is not None:
common.visible = bool(int(raw_layer.attrib["visible"]))
if raw_layer.attrib.get("id") is not None:
common.id = int(raw_layer.attrib["id"])
@@ -159,7 +166,7 @@ def _parse_common(raw_layer: etree.Element) -> Layer:
)
properties_element = raw_layer.find("./properties")
if properties_element:
if properties_element is not None:
common.properties = parse_properties(properties_element)
parallax = [1.0, 1.0]
@@ -187,13 +194,15 @@ def _parse_tile_layer(raw_layer: etree.Element) -> TileLayer:
Returns:
TileLayer: The TileLayer created from raw_layer
"""
common = _parse_common(raw_layer).__dict__
del common["size"]
tile_layer = TileLayer(
size=Size(int(raw_layer.attrib["width"]), int(raw_layer.attrib["height"])),
**_parse_common(raw_layer).__dict__,
**common,
)
data_element = raw_layer.find("./data")
if data_element:
data_element = raw_layer.find("data")
if data_element is not None:
encoding = None
if data_element.attrib.get("encoding") is not None:
encoding = data_element.attrib["encoding"]
@@ -202,10 +211,9 @@ def _parse_tile_layer(raw_layer: etree.Element) -> TileLayer:
if data_element.attrib.get("compression") is not None:
compression = data_element.attrib["compression"]
raw_chunks = data_element.findall("./chunk")
raw_chunks = data_element.findall("chunk")
if not raw_chunks:
if encoding:
if encoding and encoding != "csv":
tile_layer.data = _decode_tile_layer_data(
data=data_element.text, # type: ignore
compression=compression,
@@ -213,7 +221,7 @@ def _parse_tile_layer(raw_layer: etree.Element) -> TileLayer:
)
else:
tile_layer.data = _convert_raw_tile_layer_data(
[int(v.strip()) for v in data_element.text], # type: ignore
[int(v.strip()) for v in data_element.text.split(",")], # type: ignore
int(raw_layer.attrib["width"]),
)
else:
@@ -248,12 +256,16 @@ def _parse_object_layer(
for object_ in raw_layer.findall("./object"):
objects.append(parse_object(object_, parent_dir))
return ObjectLayer(
object_layer = ObjectLayer(
tiled_objects=objects,
draw_order=raw_layer.attrib["draworder"],
**_parse_common(raw_layer).__dict__,
)
if raw_layer.attrib.get("draworder") is not None:
object_layer.draw_order = raw_layer.attrib["draworder"]
return object_layer
def _parse_image_layer(raw_layer: etree.Element) -> ImageLayer:
"""Parse the raw_layer to an ImageLayer.
@@ -274,6 +286,8 @@ def _parse_image_layer(raw_layer: etree.Element) -> ImageLayer:
if image_element.attrib.get("trans") is not None:
transparent_color = parse_color(image_element.attrib["trans"])
common = _parse_common(raw_layer).__dict__
del common["size"]
return ImageLayer(
image=source,
size=Size(width, height),

View File

@@ -11,8 +11,9 @@ def parse(raw_properties: etree.Element) -> Properties:
final: Properties = {}
value: Property
for raw_property in raw_properties.findall("./property"):
type_ = raw_property.attrib["type"]
for raw_property in raw_properties.findall("property"):
type_ = raw_property.attrib.get("type")
value_ = raw_property.attrib["value"]
if type_ == "file":
value = Path(value_)

View File

@@ -18,6 +18,7 @@ def parse(file: Path) -> TiledMap:
Returns:
TiledMap: A parsed TiledMap.
"""
print(file)
with open(file) as map_file:
raw_map = etree.parse(map_file).getroot()
@@ -71,10 +72,10 @@ def parse(file: Path) -> TiledMap:
for my_layer in layers:
for tiled_object in my_layer.tiled_objects:
if hasattr(tiled_object, "new_tileset"):
if tiled_object.new_tileset:
if tiled_object.new_tileset is not None:
already_loaded = None
for val in map_.tilesets.values():
if val.name == tiled_object.new_tileset["name"]:
if val.name == tiled_object.new_tileset.attrib["name"]:
already_loaded = val
break

View File

@@ -32,15 +32,25 @@ def _parse_common(raw_object: etree.Element) -> TiledObject:
coordinates=OrderedPair(
float(raw_object.attrib["x"]), float(raw_object.attrib["y"])
),
visible=bool(int(raw_object.attrib["visible"])),
size=Size(
float(raw_object.attrib["width"]), float(raw_object.attrib["height"])
),
rotation=float(raw_object.attrib["rotation"]),
name=raw_object.attrib["name"],
type=raw_object.attrib["type"],
)
if raw_object.attrib.get("width") is not None:
common.size = Size(
float(raw_object.attrib["width"]), float(raw_object.attrib["height"])
)
if raw_object.attrib.get("visible") is not None:
common.visible = bool(int(raw_object.attrib["visible"]))
if raw_object.attrib.get("rotation") is not None:
common.rotation = float(raw_object.attrib["rotation"])
if raw_object.attrib.get("name") is not None:
common.name = raw_object.attrib["name"]
if raw_object.attrib.get("type") is not None:
common.type = raw_object.attrib["type"]
properties_element = raw_object.find("./properties")
if properties_element:
common.properties = parse_properties(properties_element)
@@ -94,9 +104,11 @@ def _parse_polygon(raw_object: etree.Element) -> Polygon:
Polygon: The Polygon object created from the raw object
"""
polygon = []
for raw_point in raw_object.attrib["points"].split(" "):
point = raw_point.split(",")
polygon.append(OrderedPair(float(point[0]), float(point[1])))
polygon_element = raw_object.find("./polygon")
if polygon_element is not None:
for raw_point in polygon_element.attrib["points"].split(" "):
point = raw_point.split(",")
polygon.append(OrderedPair(float(point[0]), float(point[1])))
return Polygon(points=polygon, **_parse_common(raw_object).__dict__)
@@ -204,23 +216,19 @@ def _get_parser(raw_object: etree.Element) -> Callable[[etree.Element], TiledObj
Returns:
Callable[[Element], Object]: The parser function.
"""
if raw_object.find("./ellipse"):
if raw_object.find("./ellipse") is not None:
return _parse_ellipse
if raw_object.find("./point"):
if raw_object.find("./point") is not None:
return _parse_point
if raw_object.attrib.get("gid"):
# Only tile objects have the `gid` attribute
return _parse_tile
if raw_object.find("./polygon"):
if raw_object.find("./polygon") is not None:
return _parse_polygon
if raw_object.find("./polyline"):
if raw_object.find("./polyline") is not None:
return _parse_polyline
if raw_object.find("./text"):
if raw_object.find("./text") is not None:
return _parse_text
# If it's none of the above, rectangle is the only one left.
@@ -263,13 +271,22 @@ def parse(raw_object: etree.Element, parent_dir: Optional[Path] = None) -> Tiled
new_tileset_path = tileset_path.parent
new_object = template.find("./object")
if raw_object.attrib.get("id") and new_object:
new_object.attrib["id"] = raw_object.attrib["id"]
if new_object is not None:
if raw_object.attrib.get("id") is not None:
new_object.attrib["id"] = raw_object.attrib["id"]
if raw_object.attrib.get("x") is not None:
new_object.attrib["x"] = raw_object.attrib["x"]
if raw_object.attrib.get("y") is not None:
new_object.attrib["y"] = raw_object.attrib["y"]
if new_object:
raw_object = new_object
if raw_object.attrib.get("gid"):
return _parse_tile(raw_object, new_tileset, new_tileset_path)
if raw_object.attrib.get("gid"):
return _parse_tile(raw_object, new_tileset, new_tileset_path)
return _parse_tile(raw_object)
return _get_parser(raw_object)(raw_object)

View File

@@ -79,21 +79,21 @@ def _parse_tile(raw_tile: etree.Element, external_path: Optional[Path] = None) -
tile.type = raw_tile.attrib["type"]
animation_element = raw_tile.find("./animation")
if animation_element:
if animation_element is not None:
tile.animation = []
for raw_frame in animation_element.findall("./frame"):
tile.animation.append(_parse_frame(raw_frame))
object_element = raw_tile.find("./objectgroup")
if object_element:
if object_element is not None:
tile.objects = parse_layer(object_element)
properties_element = raw_tile.find("./properties")
if properties_element:
if properties_element is not None:
tile.properties = parse_properties(properties_element)
image_element = raw_tile.find("./image")
if image_element:
if image_element is not None:
if external_path:
tile.image = (
Path(external_path / image_element.attrib["source"])
@@ -120,8 +120,6 @@ def parse(
tile_width=int(raw_tileset.attrib["tilewidth"]),
tile_height=int(raw_tileset.attrib["tileheight"]),
columns=int(raw_tileset.attrib["columns"]),
spacing=int(raw_tileset.attrib["spacing"]),
margin=int(raw_tileset.attrib["margin"]),
firstgid=firstgid,
)
@@ -134,9 +132,14 @@ def parse(
if raw_tileset.attrib.get("backgroundcolor") is not None:
tileset.background_color = parse_color(raw_tileset.attrib["backgroundcolor"])
if raw_tileset.attrib.get("spacing") is not None:
tileset.spacing = int(raw_tileset.attrib["spacing"])
if raw_tileset.attrib.get("margin") is not None:
tileset.margin = int(raw_tileset.attrib["margin"])
image_element = raw_tileset.find("image")
if image_element is not None:
print("here")
if external_path:
tileset.image = (
Path(external_path / image_element.attrib["source"])
@@ -156,21 +159,21 @@ def parse(
tileset.transparent_color = parse_color(my_string)
tileoffset_element = raw_tileset.find("./tileoffset")
if tileoffset_element:
if tileoffset_element is not None:
tileset.tile_offset = OrderedPair(
int(tileoffset_element.attrib["x"]), int(tileoffset_element.attrib["y"])
)
grid_element = raw_tileset.find("./grid")
if grid_element:
if grid_element is not None:
tileset.grid = _parse_grid(grid_element)
properties_element = raw_tileset.find("./properties")
if properties_element:
if properties_element is not None:
tileset.properties = parse_properties(properties_element)
tiles = {}
for tile_element in raw_tileset.findall("./tiles"):
for tile_element in raw_tileset.findall("./tile"):
tiles[int(tile_element.attrib["id"])] = _parse_tile(
tile_element, external_path=external_path
)
@@ -178,14 +181,14 @@ def parse(
tileset.tiles = tiles
wangsets_element = raw_tileset.find("./wangsets")
if wangsets_element:
if wangsets_element is not None:
wangsets = []
for raw_wangset in wangsets_element.findall("./wangset"):
wangsets.append(parse_wangset(raw_wangset))
tileset.wang_sets = wangsets
transformations_element = raw_tileset.find("./transformations")
if transformations_element:
if transformations_element is not None:
tileset.transformations = _parse_transformations(transformations_element)
return tileset

View File

@@ -35,10 +35,9 @@ class TiledObject:
coordinates: OrderedPair
size: Size = Size(0, 0)
rotation: float = 0
visible: bool
name: Optional[str] = None
type: Optional[str] = None
visible: bool = True
name: str = ""
type: str = ""
properties: properties_.Properties = {}