mirror of
https://github.com/OMGeeky/pytiled_parser.git
synced 2026-01-01 09:03:41 +01:00
132 lines
5.2 KiB
Python
132 lines
5.2 KiB
Python
import json
|
|
import xml.etree.ElementTree as etree
|
|
from pathlib import Path
|
|
|
|
from pytiled_parser.common_types import OrderedPair, Size
|
|
from pytiled_parser.exception import UnknownFormat
|
|
from pytiled_parser.parsers.json.tileset import parse as parse_json_tileset
|
|
from pytiled_parser.parsers.tmx.layer import parse as parse_layer
|
|
from pytiled_parser.parsers.tmx.properties import parse as parse_properties
|
|
from pytiled_parser.parsers.tmx.tileset import parse as parse_tmx_tileset
|
|
from pytiled_parser.tiled_map import TiledMap, TilesetDict
|
|
from pytiled_parser.util import check_format, parse_color
|
|
|
|
|
|
def parse(file: Path) -> TiledMap:
|
|
"""Parse the raw Tiled map into a pytiled_parser type.
|
|
|
|
Args:
|
|
file: Path to the map file.
|
|
|
|
Returns:
|
|
TiledMap: A parsed TiledMap.
|
|
"""
|
|
with open(file) as map_file:
|
|
raw_map = etree.parse(map_file).getroot()
|
|
|
|
parent_dir = file.parent
|
|
|
|
raw_tilesets = raw_map.findall("./tileset")
|
|
tilesets: TilesetDict = {}
|
|
|
|
for raw_tileset in raw_tilesets:
|
|
if raw_tileset.attrib.get("source") is not None:
|
|
# Is an external Tileset
|
|
tileset_path = Path(parent_dir / raw_tileset.attrib["source"])
|
|
parser = check_format(tileset_path)
|
|
with open(tileset_path) as tileset_file:
|
|
if parser == "tmx":
|
|
raw_tileset_external = etree.parse(tileset_file).getroot()
|
|
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tmx_tileset(
|
|
raw_tileset_external,
|
|
int(raw_tileset.attrib["firstgid"]),
|
|
external_path=tileset_path.parent,
|
|
)
|
|
elif parser == "json":
|
|
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_json_tileset(
|
|
json.load(tileset_file),
|
|
int(raw_tileset.attrib["firstgid"]),
|
|
external_path=tileset_path.parent,
|
|
)
|
|
else:
|
|
raise UnknownFormat(
|
|
"Unkown Tileset format, please use either the TSX or JSON format."
|
|
)
|
|
|
|
else:
|
|
# Is an embedded Tileset
|
|
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tmx_tileset(
|
|
raw_tileset, int(raw_tileset.attrib["firstgid"])
|
|
)
|
|
|
|
layers = []
|
|
for element in raw_map.iter():
|
|
if element.tag in ["layer", "objectgroup", "imagelayer", "group"]:
|
|
layers.append(parse_layer(element, parent_dir))
|
|
|
|
map_ = TiledMap(
|
|
map_file=file,
|
|
infinite=bool(int(raw_map.attrib["infinite"])),
|
|
layers=layers,
|
|
map_size=Size(int(raw_map.attrib["width"]), int(raw_map.attrib["height"])),
|
|
next_layer_id=int(raw_map.attrib["nextlayerid"]),
|
|
next_object_id=int(raw_map.attrib["nextobjectid"]),
|
|
orientation=raw_map.attrib["orientation"],
|
|
render_order=raw_map.attrib["renderorder"],
|
|
tiled_version=raw_map.attrib["tiledversion"],
|
|
tile_size=Size(
|
|
int(raw_map.attrib["tilewidth"]), int(raw_map.attrib["tileheight"])
|
|
),
|
|
tilesets=tilesets,
|
|
version=raw_map.attrib["version"],
|
|
)
|
|
|
|
layers = [layer for layer in map_.layers if hasattr(layer, "tiled_objects")]
|
|
|
|
for my_layer in layers:
|
|
for tiled_object in my_layer.tiled_objects:
|
|
if hasattr(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.attrib["name"]:
|
|
already_loaded = val
|
|
break
|
|
|
|
if not already_loaded:
|
|
highest_firstgid = max(map_.tilesets.keys())
|
|
last_tileset_count = map_.tilesets[highest_firstgid].tile_count
|
|
new_firstgid = highest_firstgid + last_tileset_count
|
|
map_.tilesets[new_firstgid] = parse_tmx_tileset(
|
|
tiled_object.new_tileset,
|
|
new_firstgid,
|
|
tiled_object.new_tileset_path,
|
|
)
|
|
tiled_object.gid = tiled_object.gid + (new_firstgid - 1)
|
|
|
|
else:
|
|
tiled_object.gid = tiled_object.gid + (
|
|
already_loaded.firstgid - 1
|
|
)
|
|
|
|
tiled_object.new_tileset = None
|
|
tiled_object.new_tileset_path = None
|
|
|
|
if raw_map.attrib.get("backgroundcolor") is not None:
|
|
map_.background_color = parse_color(raw_map.attrib["backgroundcolor"])
|
|
|
|
if raw_map.attrib.get("hexsidelength") is not None:
|
|
map_.hex_side_length = int(raw_map.attrib["hexsidelength"])
|
|
|
|
properties_element = raw_map.find("./properties")
|
|
if properties_element:
|
|
map_.properties = parse_properties(properties_element)
|
|
|
|
if raw_map.attrib.get("staggeraxis") is not None:
|
|
map_.stagger_axis = raw_map.attrib["staggeraxis"]
|
|
|
|
if raw_map.attrib.get("staggerindex") is not None:
|
|
map_.stagger_index = raw_map.attrib["staggerindex"]
|
|
|
|
return map_
|