Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pytiled_parser/parsers/json/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,9 @@ def _parse_common(raw_layer: RawLayer) -> Layer:
if raw_layer.get("width") is not None:
common.size = Size(raw_layer["width"], raw_layer["height"])

if raw_layer.get("offsetx") is not None:
common.offset = OrderedPair(raw_layer["offsetx"], raw_layer["offsety"])
common.offset = OrderedPair(
raw_layer.get("offsetx", 0), raw_layer.get("offsety", 0)
)

if raw_layer.get("properties") is not None:
common.properties = parse_properties(raw_layer["properties"])
Expand Down
8 changes: 4 additions & 4 deletions pytiled_parser/parsers/tmx/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,10 @@ def _parse_common(raw_layer: etree.Element) -> Layer:
if raw_layer.attrib.get("id") is not None:
common.id = int(raw_layer.attrib["id"])

if raw_layer.attrib.get("offsetx") is not None:
common.offset = OrderedPair(
float(raw_layer.attrib["offsetx"]), float(raw_layer.attrib["offsety"])
)
common.offset = OrderedPair(
float(raw_layer.attrib.get("offsetx", 0)),
float(raw_layer.attrib.get("offsety", 0)),
)

properties_element = raw_layer.find("./properties")
if properties_element is not None:
Expand Down
69 changes: 69 additions & 0 deletions tests/test_layer_offsets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""Layer offset axes are independently optional in both map formats."""

import xml.etree.ElementTree as etree

import pytest

from pytiled_parser.common_types import OrderedPair
from pytiled_parser.parsers.json.layer import parse as parse_json
from pytiled_parser.parsers.tmx.layer import parse as parse_tmx


@pytest.mark.parametrize("parser_type", ["json", "tmx"])
@pytest.mark.parametrize(
"layer_type", ["tilelayer", "objectgroup", "imagelayer", "group"]
)
@pytest.mark.parametrize(
"offsets,expected",
[
({}, (0, 0)),
({"offsetx": 17.5}, (17.5, 0)),
({"offsety": -6.25}, (0, -6.25)),
({"offsetx": 0}, (0, 0)),
({"offsety": 0}, (0, 0)),
({"offsetx": 0, "offsety": -6.25}, (0, -6.25)),
({"offsetx": -17.5, "offsety": 6.25}, (-17.5, 6.25)),
],
)
def test_independent_layer_offsets(parser_type, layer_type, offsets, expected):
if parser_type == "json":
raw = {
"name": "test",
"type": layer_type,
"opacity": 1,
"visible": True,
**offsets,
}
if layer_type == "tilelayer":
raw.update(width=1, height=1, data=[0])
elif layer_type == "objectgroup":
raw.update(objects=[], draworder="topdown")
elif layer_type == "imagelayer":
raw["image"] = "background.png"
else:
raw["layers"] = []
# Exercise recursive parsing as well as each concrete layer parser.
group = parse_json(
{
"name": "parent",
"type": "group",
"opacity": 1,
"visible": True,
"layers": [raw],
},
encoding="utf-8",
)
else:
parent = etree.Element("group", name="parent")
tag = "layer" if layer_type == "tilelayer" else layer_type
raw = etree.SubElement(parent, tag, name="test")
raw.attrib.update({key: str(value) for key, value in offsets.items()})
if layer_type == "tilelayer":
raw.attrib.update(width="1", height="1")
etree.SubElement(raw, "data", encoding="csv").text = "0"
elif layer_type == "imagelayer":
etree.SubElement(raw, "image", source="background.png")
group = parse_tmx(parent, encoding="utf-8")

assert group.offset == OrderedPair(0, 0)
assert group.layers[0].offset == OrderedPair(*expected)