mirror of
https://github.com/OMGeeky/pytiled_parser.git
synced 2026-02-23 15:49:52 +01:00
Automatic detection of map/tileset format
This commit is contained in:
@@ -12,8 +12,9 @@ PyTiled Parser is not tied to any particular graphics library or game engine.
|
|||||||
# pylint: disable=too-few-public-methods
|
# pylint: disable=too-few-public-methods
|
||||||
|
|
||||||
from .common_types import OrderedPair, Size
|
from .common_types import OrderedPair, Size
|
||||||
|
from .exception import UnknownFormat
|
||||||
from .layer import ImageLayer, Layer, LayerGroup, ObjectLayer, TileLayer
|
from .layer import ImageLayer, Layer, LayerGroup, ObjectLayer, TileLayer
|
||||||
from .parser import parse_map, parse_tmx
|
from .parser import parse_map
|
||||||
from .properties import Properties
|
from .properties import Properties
|
||||||
from .tiled_map import TiledMap
|
from .tiled_map import TiledMap
|
||||||
from .tileset import Tile, Tileset
|
from .tileset import Tile, Tileset
|
||||||
|
|||||||
2
pytiled_parser/exception.py
Normal file
2
pytiled_parser/exception.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
class UnknownFormat(Exception):
|
||||||
|
pass
|
||||||
@@ -1,22 +1,29 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from pytiled_parser import UnknownFormat
|
||||||
from pytiled_parser.parsers.json.tiled_map import parse as json_map_parse
|
from pytiled_parser.parsers.json.tiled_map import parse as json_map_parse
|
||||||
from pytiled_parser.parsers.tmx.tiled_map import parse as tmx_map_parse
|
from pytiled_parser.parsers.tmx.tiled_map import parse as tmx_map_parse
|
||||||
from pytiled_parser.tiled_map import TiledMap
|
from pytiled_parser.tiled_map import TiledMap
|
||||||
|
from pytiled_parser.util import check_format
|
||||||
|
|
||||||
|
|
||||||
def parse_map(file: Path) -> TiledMap:
|
def parse_map(file: Path) -> TiledMap:
|
||||||
"""Parse the raw Tiled map into a pytiled_parser type
|
"""Parse the raw Tiled map into a pytiled_parser type
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file: Path to the map's JSON file
|
file: Path to the map file
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
TileSet: a properly typed TileSet.
|
Tiledmap: a properly typed TiledMap
|
||||||
"""
|
"""
|
||||||
# I have no idea why, but mypy thinks this function returns "Any"
|
parser = check_format(file)
|
||||||
return json_map_parse(file) # type: ignore
|
|
||||||
|
|
||||||
|
# The type ignores are because mypy for some reaosn thinks those functions return Any
|
||||||
def parse_tmx(file: Path) -> TiledMap:
|
if parser == "tmx":
|
||||||
return tmx_map_parse(file) # type: ignore
|
return tmx_map_parse(file) # type: ignore
|
||||||
|
elif parser == "json":
|
||||||
|
return json_map_parse(file) # type: ignore
|
||||||
|
else:
|
||||||
|
raise UnknownFormat(
|
||||||
|
"Unknown Map Format, please use either the TMX or JSON format."
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
import json
|
import json
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Union, cast
|
from typing import List, Union, cast
|
||||||
|
|
||||||
from typing_extensions import TypedDict
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from pytiled_parser.common_types import Size
|
from pytiled_parser.common_types import Size
|
||||||
|
from pytiled_parser.exception import UnknownFormat
|
||||||
from pytiled_parser.parsers.json.layer import RawLayer
|
from pytiled_parser.parsers.json.layer import RawLayer
|
||||||
from pytiled_parser.parsers.json.layer import parse as parse_layer
|
from pytiled_parser.parsers.json.layer import parse as parse_layer
|
||||||
from pytiled_parser.parsers.json.properties import RawProperty
|
from pytiled_parser.parsers.json.properties import RawProperty
|
||||||
from pytiled_parser.parsers.json.properties import parse as parse_properties
|
from pytiled_parser.parsers.json.properties import parse as parse_properties
|
||||||
from pytiled_parser.parsers.json.tileset import RawTileSet
|
from pytiled_parser.parsers.json.tileset import RawTileSet
|
||||||
from pytiled_parser.parsers.json.tileset import parse as parse_tileset
|
from pytiled_parser.parsers.json.tileset import parse as parse_json_tileset
|
||||||
|
from pytiled_parser.parsers.tmx.tileset import parse as parse_tmx_tileset
|
||||||
from pytiled_parser.tiled_map import TiledMap, TilesetDict
|
from pytiled_parser.tiled_map import TiledMap, TilesetDict
|
||||||
from pytiled_parser.util import parse_color
|
from pytiled_parser.util import check_format, parse_color
|
||||||
|
|
||||||
|
|
||||||
class RawTilesetMapping(TypedDict):
|
class RawTilesetMapping(TypedDict):
|
||||||
@@ -70,16 +73,30 @@ def parse(file: Path) -> TiledMap:
|
|||||||
if raw_tileset.get("source") is not None:
|
if raw_tileset.get("source") is not None:
|
||||||
# Is an external Tileset
|
# Is an external Tileset
|
||||||
tileset_path = Path(parent_dir / raw_tileset["source"])
|
tileset_path = Path(parent_dir / raw_tileset["source"])
|
||||||
|
parser = check_format(tileset_path)
|
||||||
with open(tileset_path) as raw_tileset_file:
|
with open(tileset_path) as raw_tileset_file:
|
||||||
tilesets[raw_tileset["firstgid"]] = parse_tileset(
|
if parser == "json":
|
||||||
json.load(raw_tileset_file),
|
tilesets[raw_tileset["firstgid"]] = parse_json_tileset(
|
||||||
raw_tileset["firstgid"],
|
json.load(raw_tileset_file),
|
||||||
external_path=tileset_path.parent,
|
raw_tileset["firstgid"],
|
||||||
)
|
external_path=tileset_path.parent,
|
||||||
|
)
|
||||||
|
elif parser == "tmx":
|
||||||
|
raw_tileset_external = etree.parse(raw_tileset_file).getroot()
|
||||||
|
tilesets[raw_tileset["firstgid"]] = parse_tmx_tileset(
|
||||||
|
raw_tileset_external,
|
||||||
|
raw_tileset["firstgid"],
|
||||||
|
external_path=tileset_path.parent,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise UnknownFormat(
|
||||||
|
"Unkown Tileset format, please use either the TSX or JSON format."
|
||||||
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Is an embedded Tileset
|
# Is an embedded Tileset
|
||||||
raw_tileset = cast(RawTileSet, raw_tileset)
|
raw_tileset = cast(RawTileSet, raw_tileset)
|
||||||
tilesets[raw_tileset["firstgid"]] = parse_tileset(
|
tilesets[raw_tileset["firstgid"]] = parse_json_tileset(
|
||||||
raw_tileset, raw_tileset["firstgid"]
|
raw_tileset, raw_tileset["firstgid"]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -120,7 +137,7 @@ def parse(file: Path) -> TiledMap:
|
|||||||
highest_firstgid = max(map_.tilesets.keys())
|
highest_firstgid = max(map_.tilesets.keys())
|
||||||
last_tileset_count = map_.tilesets[highest_firstgid].tile_count
|
last_tileset_count = map_.tilesets[highest_firstgid].tile_count
|
||||||
new_firstgid = highest_firstgid + last_tileset_count
|
new_firstgid = highest_firstgid + last_tileset_count
|
||||||
map_.tilesets[new_firstgid] = parse_tileset(
|
map_.tilesets[new_firstgid] = parse_json_tileset(
|
||||||
tiled_object.new_tileset,
|
tiled_object.new_tileset,
|
||||||
new_firstgid,
|
new_firstgid,
|
||||||
tiled_object.new_tileset_path,
|
tiled_object.new_tileset_path,
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
import json
|
||||||
import xml.etree.ElementTree as etree
|
import xml.etree.ElementTree as etree
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from pytiled_parser.common_types import OrderedPair, Size
|
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.layer import parse as parse_layer
|
||||||
from pytiled_parser.parsers.tmx.properties import parse as parse_properties
|
from pytiled_parser.parsers.tmx.properties import parse as parse_properties
|
||||||
from pytiled_parser.parsers.tmx.tileset import parse as parse_tileset
|
from pytiled_parser.parsers.tmx.tileset import parse as parse_tmx_tileset
|
||||||
from pytiled_parser.tiled_map import TiledMap, TilesetDict
|
from pytiled_parser.tiled_map import TiledMap, TilesetDict
|
||||||
from pytiled_parser.util import parse_color
|
from pytiled_parser.util import check_format, parse_color
|
||||||
|
|
||||||
|
|
||||||
def parse(file: Path) -> TiledMap:
|
def parse(file: Path) -> TiledMap:
|
||||||
@@ -18,7 +21,6 @@ def parse(file: Path) -> TiledMap:
|
|||||||
Returns:
|
Returns:
|
||||||
TiledMap: A parsed TiledMap.
|
TiledMap: A parsed TiledMap.
|
||||||
"""
|
"""
|
||||||
print(file)
|
|
||||||
with open(file) as map_file:
|
with open(file) as map_file:
|
||||||
raw_map = etree.parse(map_file).getroot()
|
raw_map = etree.parse(map_file).getroot()
|
||||||
|
|
||||||
@@ -31,17 +33,29 @@ def parse(file: Path) -> TiledMap:
|
|||||||
if raw_tileset.attrib.get("source") is not None:
|
if raw_tileset.attrib.get("source") is not None:
|
||||||
# Is an external Tileset
|
# Is an external Tileset
|
||||||
tileset_path = Path(parent_dir / raw_tileset.attrib["source"])
|
tileset_path = Path(parent_dir / raw_tileset.attrib["source"])
|
||||||
|
parser = check_format(tileset_path)
|
||||||
with open(tileset_path) as tileset_file:
|
with open(tileset_path) as tileset_file:
|
||||||
raw_tileset_external = etree.parse(tileset_file).getroot()
|
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."
|
||||||
|
)
|
||||||
|
|
||||||
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tileset(
|
|
||||||
raw_tileset_external,
|
|
||||||
int(raw_tileset.attrib["firstgid"]),
|
|
||||||
external_path=tileset_path.parent,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# Is an embedded Tileset
|
# Is an embedded Tileset
|
||||||
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tileset(
|
tilesets[int(raw_tileset.attrib["firstgid"])] = parse_tmx_tileset(
|
||||||
raw_tileset, int(raw_tileset.attrib["firstgid"])
|
raw_tileset, int(raw_tileset.attrib["firstgid"])
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -83,7 +97,7 @@ def parse(file: Path) -> TiledMap:
|
|||||||
highest_firstgid = max(map_.tilesets.keys())
|
highest_firstgid = max(map_.tilesets.keys())
|
||||||
last_tileset_count = map_.tilesets[highest_firstgid].tile_count
|
last_tileset_count = map_.tilesets[highest_firstgid].tile_count
|
||||||
new_firstgid = highest_firstgid + last_tileset_count
|
new_firstgid = highest_firstgid + last_tileset_count
|
||||||
map_.tilesets[new_firstgid] = parse_tileset(
|
map_.tilesets[new_firstgid] = parse_tmx_tileset(
|
||||||
tiled_object.new_tileset,
|
tiled_object.new_tileset,
|
||||||
new_firstgid,
|
new_firstgid,
|
||||||
tiled_object.new_tileset_path,
|
tiled_object.new_tileset_path,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
"""Utility Functions for PyTiled"""
|
"""Utility Functions for PyTiled"""
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from pytiled_parser.common_types import Color
|
from pytiled_parser.common_types import Color
|
||||||
|
|
||||||
@@ -27,3 +28,12 @@ def parse_color(color: str) -> Color:
|
|||||||
)
|
)
|
||||||
|
|
||||||
raise ValueError("Improperly formatted color passed to parse_color")
|
raise ValueError("Improperly formatted color passed to parse_color")
|
||||||
|
|
||||||
|
|
||||||
|
def check_format(file_path: Path) -> str:
|
||||||
|
with open(file_path) as file:
|
||||||
|
line = file.readline().rstrip().strip()
|
||||||
|
if line[0] == "<":
|
||||||
|
return "tmx"
|
||||||
|
else:
|
||||||
|
return "json"
|
||||||
|
|||||||
Reference in New Issue
Block a user