Merge pull request #26 from Beefy-Swain/rf/caster

JSON Re-Write
This commit is contained in:
Darren Eberly
2021-02-20 22:11:17 -08:00
committed by GitHub
103 changed files with 7656 additions and 2341 deletions

3
.gitignore vendored
View File

@@ -103,3 +103,6 @@ venv.bak/
# mypy
.mypy_cache/
.idea/
# VS Code Directory
.vscode

View File

@@ -305,7 +305,8 @@ good-names=i,
y,
ex,
Run,
_
_,
id
# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no

View File

@@ -1,8 +1,7 @@
# PyTiled Parser
PyTiled Parser is a Python Library for parsing
[Tiled Map Editor](https://www.mapeditor.org/) (`.tmx`) files used to generate
maps and levels for 2D top-down or side-scrolling games.
PyTiled Parser is a Python Library for parsing JSON formatted
[Tiled Map Editor](https://www.mapeditor.org/) maps and tilesets to be used as maps and levels for 2D top-down (orthogonal, hexogonal, or isometric) or side-scrolling games in a strictly typed fashion.
PyTiled Parser is not tied to any particular graphics library, and can be used
with [Arcade](http://arcade.academy),
@@ -10,7 +9,7 @@ with [Arcade](http://arcade.academy),
[Pygame](https://www.pygame.org/news), etc.
* Documentation available at: https://pytiled-parser.readthedocs.io/
* GitHub project at: https://github.com/pvcraven/pytiled_parser
* GitHub project at: https://github.com/Beefy-Swain/pytiled_parser
* PiPy: https://pypi.org/project/pytiled-parser/
The [Arcade](http://arcade.academy) library has
@@ -19,4 +18,10 @@ integrate PyTiled with that 2D libary, and
[example code](http://arcade.academy/examples/index.html#tmx-files-tiled-map-editor) showing its use.
Original module by [Beefy-Swain](https://github.com/Beefy-Swain).
Contributions from [pvcraven](https://github.com/pvcraven).
Significant contributions from [pvcraven](https://github.com/pvcraven) and [Cleptomania](https://github.com/Cleptomania).
## Developement
To develop pytiled parser, clone the repo, create a `venv` using a supported Python version, and activate it. Then install the package as well as all testing dependencies with the command `python -m pip install -e ".[tests]"`.
### Testing
Run `pytest --cov=pytiled_parser` to run the test harness and report coverage.

View File

@@ -1,11 +0,0 @@
-e .
black
pytest
sphinx
coverage
coveralls
sphinx_rtd_theme
setuptools
pytest-cov
pytest-mock
wheel

View File

@@ -1,35 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -1,23 +1,59 @@
.. _pytiled-api:
PyTiled Parser API
==================
This page documents the Application Programming Interface (API)
for the PyTiled Parser library.
pytiled\_parser.common\_types
------------------------------------
.. automodule:: pytiled_parser.xml_parser
:members:
:undoc-members:
:show-inheritance:
.. automodule:: pytiled_parser.common_types
:members:
:undoc-members:
:show-inheritance:
.. automodule:: pytiled_parser.objects
:members:
:undoc-members:
:show-inheritance:
pytiled\_parser.layer
----------------------------
.. automodule:: pytiled_parser.utilities
:members:
:undoc-members:
:show-inheritance:
.. automodule:: pytiled_parser.layer
:members:
:undoc-members:
:show-inheritance:
pytiled\_parser.properties
---------------------------------
.. automodule:: pytiled_parser.properties
:members:
:undoc-members:
:show-inheritance:
pytiled\_parser.tiled\_map
---------------------------------
.. automodule:: pytiled_parser.tiled_map
:members:
:undoc-members:
:show-inheritance:
pytiled\_parser.tiled\_object
------------------------------------
.. automodule:: pytiled_parser.tiled_object
:members:
:undoc-members:
:show-inheritance:
pytiled\_parser.tileset
------------------------------
.. automodule:: pytiled_parser.tileset
:members:
:undoc-members:
:show-inheritance:
pytiled\_parser.util
---------------------------
.. automodule:: pytiled_parser.util
:members:
:undoc-members:
:show-inheritance:

View File

@@ -2,7 +2,7 @@
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
@@ -10,21 +10,20 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
import os
import sys
project = "PyTiled Parser"
copyright = "2019, Beefy-Swain"
author = "Beefy-Swain"
sys.path.insert(0, os.path.abspath('../..'))
# -- Project information -----------------------------------------------------
project = 'PyTiled Parser'
copyright = '2021, Beefy-Swain, Cleptomania'
author = 'Beefy-Swain, Cleptomania'
# The full version, including alpha/beta/rc tags
release = '1.0.0'
sys.path.insert(0, os.path.abspath("../.."))
# -- General configuration ---------------------------------------------------
@@ -32,37 +31,34 @@ sys.path.insert(0, os.path.abspath("../.."))
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.ifconfig",
"sphinx.ext.viewcode",
'sphinx.ext.autodoc',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
source_suffix = ".rst"
master_doc = "index"
pygments_style = "sphinx"
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
source_suffix = '.rst'
master_doc = 'index'
pygments_style = 'sphinx'
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_static_path = ['_static']

View File

@@ -1,17 +1,11 @@
PyTiled Parser
==============
.. image:: 10_ladders_and_more.png
:width: 50%
PyTiled Parser is a Python library for parsing `Tiled Map Editor`_ (`.json`) files used to generate maps and levels for 2D games.
PyTiled Parser is a Python Library for parsing
`Tiled Map Editor`_ (`.tmx`) files used to generate
maps and levels for 2D top-down or side-scrolling games.
PyTiled Parser is not tied to any particular graphics library, and can be used with Arcade_, Pyglet_, Pygame_, and more.
PyTiled Parser is not tied to any particular graphics library, and can be used
with Arcade_, Pyglet_, Pygame_, and more.
API Documentation
API documentation
-----------------
.. toctree::
@@ -19,18 +13,8 @@ API Documentation
api
Examples
--------
* `Games using the Arcade library <http://arcade.academy/examples/index.html#tmx-files-tiled-map-editor>`_
.. _Tiled Map Editor: https://www.mapeditor.org/
.. _Arcade: http://arcade.academy
.. _Pyglet: https://pyglet.readthedocs.io/en/pyglet-1.3-maintenance/
.. _Pygame: https://www.pygame.org/news
For More Info
-------------
* `PyTiled Parser on GitHub <https://github.com/pvcraven/pytiled_parser>`_
* `PyTiled Parser on PyPi <https://pypi.org/project/pytiled-parser/>`_
* `PyTiled Parser on Github <https://github.com/beefy-swain/pytiled_parser>`_
* `PyTiled Parser on PyPi <https://pypi.org/project/pytiled-parser/>`_

130
make.bat
View File

@@ -1,130 +0,0 @@
@echo off
rem Build script for Windows
IF "%~1"=="" GOTO printdoc
IF "%~1"=="full" GOTO makefull
IF "%~1"=="dist" GOTO makedist
IF "%~1"=="test" GOTO test
IF "%~1"=="testcov" GOTO test
IF "%~1"=="fast" GOTO makefast
IF "%~1"=="docs" GOTO makedoc
IF "%~1"=="spelling" GOTO spelling
IF "%~1"=="deploy_pypi" GOTO deploy_pypi
IF "%~1"=="clean" GOTO clean
GOTO printdoc
:clean
rmdir /S /Q pytiled_parser.egg-info
rmdir /S /Q build
rmdir /S /Q dist
rmdir /S /Q .pytest_cache
rmdir /S /Q doc\build
GOTO end
:test
pytest
GOTO end
:testcov
pytest --cov=arcade
GOTO end
:makedist
rem Clean out old builds
del /q dist\*.*
python setup.py clean
rem Build the python
python setup.py build
python setup.py bdist_wheel
GOTO end
:makefull
rem -- This builds the project, installs it, and runs unit tests
rem Clean out old builds
rmdir /s /q "doc\build"
del /q dist\*.*
python setup.py clean
rem Build the python
python setup.py build
python setup.py bdist_wheel
rem Install the packages
pip uninstall -y arcade
for /r %%i in (dist\*) do pip install "%%i"
rem Build the documentation
sphinx-build -b html doc doc/build/html
rem Run tests and do code coverage
coverage run --source arcade setup.py test
coverage report --omit=arcade/examples/* -m
GOTO end
rem -- Make the documentation
:makedoc
rmdir /s /q "doc\build"
sphinx-build -n -b html doc doc/build/html
GOTO end
rem -- Make the documentation
:spelling
rmdir /s /q "doc\build"
sphinx-build -n -b spelling doc doc/build/html
GOTO end
rem == This does a fast build and install, but no unit tests
:makefast
python setup.py build
python setup.py bdist_wheel
pip uninstall -y pytiled_parser
for /r %%i in (dist\*) do pip install "%%i"
GOTO end
rem -- Deploy
:deploy_pypi
rem Do a "pip install twine" and set environment variables before running.
twine upload -u %PYPI_USER% -p %PYPI_PASSWORD% -r pypi dist/*
GOTO end
rem -- Print documentation
:printdoc
echo make test - Runs the tests
echo make testcov - Runs the tests with coverage
echo make dist - Make the distributables
echo make full - Builds the project, installs it, builds
echo documentation, runs unit tests.
echo make docs Builds the documentation. Documentation
echo will be in doc/build/html
echo make fast - Builds and installs the library WITHOUT unit
echo tests.
echo make deploy_pypi - Deploy to PyPi (if you have environment
echo variables set up correctly.)
:end

15
make.sh
View File

@@ -1,15 +0,0 @@
#!/bin/bash
rm -rf doc/build
rm dist/*
python3 setup.py clean
python3 setup.py build
python3 setup.py bdist_wheel
pip3 uninstall -y pytiled_parser
for file in dist/*
do
pip3 install $file
done
# sphinx-build -b html doc doc/build/html
coverage run --source pytiled_parser setup.py test
coverage report -m

View File

@@ -1,21 +0,0 @@
# Global options:
[mypy]
python_version = 3.6
warn_unused_configs = False
disallow_any_unimported = True
disallow_any_expr = True
disallow_any_decorated = True
disallow_any_explicit = True
disallow_any_generics = True
disallow_subclassing_any = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
warn_return_any = True
# Per-module options:
[mypy-tests.*]
ignore_errors = True

3
pyproject.toml Normal file
View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

View File

@@ -1,4 +1,19 @@
"""init for pytiled_parser"""
"""Parse Tiled Maps and Tilesets
from . import objects, utilities
from .xml_parser import parse_tile_map
See: https://www.mapeditor.org/
This library is for parsing JSON formatted Tiled Map Editormaps and tilesets to be
used as maps and levels for 2D top-down (orthogonal, hexogonal, or isometric)
or side-scrolling games in a strictly typed fashion.
PyTiled Parser is not tied to any particular graphics library or game engine.
"""
# pylint: disable=too-few-public-methods
from .common_types import OrderedPair, Size
from .layer import ImageLayer, Layer, LayerGroup, ObjectLayer, TileLayer
from .properties import Properties
from .tiled_map import TiledMap, parse_map
from .tileset import Tile, Tileset
from .version import __version__

View File

@@ -0,0 +1,52 @@
"""Module containing types that are common to other modules."""
# pylint: disable=too-few-public-methods
from typing import NamedTuple
import attr
class Color(NamedTuple):
"""Color NamedTuple.
Attributes:
red: Red, between 1 and 255.
green: Green, between 1 and 255.
blue: Blue, between 1 and 255.
alpha: Alpha, between 1 and 255.
"""
red: int
green: int
blue: int
alpha: int
@attr.s(auto_attribs=True)
class Template:
"""FIXME TODO"""
class Size(NamedTuple):
"""Size NamedTuple.
Attributes:
width: The width of the object in pixels.
height: The height of the object in pixels.
"""
width: float
height: float
class OrderedPair(NamedTuple):
"""OrderedPair NamedTuple.
Attributes:
x: X coordinate.
y: Y coordinate.
"""
x: float
y: float

465
pytiled_parser/layer.py Normal file
View File

@@ -0,0 +1,465 @@
"""This module handles parsing all types of layers.
See:
- https://doc.mapeditor.org/en/stable/reference/json-map-format/#layer
- https://doc.mapeditor.org/en/stable/manual/layers/
- https://doc.mapeditor.org/en/stable/manual/editing-tile-layers/
"""
# pylint: disable=too-few-public-methods
import base64
import gzip
import zlib
from pathlib import Path
from typing import Any, Callable, List, Optional, Union
from typing import cast as type_cast
import attr
from typing_extensions import TypedDict
from . import properties as properties_
from . import tiled_object
from .common_types import Color, OrderedPair, Size
from .util import parse_color
@attr.s(auto_attribs=True, kw_only=True)
class Layer:
"""Class that all layers inherit from.
See: https://doc.mapeditor.org/en/stable/reference/json-map-format/#layer
Attributes:
name: The name of the layer object.
opacity: Decimal value between 0 and 1 to determine opacity. 1 is completely
opaque, 0 is completely transparent.
visible: If the layer is visible in the Tiled Editor. (Do not use for games)
coordinates: Where layer content starts in tiles. (For infinite maps)
id: Unique ID of the layer. Each layer that added to a map gets a unique id.
Even if a layer is deleted, no layer ever gets the same ID.
size: Ordered pair of size of map in tiles.
offset: Rendering offset of the layer object in pixels.
properties: Properties for the layer.
"""
name: str
opacity: float
visible: bool
coordinates: OrderedPair = OrderedPair(0, 0)
id: Optional[int] = None
size: Optional[Size] = None
offset: Optional[OrderedPair] = None
properties: Optional[properties_.Properties] = None
TileLayerGrid = List[List[int]]
@attr.s(auto_attribs=True)
class Chunk:
"""Chunk object for infinite maps.
See: https://doc.mapeditor.org/en/stable/reference/json-map-format/#chunk
Attributes:
coordinates: Location of chunk in tiles.
size: The size of the chunk in tiles.
data: The global tile IDs in chunky according to row.
"""
coordinates: OrderedPair
size: Size
data: List[List[int]]
# The tile data for one layer.
#
# Either a 2 dimensional array of integers representing the global tile IDs
# for a TileLayerGrid, or a list of chunks for an infinite map layer.
LayerData = Union[TileLayerGrid, List[Chunk]]
@attr.s(auto_attribs=True, kw_only=True)
class TileLayer(Layer):
"""Tile map layer containing tiles.
See:
https://doc.mapeditor.org/en/stable/reference/json-map-format/#tile-layer-example
Attributes:
chunks: list of chunks (infinite maps)
data: Either an 2 dimensional array of integers representing the global tile
IDs for the map layer, or a list of chunks for an infinite map.
"""
chunks: Optional[List[Chunk]] = None
data: Optional[List[List[int]]] = None
@attr.s(auto_attribs=True, kw_only=True)
class ObjectLayer(Layer):
"""TiledObject Group Object.
The object group is in fact a map layer, and is hence called "object layer" in
Tiled.
See:
https://doc.mapeditor.org/en/stable/reference/json-map-format/#object-layer-example
Attributes:
tiled_objects: List of tiled_objects in the layer.
draworder: Whether the objects are drawn according to the order of the object
elements in the object group element ('manual'), or sorted by their
y-coordinate ('topdown'). Defaults to 'topdown'. See:
https://doc.mapeditor.org/en/stable/manual/objects/#changing-stacking-order
for more info.
"""
tiled_objects: List[tiled_object.TiledObject]
draw_order: Optional[str] = "topdown"
@attr.s(auto_attribs=True, kw_only=True)
class ImageLayer(Layer):
"""Map layer containing images.
See: https://doc.mapeditor.org/en/stable/manual/layers/#image-layers
Attributes:
image: The image used by this layer.
transparent_color: Color that is to be made transparent on this layer.
"""
image: Path
transparent_color: Optional[Color] = None
@attr.s(auto_attribs=True, kw_only=True)
class LayerGroup(Layer):
"""A layer that contains layers (potentially including other LayerGroups).
Offset and opacity recursively affect child layers.
See:
- https://doc.mapeditor.org/en/stable/reference/json-map-format/#layer
- https://doc.mapeditor.org/en/stable/manual/layers/#group-layers
Attributes:
Layers: list of layers contained in the group.
"""
layers: Optional[List[Layer]]
class RawChunk(TypedDict):
"""The keys and their types that appear in a Chunk JSON Object.
See: https://doc.mapeditor.org/en/stable/reference/json-map-format/#chunk
"""
data: Union[List[int], str]
height: int
width: int
x: int
y: int
class RawLayer(TypedDict):
"""The keys and their types that appear in a Layer JSON Object.
See: https://doc.mapeditor.org/en/stable/reference/json-map-format/#layer
"""
chunks: List[RawChunk]
compression: str
data: Union[List[int], str]
draworder: str
encoding: str
height: int
id: int
image: str
layers: List[Any]
name: str
objects: List[tiled_object.RawTiledObject]
offsetx: float
offsety: float
opacity: float
properties: List[properties_.RawProperty]
startx: int
starty: int
transparentcolor: str
type: str
visible: bool
width: int
x: int
y: int
def _convert_raw_tile_layer_data(data: List[int], layer_width: int) -> List[List[int]]:
"""Convert raw layer data into a nested lit based on the layer width
Args:
data: The data to convert
layer_width: Width of the layer
Returns:
List[List[int]]: A nested list containing the converted data
"""
tile_grid: List[List[int]] = [[]]
column_count = 0
row_count = 0
for item in data:
column_count += 1
tile_grid[row_count].append(item)
if not column_count % layer_width and column_count < len(data):
row_count += 1
tile_grid.append([])
return tile_grid
def _decode_tile_layer_data(
data: str, compression: str, layer_width: int
) -> List[List[int]]:
"""Decode Base64 Encoded tile data. Optionally supports gzip and zlib compression.
Args:
data: The base64 encoded data
compression: Either zlib, gzip, or empty. If empty no decompression is done.
Returns:
List[List[int]]: A nested list containing the decoded data
Raises:
ValueError: For an unsupported compression type.
"""
unencoded_data = base64.b64decode(data)
if compression == "zlib":
unzipped_data = zlib.decompress(unencoded_data)
elif compression == "gzip":
unzipped_data = gzip.decompress(unencoded_data)
else:
unzipped_data = unencoded_data
tile_grid: List[int] = []
byte_count = 0
int_count = 0
int_value = 0
for byte in unzipped_data:
int_value += byte << (byte_count * 8)
byte_count += 1
if not byte_count % 4:
byte_count = 0
int_count += 1
tile_grid.append(int_value)
int_value = 0
return _convert_raw_tile_layer_data(tile_grid, layer_width)
def _cast_chunk(
raw_chunk: RawChunk, encoding: Optional[str] = None, compression: str = None
) -> Chunk:
"""Cast the raw_chunk to a Chunk.
Args:
raw_chunk: RawChunk to be casted to a Chunk
encoding: Encoding type. ("base64" or None)
compression: Either zlib, gzip, or empty. If empty no decompression is done.
Returns:
Chunk: The Chunk created from the raw_chunk
"""
if encoding == "base64":
assert isinstance(compression, str)
assert isinstance(raw_chunk["data"], str)
data = _decode_tile_layer_data(
raw_chunk["data"], compression, raw_chunk["width"]
)
else:
data = _convert_raw_tile_layer_data(
raw_chunk["data"], raw_chunk["width"] # type: ignore
)
chunk = Chunk(
coordinates=OrderedPair(raw_chunk["x"], raw_chunk["y"]),
size=Size(raw_chunk["width"], raw_chunk["height"]),
data=data,
)
return chunk
def _get_common_attributes(raw_layer: RawLayer) -> Layer:
"""Create a Layer containing all the attributes common to all layers.
This is to create the stub Layer object that can then be used to create the actual
specific sub-classes of Layer.
Args:
raw_layer: Raw Tiled object get common attributes from
Returns:
Layer: The attributes in common of all layers
"""
common_attributes = Layer(
name=raw_layer["name"],
opacity=raw_layer["opacity"],
visible=raw_layer["visible"],
)
# if startx is present, starty is present
if raw_layer.get("startx") is not None:
common_attributes.coordinates = OrderedPair(
raw_layer["startx"], raw_layer["starty"]
)
if raw_layer.get("id") is not None:
common_attributes.id = raw_layer["id"]
# if either width or height is present, they both are
if raw_layer.get("width") is not None:
common_attributes.size = Size(raw_layer["width"], raw_layer["height"])
if raw_layer.get("offsetx") is not None:
common_attributes.offset = OrderedPair(
raw_layer["offsetx"], raw_layer["offsety"]
)
if raw_layer.get("properties") is not None:
common_attributes.properties = properties_.cast(raw_layer["properties"])
return common_attributes
def _cast_tile_layer(raw_layer: RawLayer) -> TileLayer:
"""Cast the raw_layer to a TileLayer.
Args:
raw_layer: RawLayer to be casted to a TileLayer
Returns:
TileLayer: The TileLayer created from raw_layer
"""
tile_layer = TileLayer(**_get_common_attributes(raw_layer).__dict__)
if raw_layer.get("chunks") is not None:
tile_layer.chunks = []
for chunk in raw_layer["chunks"]:
if raw_layer.get("encoding") is not None:
tile_layer.chunks.append(
_cast_chunk(chunk, raw_layer["encoding"], raw_layer["compression"])
)
else:
tile_layer.chunks.append(_cast_chunk(chunk))
if raw_layer.get("data") is not None:
if raw_layer.get("encoding") is not None:
tile_layer.data = _decode_tile_layer_data(
data=type_cast(str, raw_layer["data"]),
compression=raw_layer["compression"],
layer_width=raw_layer["width"],
)
else:
tile_layer.data = _convert_raw_tile_layer_data(
raw_layer["data"], raw_layer["width"] # type: ignore
)
return tile_layer
def _cast_object_layer(raw_layer: RawLayer) -> ObjectLayer:
"""Cast the raw_layer to an ObjectLayer.
Args:
raw_layer: RawLayer to be casted to an ObjectLayer
Returns:
ObjectLayer: The ObjectLayer created from raw_layer
"""
tiled_objects = []
for tiled_object_ in raw_layer["objects"]:
tiled_objects.append(tiled_object.cast(tiled_object_))
return ObjectLayer(
tiled_objects=tiled_objects,
draw_order=raw_layer["draworder"],
**_get_common_attributes(raw_layer).__dict__,
)
def _cast_image_layer(raw_layer: RawLayer) -> ImageLayer:
"""Cast the raw_layer to a ImageLayer.
Args:
raw_layer: RawLayer to be casted to a ImageLayer
Returns:
ImageLayer: The ImageLayer created from raw_layer
"""
image_layer = ImageLayer(
image=Path(raw_layer["image"]), **_get_common_attributes(raw_layer).__dict__
)
if raw_layer.get("transparentcolor") is not None:
image_layer.transparent_color = parse_color(raw_layer["transparentcolor"])
return image_layer
def _cast_group_layer(raw_layer: RawLayer) -> LayerGroup:
"""Cast the raw_layer to a LayerGroup.
Args:
raw_layer: RawLayer to be casted to a LayerGroup
Returns:
LayerGroup: The LayerGroup created from raw_layer
"""
layers = []
for layer in raw_layer["layers"]:
layers.append(cast(layer))
return LayerGroup(layers=layers, **_get_common_attributes(raw_layer).__dict__)
def _get_caster(type_: str) -> Callable[[RawLayer], Layer]:
"""Get the caster function for the raw layer.
Args:
type_: the type of the layer
Returns:
Callable[[RawLayer], Layer]: The caster function.
"""
casters = {
"tilelayer": _cast_tile_layer,
"objectgroup": _cast_object_layer,
"imagelayer": _cast_image_layer,
"group": _cast_group_layer,
}
return casters[type_]
def cast(raw_layer: RawLayer) -> Layer:
"""Cast a raw Tiled layer into a pytiled_parser type.
This function will determine the type of layer and cast accordingly.
Args:
raw_layer: Raw layer to be cast.
Returns:
Layer: a properly typed Layer.
"""
caster = _get_caster(raw_layer["type"])
return caster(raw_layer)

View File

@@ -0,0 +1,55 @@
"""Properties Module
This module casts raw properties from Tiled maps into a dictionary of
properly typed Properties.
"""
from pathlib import Path
from typing import Dict, List, Union
from typing import cast as type_cast
from typing_extensions import TypedDict
from .common_types import Color
from .util import parse_color
Property = Union[float, Path, str, bool, Color]
Properties = Dict[str, Property]
RawValue = Union[float, str, bool]
class RawProperty(TypedDict):
"""A dictionary of raw properties."""
name: str
type: str
value: RawValue
def cast(raw_properties: List[RawProperty]) -> Properties:
"""Cast a list of `RawProperty`s into `Properties`
Args:
raw_properties: The list of `RawProperty`s to cast.
Returns:
Properties: The casted `Properties`.
"""
final: Properties = {}
value: Property
for property_ in raw_properties:
if property_["type"] == "file":
value = Path(type_cast(str, property_["value"]))
elif property_["type"] == "color":
value = parse_color(type_cast(str, property_["value"]))
else:
value = property_["value"]
final[property_["name"]] = value
return final

View File

@@ -0,0 +1,8 @@
# pylint: disable=too-few-public-methods
import attr
@attr.s(auto_attribs=True)
class Template:
"""FIXME TODO"""

172
pytiled_parser/tiled_map.py Normal file
View File

@@ -0,0 +1,172 @@
# pylint: disable=too-few-public-methods
import json
from pathlib import Path
from typing import Dict, List, Optional, Union
from typing import cast as typing_cast
import attr
from typing_extensions import TypedDict
from . import layer, properties, tileset
from .common_types import Color, Size
from .layer import Layer, RawLayer
from .properties import Properties, RawProperty
from .tileset import RawTileSet, Tileset
from .util import parse_color
TilesetDict = Dict[int, Tileset]
@attr.s(auto_attribs=True)
class TiledMap:
"""Object for storing a TMX with all associated layers and properties.
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#map
Attributes:
infinite: If the map is infinite or not.
layers: List of layer objects by draw order.
map_size: The map width in tiles.
next_layer_id: Stores the next available ID for new layers.
next_object_id: Stores the next available ID for new objects.
orientation: Map orientation. Tiled supports "orthogonal", "isometric",
"staggered" and "hexagonal"
render_order: The order in which tiles on tile layers are rendered. Valid values
are right-down, right-up, left-down and left-up. In all cases, the map is
tiled_version: The Tiled version used to save the file. May be a date (for
snapshot builds).
drawn row-by-row. (only supported for orthogonal maps at the moment)
tile_size: The size of a tile.
tilesets: Dict of Tileset where Key is the firstgid and the value is the Tileset
version: The JSON format version.
background_color: The background color of the map.
properties: The properties of the Map.
hex_side_length: Only for hexagonal maps. Determines the width or height
(depending on the staggered axis) of the tile's edge, in pixels.
stagger_axis: For staggered and hexagonal maps, determines which axis ("x" or
"y") is staggered.
stagger_index: For staggered and hexagonal maps, determines whether the "even"
or "odd" indexes along the staggered axis are shifted.
"""
infinite: bool
layers: List[Layer]
map_size: Size
next_layer_id: Optional[int]
next_object_id: int
orientation: str
render_order: str
tiled_version: str
tile_size: Size
tilesets: TilesetDict
version: float
map_file: Optional[Path] = None
background_color: Optional[Color] = None
properties: Optional[Properties] = None
hex_side_length: Optional[int] = None
stagger_axis: Optional[str] = None
stagger_index: Optional[str] = None
class _RawTilesetMapping(TypedDict):
""" The way that tilesets are stored in the Tiled JSON formatted map."""
firstgid: int
source: str
class _RawTiledMap(TypedDict):
"""The keys and their types that appear in a Tiled JSON Map.
Keys:
compressionlevel: not documented - https://github.com/bjorn/tiled/issues/2815
"""
backgroundcolor: str
compressionlevel: int
height: int
hexsidelength: int
infinite: bool
layers: List[RawLayer]
nextlayerid: int
nextobjectid: int
orientation: str
properties: List[RawProperty]
renderorder: str
staggeraxis: str
staggerindex: str
tiledversion: str
tileheight: int
tilesets: List[_RawTilesetMapping]
tilewidth: int
type: str
version: float
width: int
def parse_map(file: Path) -> TiledMap:
"""Parse the raw Tiled map into a pytiled_parser type
Args:
file: Path to the map's JSON file
Returns:
TileSet: a properly typed TileSet.
"""
with open(file) as map_file:
raw_tiled_map = json.load(map_file)
parent_dir = file.parent
raw_tilesets: List[Union[RawTileSet, _RawTilesetMapping]] = raw_tiled_map[
"tilesets"
]
tilesets: TilesetDict = {}
for raw_tileset in raw_tilesets:
if raw_tileset.get("source") is not None:
# Is an external Tileset
with open(parent_dir / raw_tileset["source"]) as raw_tileset_file:
tilesets[raw_tileset["firstgid"]] = tileset.cast(
json.load(raw_tileset_file)
)
else:
# Is an embedded Tileset
raw_tileset = typing_cast(RawTileSet, raw_tileset)
tilesets[raw_tileset["firstgid"]] = tileset.cast(raw_tileset)
# `map` is a built-in function
map_ = TiledMap(
map_file=file,
infinite=raw_tiled_map["infinite"],
layers=[layer.cast(layer_) for layer_ in raw_tiled_map["layers"]],
map_size=Size(raw_tiled_map["width"], raw_tiled_map["height"]),
next_layer_id=raw_tiled_map["nextlayerid"],
next_object_id=raw_tiled_map["nextobjectid"],
orientation=raw_tiled_map["orientation"],
render_order=raw_tiled_map["renderorder"],
tiled_version=raw_tiled_map["tiledversion"],
tile_size=Size(raw_tiled_map["tilewidth"], raw_tiled_map["tileheight"]),
tilesets=tilesets,
version=raw_tiled_map["version"],
)
if raw_tiled_map.get("backgroundcolor") is not None:
map_.background_color = parse_color(raw_tiled_map["backgroundcolor"])
if raw_tiled_map.get("hexsidelength") is not None:
map_.hex_side_length = raw_tiled_map["hexsidelength"]
if raw_tiled_map.get("properties") is not None:
map_.properties = properties.cast(raw_tiled_map["properties"])
if raw_tiled_map.get("staggeraxis") is not None:
map_.stagger_axis = raw_tiled_map["staggeraxis"]
if raw_tiled_map.get("staggerindex") is not None:
map_.stagger_index = raw_tiled_map["staggerindex"]
return map_

View File

@@ -0,0 +1,405 @@
# pylint: disable=too-few-public-methods
from typing import Callable, Dict, List, Optional, Union
import attr
from typing_extensions import TypedDict
from . import properties as properties_
from .common_types import Color, OrderedPair, Size
from .util import parse_color
@attr.s(auto_attribs=True, kw_only=True)
class TiledObject:
"""TiledObject object.
See:
https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#object
Attributes:
id_: Unique ID of the tiled object. Each tiled object that is placed on a map
gets a unique id. Even if an tiled object was deleted, no tiled object gets
the same ID.
gid: Global tiled object ID.
coordinates: The location of the tiled object in pixels.
size: The width of the tiled object in pixels (default: (0, 0)).
rotation: The rotation of the tiled object in degrees clockwise (default: 0).
opacity: The opacity of the tiled object. (default: 1)
name: The name of the tiled object.
type: The type of the tiled object.
properties: The properties of the TiledObject.
"""
id: int
coordinates: OrderedPair
size: Size = Size(0, 0)
rotation: float = 0
visible: bool
name: Optional[str] = None
type: Optional[str] = None
properties: properties_.Properties = {}
@attr.s()
class Ellipse(TiledObject):
"""Elipse shape defined by a point, width, height, and rotation.
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#ellipse
"""
@attr.s()
class Point(TiledObject):
"""Point defined by a coordinate (x,y).
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#point
"""
@attr.s(auto_attribs=True, kw_only=True)
class Polygon(TiledObject):
"""Polygon shape defined by a set of connections between points.
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#polygon
Attributes:
points: FIXME
"""
points: List[OrderedPair]
@attr.s(auto_attribs=True, kw_only=True)
class Polyline(TiledObject):
"""Polyline defined by a set of connections between points.
See:
https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#polyline
Attributes:
points: List of coordinates relative to the location of the object.
"""
points: List[OrderedPair]
@attr.s()
class Rectangle(TiledObject):
"""Rectangle shape defined by a point, width, and height.
See: https://doc.mapeditor.org/en/stable/manual/objects/#insert-rectangle
(objects in tiled are rectangles by default, so there is no specific
documentation on the tmx-map-format page for it.)
"""
@attr.s(auto_attribs=True, kw_only=True)
class Text(TiledObject):
"""Text object with associated settings.
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#text
and https://doc.mapeditor.org/en/stable/manual/objects/#insert-text
Attributes:
font_family: The font family used (default: "sans-serif")
font_size: The size of the font in pixels. (default: 16)
wrap: Whether word wrapping is enabled. (default: False)
color: Color of the text. (default: #000000)
bold: Whether the font is bold. (default: False)
italic: Whether the font is italic. (default: False)
underline: Whether the text is underlined. (default: False)
strike_out: Whether the text is striked-out. (default: False)
kerning: Whether kerning should be used while rendering the text. (default:
False)
horizontal_align: Horizontal alignment of the text (default: "left")
vertical_align: Vertical alignment of the text (defalt: "top")
"""
text: str
color: Color = Color(255, 255, 255, 255)
font_family: str = "sans-serif"
font_size: float = 16
bold: bool = False
italic: bool = False
kerning: bool = True
strike_out: bool = False
underline: bool = False
horizontal_align: str = "left"
vertical_align: str = "top"
wrap: bool = False
@attr.s(auto_attribs=True, kw_only=True)
class Tile(TiledObject):
"""Tile object
See: https://doc.mapeditor.org/en/stable/manual/objects/#insert-tile
Attributes:
gid: Reference to a global tile id.
"""
gid: int
class RawTextDict(TypedDict):
""" The keys and their types that appear in a Text JSON Object."""
text: str
color: str
fontfamily: str
pixelsize: float # this is `font_size` in Text
bold: bool
italic: bool
strikeout: bool
underline: bool
kerning: bool
halign: str
valign: str
wrap: bool
class RawTiledObject(TypedDict):
""" The keys and their types that appear in a Tiled JSON Object."""
id: int
gid: int
x: float
y: float
width: float
height: float
rotation: float
visible: bool
name: str
type: str
properties: List[properties_.RawProperty]
ellipse: bool
point: bool
polygon: List[Dict[str, float]]
polyline: List[Dict[str, float]]
text: Dict[str, Union[float, str]]
RawTiledObjects = List[RawTiledObject]
def _get_common_attributes(raw_tiled_object: RawTiledObject) -> TiledObject:
"""Create a TiledObject containing all the attributes common to all tiled objects
Args:
raw_tiled_object: Raw Tiled object get common attributes from
Returns:
TiledObject: The attributes in common of all Tiled Objects
"""
common_attributes = TiledObject(
id=raw_tiled_object["id"],
coordinates=OrderedPair(raw_tiled_object["x"], raw_tiled_object["y"]),
visible=raw_tiled_object["visible"],
size=Size(raw_tiled_object["width"], raw_tiled_object["height"]),
rotation=raw_tiled_object["rotation"],
name=raw_tiled_object["name"],
type=raw_tiled_object["type"],
)
if raw_tiled_object.get("properties") is not None:
common_attributes.properties = properties_.cast(raw_tiled_object["properties"])
return common_attributes
def _cast_ellipse(raw_tiled_object: RawTiledObject) -> Ellipse:
"""Cast the raw_tiled_object to an Ellipse object.
Args:
raw_tiled_object: Raw Tiled object to be casted to an Ellipse
Returns:
Ellipse: The Ellipse object created from the raw_tiled_object
"""
return Ellipse(**_get_common_attributes(raw_tiled_object).__dict__)
def _cast_rectangle(raw_tiled_object: RawTiledObject) -> Rectangle:
"""Cast the raw_tiled_object to a Rectangle object.
Args:
raw_tiled_object: Raw Tiled object to be casted to a Rectangle
Returns:
Rectangle: The Rectangle object created from the raw_tiled_object
"""
return Rectangle(**_get_common_attributes(raw_tiled_object).__dict__)
def _cast_point(raw_tiled_object: RawTiledObject) -> Point:
"""Cast the raw_tiled_object to a Point object.
Args:
raw_tiled_object: Raw Tiled object to be casted to a Point
Returns:
Point: The Point object created from the raw_tiled_object
"""
return Point(**_get_common_attributes(raw_tiled_object).__dict__)
def _cast_tile(raw_tiled_object: RawTiledObject) -> Tile:
"""Cast the raw_tiled_object to a Tile object.
Args:
raw_tiled_object: Raw Tiled object to be casted to a Tile
Returns:
Tile: The Tile object created from the raw_tiled_object
"""
gid = raw_tiled_object["gid"]
return Tile(gid=gid, **_get_common_attributes(raw_tiled_object).__dict__)
def _cast_polygon(raw_tiled_object: RawTiledObject) -> Polygon:
"""Cast the raw_tiled_object to a Polygon object.
Args:
raw_tiled_object: Raw Tiled object to be casted to a Polygon
Returns:
Polygon: The Polygon object created from the raw_tiled_object
"""
polygon = []
for point in raw_tiled_object["polygon"]:
polygon.append(OrderedPair(point["x"], point["y"]))
return Polygon(points=polygon, **_get_common_attributes(raw_tiled_object).__dict__)
def _cast_polyline(raw_tiled_object: RawTiledObject) -> Polyline:
"""Cast the raw_tiled_object to a Polyline object.
Args:
raw_tiled_object: Raw Tiled Object to be casted to a Polyline
Returns:
Polyline: The Polyline object created from the raw_tiled_object
"""
polyline = []
for point in raw_tiled_object["polyline"]:
polyline.append(OrderedPair(point["x"], point["y"]))
return Polyline(
points=polyline, **_get_common_attributes(raw_tiled_object).__dict__
)
def _cast_text(raw_tiled_object: RawTiledObject) -> Text:
"""Cast the raw_tiled_object to a Text object.
Args:
raw_tiled_object: Raw Tiled object to be casted to a Text object
Returns:
Text: The Text object created from the raw_tiled_object
"""
# required attributes
raw_text_dict: RawTextDict = raw_tiled_object["text"]
text = raw_text_dict["text"]
# create base Text object
text_object = Text(text=text, **_get_common_attributes(raw_tiled_object).__dict__)
# optional attributes
if raw_text_dict.get("color") is not None:
text_object.color = parse_color(raw_text_dict["color"])
if raw_text_dict.get("fontfamily") is not None:
text_object.font_family = raw_text_dict["fontfamily"]
if raw_text_dict.get("pixelsize") is not None:
text_object.font_size = raw_text_dict["pixelsize"]
if raw_text_dict.get("bold") is not None:
text_object.bold = raw_text_dict["bold"]
if raw_text_dict.get("italic") is not None:
text_object.italic = raw_text_dict["italic"]
if raw_text_dict.get("kerning") is not None:
text_object.kerning = raw_text_dict["kerning"]
if raw_text_dict.get("strikeout") is not None:
text_object.strike_out = raw_text_dict["strikeout"]
if raw_text_dict.get("underline") is not None:
text_object.underline = raw_text_dict["underline"]
if raw_text_dict.get("halign") is not None:
text_object.horizontal_align = raw_text_dict["halign"]
if raw_text_dict.get("valign") is not None:
text_object.vertical_align = raw_text_dict["valign"]
if raw_text_dict.get("wrap") is not None:
text_object.wrap = raw_text_dict["wrap"]
return text_object
def _get_caster(
raw_tiled_object: RawTiledObject,
) -> Callable[[RawTiledObject], TiledObject]:
"""Get the caster function for the raw tiled object.
Args:
raw_tiled_object: Raw Tiled object that is analysed to determine which caster
to return.
Returns:
Callable[[RawTiledObject], TiledObject]: The caster function.
"""
if raw_tiled_object.get("ellipse"):
return _cast_ellipse
if raw_tiled_object.get("point"):
return _cast_point
if raw_tiled_object.get("gid"):
# Only Tile objects have the `gid` key (I think)
return _cast_tile
if raw_tiled_object.get("polygon"):
return _cast_polygon
if raw_tiled_object.get("polyline"):
return _cast_polyline
if raw_tiled_object.get("text"):
return _cast_text
return _cast_rectangle
def cast(raw_tiled_object: RawTiledObject) -> TiledObject:
"""Cast the raw tiled object into a pytiled_parser type
Args:
raw_tiled_object: Raw Tiled object that is to be cast.
Returns:
TiledObject: a properly typed Tiled object.
"""
caster = _get_caster(raw_tiled_object)
tiled_object = caster(raw_tiled_object)
return tiled_object

424
pytiled_parser/tileset.py Normal file
View File

@@ -0,0 +1,424 @@
# pylint: disable=too-few-public-methods
from pathlib import Path
from typing import Dict, List, NamedTuple, Optional
import attr
from typing_extensions import TypedDict
from . import layer
from . import properties as properties_
from .common_types import Color, OrderedPair
from .util import parse_color
class Grid(NamedTuple):
"""Contains info for isometric maps.
This element is only used in case of isometric orientation, and determines how tile
overlays for terrain and collision information are rendered.
Args:
orientation: Orientation of the grid for the tiles in this tileset (orthogonal
or isometric).
width: Width of a grid cell.
height: Height of a grid cell.
"""
orientation: str
width: int
height: int
class Terrain(NamedTuple):
"""Terrain object.
Args:
name: The name of the terrain type.
tile: The local tile-id of the tile that represents the terrain visually.
"""
name: str
tile: int
properties: Optional[properties_.Properties] = None
@attr.s(auto_attribs=True)
class TileTerrain:
"""Defines each corner of a tile by Terrain index in
'TileSet.terrain_types'.
Defaults to 'None'. 'None' means that corner has no terrain.
Attributes:
top_left: Top left terrain type.
top_right: Top right terrain type.
bottom_left: Bottom left terrain type.
bottom_right: Bottom right terrain type.
"""
top_left: Optional[int] = None
top_right: Optional[int] = None
bottom_left: Optional[int] = None
bottom_right: Optional[int] = None
class Frame(NamedTuple):
"""Animation Frame object.
This is only used as a part of an animation for Tile objects.
Args:
tile_id: The local ID of a tile within the parent tile set object.
duration: How long in milliseconds this frame should be displayed before
advancing to the next frame.
"""
tile_id: int
duration: int
@attr.s(auto_attribs=True, kw_only=True)
class Tile:
# FIXME: args
"""Individual tile object.
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#tile
Args:
id: The local tile ID within its tileset.
type: The type of the tile. Refers to an object type and is used by tile
objects.
terrain: Defines the terrain type of each corner of the tile.
animation: Each tile can have exactly one animation associated with it.
"""
id: int
opacity: int = 1
type: Optional[str] = None
terrain: Optional[TileTerrain] = None
animation: Optional[List[Frame]] = None
objects: Optional[layer.Layer] = None
image: Optional[Path] = None
image_width: Optional[int] = None
image_height: Optional[int] = None
properties: Optional[properties_.Properties] = None
tileset: Optional["Tileset"] = None
flipped_horizontally: bool = False
flipped_diagonally: bool = False
flipped_vertically: bool = False
@attr.s(auto_attribs=True)
class Tileset:
"""Object for storing a TSX with all associated collision data.
Args:
name: The name of this tileset.
max_tile_size: The maximum size of a tile in this tile set in pixels.
spacing: The spacing in pixels between the tiles in this tileset (applies to
the tileset image).
margin: The margin around the tiles in this tileset (applies to the tileset
image).
tile_count: The number of tiles in this tileset.
columns: The number of tile columns in the tileset. For image collection
tilesets it is editable and is used when displaying the tileset.
grid: Only used in case of isometric orientation, and determines how tile
overlays for terrain and collision information are rendered.
tileoffset: Used to specify an offset in pixels when drawing a tile from the
tileset. When not present, no offset is applied.
image: Used for spritesheet tile sets.
terrain_types: List of of terrain types which can be referenced from the
terrain attribute of the tile object. Ordered according to the terrain
element's appearance in the TSX file.
tiles: Dict of Tile objects by Tile.id.
tsx_file: Path of the file containing the tileset, None if loaded internally
from a map
parent_dir: Path of the parent directory of the file containing the tileset,
None if loaded internally from a map
"""
name: str
tile_width: int
tile_height: int
tile_count: int
columns: int
spacing: int = 0
margin: int = 0
type: Optional[str] = None
tiled_version: Optional[str] = None
version: Optional[float] = None
image: Optional[Path] = None
image_width: Optional[int] = None
image_height: Optional[int] = None
firstgid: Optional[int] = None
background_color: Optional[Color] = None
tile_offset: Optional[OrderedPair] = None
transparent_color: Optional[Color] = None
grid: Optional[Grid] = None
properties: Optional[properties_.Properties] = None
terrain_types: Optional[List[Terrain]] = None
tiles: Optional[Dict[int, Tile]] = None
class RawFrame(TypedDict):
""" The keys and their types that appear in a Frame JSON Object."""
duration: int
tileid: int
class RawTileOffset(TypedDict):
""" The keys and their types that appear in a TileOffset JSON Object."""
x: int
y: int
class RawTerrain(TypedDict):
""" The keys and their types that appear in a Terrain JSON Object."""
name: str
properties: List[properties_.RawProperty]
tile: int
class RawTile(TypedDict):
""" The keys and their types that appear in a Tile JSON Object."""
animation: List[RawFrame]
id: int
image: str
imageheight: int
imagewidth: int
opacity: float
properties: List[properties_.RawProperty]
objectgroup: layer.RawLayer
terrain: List[int]
type: str
class RawGrid(TypedDict):
""" The keys and their types that appear in a Grid JSON Object."""
height: int
width: int
orientation: str
class RawTileSet(TypedDict):
""" The keys and their types that appear in a TileSet JSON Object."""
backgroundcolor: str
columns: int
firstgid: int
grid: RawGrid
image: str
imageheight: int
imagewidth: int
margin: int
name: str
properties: List[properties_.RawProperty]
source: str
spacing: int
terrains: List[RawTerrain]
tilecount: int
tiledversion: str
tileheight: int
tileoffset: RawTileOffset
tiles: List[RawTile]
tilewidth: int
transparentcolor: str
type: str
version: float
def _cast_frame(raw_frame: RawFrame) -> Frame:
"""Cast the raw_frame to a Frame.
Args:
raw_frame: RawFrame to be casted to a Frame
Returns:
Frame: The Frame created from the raw_frame
"""
return Frame(duration=raw_frame["duration"], tile_id=raw_frame["tileid"])
def _cast_tile_offset(raw_tile_offset: RawTileOffset) -> OrderedPair:
"""Cast the raw_tile_offset to an OrderedPair.
Args:
raw_tile_offset: RawTileOffset to be casted to an OrderedPair
Returns:
OrderedPair: The OrderedPair created from the raw_tile_offset
"""
return OrderedPair(raw_tile_offset["x"], raw_tile_offset["y"])
def _cast_terrain(raw_terrain: RawTerrain) -> Terrain:
"""Cast the raw_terrain to a Terrain object.
Args:
raw_terrain: RawTerrain to be casted to a Terrain
Returns:
Terrain: The Terrain created from the raw_terrain
"""
if raw_terrain.get("properties") is not None:
return Terrain(
name=raw_terrain["name"],
tile=raw_terrain["tile"],
properties=properties_.cast(raw_terrain["properties"]),
)
else:
return Terrain(
name=raw_terrain["name"],
tile=raw_terrain["tile"],
)
def _cast_tile(raw_tile: RawTile) -> Tile:
"""Cast the raw_tile to a Tile object.
Args:
raw_tile: RawTile to be casted to a Tile
Returns:
Tile: The Tile created from the raw_tile
"""
id_ = raw_tile["id"]
tile = Tile(id=id_)
if raw_tile.get("animation") is not None:
tile.animation = []
for frame in raw_tile["animation"]:
tile.animation.append(_cast_frame(frame))
if raw_tile.get("objectgroup") is not None:
tile.objects = layer.cast(raw_tile["objectgroup"])
if raw_tile.get("properties") is not None:
tile.properties = properties_.cast(raw_tile["properties"])
if raw_tile.get("image") is not None:
tile.image = Path(raw_tile["image"])
if raw_tile.get("imagewidth") is not None:
tile.image_width = raw_tile["imagewidth"]
if raw_tile.get("imageheight") is not None:
tile.image_height = raw_tile["imageheight"]
if raw_tile.get("terrain") is not None:
raw_terrain = raw_tile["terrain"]
terrain = TileTerrain(
top_left=raw_terrain[0],
top_right=raw_terrain[1],
bottom_left=raw_terrain[2],
bottom_right=raw_terrain[3],
)
tile.terrain = terrain
if raw_tile.get("type") is not None:
tile.type = raw_tile["type"]
return tile
def _cast_grid(raw_grid: RawGrid) -> Grid:
"""Cast the raw_grid to a Grid object.
Args:
raw_grid: RawGrid to be casted to a Grid
Returns:
Grid: The Grid created from the raw_grid
"""
return Grid(
orientation=raw_grid["orientation"],
width=raw_grid["width"],
height=raw_grid["height"],
)
def cast(raw_tileset: RawTileSet) -> Tileset:
"""Cast the raw tileset into a pytiled_parser type
Args:
raw_tileset: Raw Tileset to be cast.
Returns:
TileSet: a properly typed TileSet.
"""
tileset = Tileset(
name=raw_tileset["name"],
tile_count=raw_tileset["tilecount"],
tile_width=raw_tileset["tilewidth"],
tile_height=raw_tileset["tileheight"],
columns=raw_tileset["columns"],
spacing=raw_tileset["spacing"],
margin=raw_tileset["margin"],
)
if raw_tileset.get("type") is not None:
tileset.type = raw_tileset["type"]
if raw_tileset.get("version") is not None:
tileset.version = raw_tileset["version"]
if raw_tileset.get("tiledversion") is not None:
tileset.tiled_version = raw_tileset["tiledversion"]
if raw_tileset.get("image") is not None:
tileset.image = Path(raw_tileset["image"])
if raw_tileset.get("imagewidth") is not None:
tileset.image_width = raw_tileset["imagewidth"]
if raw_tileset.get("imageheight") is not None:
tileset.image_height = raw_tileset["imageheight"]
if raw_tileset.get("firstgid") is not None:
tileset.firstgid = raw_tileset["firstgid"]
if raw_tileset.get("backgroundcolor") is not None:
tileset.background_color = parse_color(raw_tileset["backgroundcolor"])
if raw_tileset.get("tileoffset") is not None:
tileset.tile_offset = _cast_tile_offset(raw_tileset["tileoffset"])
if raw_tileset.get("transparentcolor") is not None:
tileset.transparent_color = parse_color(raw_tileset["transparentcolor"])
if raw_tileset.get("grid") is not None:
tileset.grid = _cast_grid(raw_tileset["grid"])
if raw_tileset.get("properties") is not None:
tileset.properties = properties_.cast(raw_tileset["properties"])
if raw_tileset.get("terrains") is not None:
terrains = []
for raw_terrain in raw_tileset["terrains"]:
terrains.append(_cast_terrain(raw_terrain))
tileset.terrain_types = terrains
if raw_tileset.get("tiles") is not None:
tiles = {}
for raw_tile in raw_tileset["tiles"]:
tiles[raw_tile["id"]] = _cast_tile(raw_tile)
tileset.tiles = tiles
return tileset

29
pytiled_parser/util.py Normal file
View File

@@ -0,0 +1,29 @@
"""Utility Functions for PyTiled"""
from pytiled_parser.common_types import Color
def parse_color(color: str) -> Color:
"""Convert Tiled color format into PyTiled's.
Args:
color (str): Tiled formatted color string.
Returns:
:Color: Color object in the format that PyTiled understands.
"""
# the actual part we care about is always an even number
if len(color) % 2:
# strip initial '#' character
color = color[1:]
if len(color) == 6:
# full opacity if no alpha specified
return Color(int(color[0:2], 16), int(color[2:4], 16), int(color[4:6], 16), 255)
elif len(color) == 8:
return Color(
int(color[0:2], 16),
int(color[2:4], 16),
int(color[4:6], 16),
int(color[6:8], 16),
)
raise ValueError("Improperly formatted color passed to parse_color")

View File

@@ -0,0 +1,3 @@
"""pytiled_parser version"""
__version__ = "1.0.0"

View File

@@ -0,0 +1,57 @@
from typing import List, NamedTuple, Optional
import attr
from typing_extensions import TypedDict
from . import properties as properties_
from .common_types import Color, OrderedPair
class WangTile(NamedTuple):
id: int
dflip: bool = False
hflip: bool = False
vflip: bool = False
wang_ids: List[int] = []
class WangColor(NamedTuple):
color: Color
name: str
probability: float
tile: int
class WangSet(NamedTuple):
cornercolors: List[WangColor]
edgecolors: List[WangColor]
name: str
tile: int
wang_tiles: List[WangTile]
properties: Optional[properties_.Properties] = None
class RawWangTile(TypedDict):
""" The keys and their types that appear in a Wang Tile JSON Object."""
tileid: int
dflip: bool
hflip: bool
vflip: bool
wangid: List[int]
class RawWangColor(TypedDict):
""" The keys and their types that appear in a Wang Color JSON Object."""
color: str
name: str
probability: float
tile: int
class RawWangSet(TypedDict):
""" The keys and their types that appear in a Wang Set JSON Object."""

View File

@@ -1,9 +1,6 @@
[metadata]
name = pytiled_parser
description = PongWall Server Prototype
version = 0.9.1
author = Benjamin Kirkbride
author-email = BenjaminKirkbride@gmail.com
description = A library for parsing JSON formatted Tiled Map Editor maps and tilesets.
license = MIT
license-file = LICENSE
url = https://github.com/Beefy-Swain/pytiled_parser
@@ -21,21 +18,47 @@ classifiers =
Topic :: Software Development :: Libraries :: Python Modules
[options]
packages = find:
include_package_data = True
python_requires = >=3.6
setup_requires =
setuptools >= 40.6
pip >= 10
install_requires =
attrs
typing-extensions
[options.packages.find]
include =
pytiled_parser
pytiled_parser.*
[options.extras_require]
tests =
dev =
pytest
pytest-cov
black
pylint
mypy
isort
isort<5,>=4.2.5
build =
pep517
docs =
sphinx
sphinx_rtd_theme
[build_sphinx]
source-dir = docs
build-dir = docs/build
all_files = 1
[upload-sphinx]
upload-dir = docs/build/html
[bdist_wheel]
universal=0
[coverage:run]
branch = True
@@ -59,10 +82,10 @@ warn_redundant_casts = True
# Per-module options:
[mypy-pytiled_parser.*]
disallow_any_unimported = False
disallow_any_unimported = True
disallow_any_decorated = True
disallow_any_generics = True
disallow_subclassing_any = False
disallow_subclassing_any = True
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_incomplete_defs = True

View File

@@ -1,4 +1,6 @@
# pylint: disable-all
# type: ignore
from setuptools import setup
setup()
exec(open("pytiled_parser/version.py").read())
setup(version=__version__)

View File

@@ -1 +0,0 @@
../../../the_decay_factor_assets/the-decay-factor---assets/assets/

View File

@@ -1,69 +0,0 @@
import os
import arcade
import arcade.tiled
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SPRITE_SCALING = 1
GRAVITY = 1.1
class BasicTestWindow(arcade.Window):
def __init__(self, width, height, title, map_name):
super().__init__(width, height, title)
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)
self.layers = []
my_map = arcade.tiled.read_tiled_map(map_name, 1)
for layer in my_map.layers:
self.layers.append(
arcade.tiled.generate_sprites(
my_map, layer, 1, "../arcade/arcade/examples/"
)
)
def on_draw(self):
arcade.start_render()
for layer in self.layers:
layer.draw()
class CollisionTestWindow(BasicTestWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.frame_count = 0
self.player_list = arcade.SpriteList()
self.player_sprite = arcade.Sprite(
"../arcade/arcade/examples/images/character.png", SPRITE_SCALING
)
self.player_sprite.center_x = 400
self.player_sprite.center_y = 800
self.player_list.append(self.player_sprite)
self.physics_engine = arcade.PhysicsEnginePlatformer(
self.player_sprite, self.layers[0], gravity_constant=GRAVITY
)
def on_draw(self):
super().on_draw()
self.frame_count += 1
self.player_list.draw()
if self.frame_count == 20:
print(self.player_sprite.center_x, self.player_sprite.center_y)
def update(self, delta_time):
self.physics_engine.update()
window = CollisionTestWindow(
SCREEN_WIDTH,
SCREEN_HEIGHT,
"Test Text",
"../arcade/arcade/examples/map_polyline_collision.tmx",
)
arcade.run()

View File

@@ -1 +0,0 @@
MAP_NAME = "assets/tiled_test_4.tmx"

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +0,0 @@
import arcade
import config
from arcade.tiled import read_tiled_map
class MyTestWindow(arcade.Window):
def __init__(self, width, height, title):
super().__init__(width, height, title)
self.map = arcade.generate_sprites(my_map, "Tile Layer 1", 1, "./assets/")
def on_draw(self):
arcade.start_render()
self.map.draw()
MAP_NAME = "assets/tiled_test_4.tmx"
my_map = arcade.read_tiled_map(config.MAP_NAME, 1)
for row in my_map.layers["Tile Layer 1"]:
for grid_object in row:
print(grid_object)
print(
f"{grid_object.tile.local_id}, {grid_object.center_x}, {grid_object.center_y}"
)
test = MyTestWindow(640, 800, "meme")
test.test()
test.close()

View File

@@ -1,22 +0,0 @@
import attr
@attr.s(auto_attribs=True, kw_only=True)
class Foo:
x: int
y: int
a: int = 5
@attr.s(auto_attribs=True, kw_only=True)
class Bar(Foo):
z: int
foo = Foo(x=1, y=2)
bar = Bar(x=1, y=2, z=3)
print(foo)
print(bar)

View File

@@ -1,178 +0,0 @@
{
"parent_dir": PosixPath(
"/home/ben/Projects/pytiled_parser/pytiled_parser-venv/pytiled_parser/tests/test_data"
),
"version": "1.2",
"tiled_version": "1.2.3",
"orientation": "orthogonal",
"render_order": "right-down",
"map_size": Size(width=8, height=6),
"tile_size": Size(width=32, height=32),
"infinite": False,
"next_layer_id": 2,
"next_object_id": 1,
"tile_sets": {
1: TileSet(
name="tile_set_image",
max_tile_size=Size(width=32, height=32),
spacing=1,
margin=1,
tile_count=48,
columns=8,
tile_offset=None,
grid=None,
properties=None,
image=Image(
source="images/tmw_desert_spacing.png",
size=Size(width=265, height=199),
trans=None,
),
terrain_types=None,
tiles={
9: Tile(
id=9,
type=None,
terrain=None,
animation=None,
image=None,
hitboxes=[
TiledObject(
id=2,
location=OrderedPair(x=1.0, y=1.0),
size=Size(width=32.0, height=32.0),
rotation=1,
opacity=1,
name="wall",
type="rectangle type",
properties=None,
template=None,
)
],
),
19: Tile(
id=19,
type=None,
terrain=None,
animation=None,
image=None,
hitboxes=[
TiledObject(
id=1,
location=OrderedPair(x=32.0, y=1.0),
size=Size(width=0, height=0),
rotation=1,
opacity=1,
name="wall corner",
type="polygon type",
properties=None,
template=None,
)
],
),
20: Tile(
id=20,
type=None,
terrain=None,
animation=None,
image=None,
hitboxes=[
TiledObject(
id=1,
location=OrderedPair(x=1.45455, y=1.45455),
size=Size(width=0, height=0),
rotation=1,
opacity=1,
name="polyline",
type="polyline type",
properties=None,
template=None,
)
],
),
31: Tile(
id=31,
type=None,
terrain=None,
animation=None,
image=None,
hitboxes=[
TiledObject(
id=1,
location=OrderedPair(x=5.09091, y=2.54545),
size=Size(width=19.6364, height=19.2727),
rotation=1,
opacity=1,
name="rock 1",
type="elipse type",
properties=None,
template=None,
),
TiledObject(
id=2,
location=OrderedPair(x=16.1818, y=22.0),
size=Size(width=8.54545, height=8.36364),
rotation=-1,
opacity=1,
name="rock 2",
type="elipse type",
properties=None,
template=None,
),
],
),
45: Tile(
id=45,
type=None,
terrain=None,
animation=None,
image=None,
hitboxes=[
TiledObject(
id=1,
location=OrderedPair(x=14.7273, y=26.3636),
size=Size(width=0, height=0),
rotation=0,
opacity=1,
name="sign",
type="point type",
properties=None,
template=None,
)
],
),
},
)
},
"layers": [
TileLayer(
id=1,
name="Tile Layer 1",
offset=None,
opacity=None,
properties=None,
size=Size(width=8, height=6),
data=[
[1, 2, 3, 4, 5, 6, 7, 8],
[9, 10, 11, 12, 13, 14, 15, 16],
[17, 18, 19, 20, 21, 22, 23, 24],
[25, 26, 27, 28, 29, 30, 31, 32],
[33, 34, 35, 36, 37, 38, 39, 40],
[41, 42, 43, 44, 45, 46, 47, 48],
],
)
],
"hex_side_length": None,
"stagger_axis": None,
"stagger_index": None,
"background_color": None,
"properties": {
"bool property - false": False,
"bool property - true": True,
"color property": "#ff49fcff",
"file property": PosixPath("../../../../../../../../var/log/syslog"),
"float property": 1.23456789,
"int property": 13,
"string property": "Hello, World!!",
},
}
e

View File

@@ -1,32 +0,0 @@
import arcade
import arcade.tiled
import pprint
pp = pprint.PrettyPrinter(indent=4, compact=True, width=200)
class MyTestWindow(arcade.Window):
def __init__(self, width, height, title, map_name):
super().__init__(width, height, title)
self.layers = []
my_map = arcade.tiled.read_tiled_map(map_name, 1)
pp.pprint(my_map.layers_int_data)
for layer in my_map.layers_int_data:
self.layers.append(
arcade.tiled.generate_sprites(
my_map, layer, 1, "../arcade/arcade/examples/"
)
)
def on_draw(self):
arcade.start_render()
for layer in self.layers:
layer.draw()
MAP_NAME = "../arcade/arcade/examples/map_base64_gzip.tmx"
test = MyTestWindow(640, 800, "meme", MAP_NAME)
arcade.run()

View File

@@ -1,11 +0,0 @@
import pickle
import pprint
from io import StringIO
import pytiled_parser
MAP_NAME = "/home/ben/Projects/pytiled_parser/pytiled_parser-venv/pytiled_parser/tests/test_data/test_map_simple_hitboxes.tmx"
map = pytiled_parser.parse_tile_map(MAP_NAME)
print(map.__dict__)

View File

@@ -0,0 +1,649 @@
{
"compressionlevel": 0,
"editorsettings": {
"export": {
"target": "."
}
},
"height": 6,
"infinite": false,
"layers": [
{
"data": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48
],
"height": 6,
"id": 1,
"name": "Tile Layer 1",
"opacity": 1,
"type": "tilelayer",
"visible": true,
"width": 8,
"x": 0,
"y": 0
},
{
"draworder": "topdown",
"id": 2,
"name": "Object Layer 1",
"objects": [
{
"height": 41.4686825053996,
"id": 1,
"name": "name: rectangle",
"rotation": 0,
"type": "rectangle",
"visible": true,
"width": 45.3972945322269,
"x": 27.7185404115039,
"y": 23.571672160964
},
{
"height": 0,
"id": 2,
"name": "name: point",
"point": true,
"rotation": 0,
"type": "point",
"visible": true,
"width": 0,
"x": 159.981811981357,
"y": 82.9373650107991
},
{
"height": 0,
"id": 3,
"name": "name: point invisible",
"point": true,
"rotation": 0,
"type": "point",
"visible": false,
"width": 0,
"x": 109.346368080027,
"y": 95.8144822098443
},
{
"height": 32.7384335568944,
"id": 4,
"name": "name: rectangle - invisible",
"rotation": 0,
"type": "rectangle",
"visible": false,
"width": 30.9923837671934,
"x": 163.910424008185,
"y": 91.0128452881664
},
{
"height": 22,
"id": 5,
"name": "name: rectangle - rotated",
"rotation": 10,
"type": "rectangle",
"visible": true,
"width": 10,
"x": 183.335227918609,
"y": 23.3534159372513
},
{
"ellipse": true,
"height": 18.5517790155735,
"id": 6,
"name": "name: ellipse",
"rotation": 0,
"type": "ellipse",
"visible": true,
"width": 57.4013868364215,
"x": 37.5400704785722,
"y": 81.1913152210981
},
{
"ellipse": true,
"height": 31.4288962146186,
"id": 7,
"name": "name: ellipse - invisible",
"rotation": 0,
"type": "ellipse",
"visible": false,
"width": 6.32943048766625,
"x": 22.6986472661134,
"y": 53.9092872570194
},
{
"ellipse": true,
"height": 24.2264408321018,
"id": 8,
"name": "name: ellipse - rotated",
"rotation": 111,
"type": "ellipse",
"visible": true,
"width": 29.6828464249176,
"x": 35.7940206888712,
"y": 120.040923041946
},
{
"height": 0,
"id": 9,
"name": "name: polygon",
"polygon": [
{
"x": 0,
"y": 0
},
{
"x": 19.424803910424,
"y": 27.063771740366
},
{
"x": 19.6430601341366,
"y": 3.05558713197681
},
{
"x": -2.61907468455156,
"y": 15.9327043310219
},
{
"x": 25.317721950665,
"y": 16.3692167784472
}
],
"rotation": 0,
"type": "polygon",
"visible": true,
"width": 0,
"x": 89.485051722178,
"y": 38.6313515971354
},
{
"height": 0,
"id": 10,
"name": "name: polygon - invisible",
"polygon": [
{
"x": 0,
"y": 0
},
{
"x": -12.8771171990451,
"y": 7.63896782994203
},
{
"x": -14.8414232124588,
"y": -10.2580425144936
}
],
"rotation": 0,
"type": "polygon",
"visible": false,
"width": 0,
"x": 133.791065135842,
"y": 24.4446970558145
},
{
"height": 0,
"id": 11,
"name": "name: polygon - rotated",
"polygon": [
{
"x": 0,
"y": 0
},
{
"x": -12.8771171990451,
"y": 0
},
{
"x": -6.98419915880413,
"y": 7.63896782994203
},
{
"x": -13.9683983176083,
"y": 16.8057292258725
},
{
"x": 3.71035580311468,
"y": 15.277935659884
},
{
"x": -3.71035580311471,
"y": 8.29373650107991
}
],
"rotation": 123,
"type": "polygon",
"visible": true,
"width": 0,
"x": 152.779356598841,
"y": 19.8613163578493
},
{
"height": 0,
"id": 12,
"name": "name: polyline",
"polyline": [
{
"x": 0,
"y": 0
},
{
"x": -13.3136296464704,
"y": 41.0321700579743
},
{
"x": 21.3891099238377,
"y": 16.8057292258725
}
],
"rotation": 0,
"type": "polyline",
"visible": true,
"width": 0,
"x": 124.187791292486,
"y": 90.1398203933159
},
{
"height": 0,
"id": 31,
"name": "name: polyline - invisible",
"polyline": [
{
"x": 0,
"y": 0
},
{
"x": -9,
"y": 20.3333333333333
},
{
"x": 5,
"y": 23.6666666666667
}
],
"rotation": 0,
"type": "polyline",
"visible": false,
"width": 0,
"x": 140,
"y": 163.333333333333
},
{
"height": 0,
"id": 32,
"name": "name: polyline - rotated",
"polyline": [
{
"x": 0,
"y": 0
},
{
"x": 10.3333333333333,
"y": 13
},
{
"x": -5.33333333333331,
"y": 19.6666666666667
}
],
"rotation": 0,
"type": "polyline",
"visible": true,
"width": 0,
"x": 192.333333333333,
"y": 128.666666666667
},
{
"gid": 79,
"height": 32,
"id": 13,
"name": "name: tile",
"rotation": 0,
"type": "tile",
"visible": true,
"width": 32,
"x": 111.898147095601,
"y": 48.3019211094691
},
{
"gid": 80,
"height": 32,
"id": 14,
"name": "name: tile - invisible",
"rotation": 0,
"type": "tile",
"visible": false,
"width": 32,
"x": 41.1831306127089,
"y": 168.779356598841
},
{
"gid": 2147483742,
"height": 32,
"id": 15,
"name": "name: tile - horizontal flipped",
"rotation": 0,
"type": "tile",
"visible": true,
"width": 32,
"x": 197.236330567239,
"y": 59.8695009662385
},
{
"gid": 1073741918,
"height": 32,
"id": 16,
"name": "name: tile - vertical flipped",
"rotation": 0,
"type": "tile",
"visible": true,
"width": 32,
"x": 32.4528816642037,
"y": 60.742525861089
},
{
"gid": 3221225558,
"height": 32,
"id": 17,
"name": "name: tile - both flipped",
"rotation": 0,
"type": "tile",
"visible": true,
"width": 32,
"x": 167.553484142321,
"y": 95.6635216551097
},
{
"gid": 86,
"height": 32,
"id": 18,
"name": "name: tile - rotated",
"rotation": 89,
"type": "tile",
"visible": true,
"width": 32,
"x": 85.65,
"y": 142.62
},
{
"height": 19,
"id": 19,
"name": "name: text",
"rotation": 0,
"text": {
"text": "Hello World",
"wrap": true
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 81.7106470956008,
"y": 93.2986813686484
},
{
"height": 19,
"id": 20,
"name": "name: text - invisible",
"rotation": 0,
"text": {
"text": "Hello World",
"wrap": true
},
"type": "text",
"visible": false,
"width": 92.375,
"x": 8.37655592815732,
"y": 112.068716607935
},
{
"height": 19,
"id": 21,
"name": "name: text - rotated",
"rotation": 19,
"text": {
"text": "Hello World",
"wrap": true
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 157.882069171308,
"y": 78.4572581561896
},
{
"height": 19,
"id": 22,
"name": "name: text - different font",
"rotation": 0,
"text": {
"bold": true,
"fontfamily": "DejaVu Sans",
"pixelsize": 19,
"text": "Hello World",
"wrap": true
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 2.70189411162896,
"y": 101.592417869728
},
{
"height": 19,
"id": 23,
"name": "name: text - no word wrap",
"rotation": 0,
"text": {
"text": "Hello World"
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 9.90434949414573,
"y": 154.192167784472
},
{
"height": 19,
"id": 24,
"name": "name: text - right bottom align",
"rotation": 0,
"text": {
"halign": "right",
"text": "Hello World",
"valign": "bottom",
"wrap": true
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 151.989151131067,
"y": 1.19455496191883
},
{
"height": 19,
"id": 25,
"name": "text: center center align",
"rotation": 0,
"text": {
"halign": "center",
"text": "Hello World",
"valign": "center",
"wrap": true
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 4.22968767761736,
"y": 3.81362964647039
},
{
"height": 19,
"id": 26,
"name": "name: text - justified",
"rotation": 0,
"text": {
"halign": "justify",
"text": "Hello World",
"wrap": true
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 13.8329615209731,
"y": 60.7785040354666
},
{
"height": 19,
"id": 27,
"name": "name: text - red",
"rotation": 0,
"text": {
"color": "#aa0000",
"text": "Hello World",
"wrap": true
},
"type": "text",
"visible": true,
"width": 92.375,
"x": 96.3338140843469,
"y": 130.620495623508
},
{
"height": 0,
"id": 28,
"name": "name: rectangle - no width or height",
"rotation": 0,
"type": "rectangle",
"visible": true,
"width": 0,
"x": 131.17199045129,
"y": 53.4727748095942
},
{
"ellipse": true,
"height": 0,
"id": 29,
"name": "name: ellipse - no width or height",
"rotation": 0,
"type": "ellipse",
"visible": true,
"width": 0,
"x": 72.4610662725929,
"y": 127.679890871888
},
{
"height": 13.7501420938956,
"id": 30,
"name": "name: rectangle - properties",
"properties": [
{
"name": "bool property",
"type": "bool",
"value": false
},
{
"name": "color property",
"type": "color",
"value": "#ffaa0000"
},
{
"name": "file property",
"type": "file",
"value": "../../../../../../dev/null"
},
{
"name": "float property",
"type": "float",
"value": 42.1
},
{
"name": "int property",
"type": "int",
"value": 8675309
},
{
"name": "string property",
"type": "string",
"value": "pytiled_parser rulez!1!!"
}
],
"rotation": 0,
"type": "rectangle",
"visible": true,
"width": 21.170853700125,
"x": 39.0678640445606,
"y": 131.826759122428
}
],
"opacity": 1,
"type": "objectgroup",
"visible": true,
"x": 0,
"y": 0
}
],
"nextlayerid": 3,
"nextobjectid": 33,
"orientation": "orthogonal",
"renderorder": "right-down",
"tiledversion": "1.3.5",
"tileheight": 32,
"tilesets": [
{
"firstgid": 1,
"source": "tileset_image_objects.json"
},
{
"firstgid": 49,
"source": "tileset_image.json"
}
],
"tilewidth": 32,
"type": "map",
"version": 1.2,
"width": 8
}

View File

@@ -0,0 +1,14 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.1",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,192 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":5,
"tiledversion":"1.3.1",
"tileheight":32,
"tiles":[
{
"id":9,
"objectgroup":
{
"draworder":"index",
"name":"",
"objects":[
{
"height":32,
"id":2,
"name":"wall",
"rotation":1,
"type":"rectangle type",
"visible":true,
"width":32,
"x":1,
"y":1
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}
},
{
"id":19,
"objectgroup":
{
"draworder":"index",
"name":"",
"objects":[
{
"height":0,
"id":1,
"name":"wall corner",
"polygon":[
{
"x":0,
"y":0
},
{
"x":-32,
"y":0
},
{
"x":-32,
"y":32
},
{
"x":-16,
"y":32.1818
},
{
"x":-15.8182,
"y":16.9091
},
{
"x":0.181818,
"y":17.0909
}],
"rotation":1,
"type":"polygon type",
"visible":true,
"width":0,
"x":32,
"y":1
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}
},
{
"id":20,
"objectgroup":
{
"draworder":"index",
"name":"",
"objects":[
{
"height":0,
"id":1,
"name":"polyline",
"polyline":[
{
"x":0,
"y":0
},
{
"x":25.0909,
"y":21.2727
},
{
"x":9.63636,
"y":28.3636
}],
"rotation":1,
"type":"polyline type",
"visible":true,
"width":0,
"x":1.45455,
"y":1.45455
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}
},
{
"id":31,
"objectgroup":
{
"draworder":"index",
"name":"",
"objects":[
{
"ellipse":true,
"height":19.2727,
"id":1,
"name":"rock 1",
"rotation":1,
"type":"elipse type",
"visible":true,
"width":19.6364,
"x":5.09091,
"y":2.54545
},
{
"ellipse":true,
"height":8.36364,
"id":2,
"name":"rock 2",
"rotation":-1,
"type":"elipse type",
"visible":true,
"width":8.54545,
"x":16.1818,
"y":22
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}
},
{
"id":45,
"objectgroup":
{
"draworder":"index",
"name":"",
"objects":[
{
"height":0,
"id":1,
"name":"sign",
"point":true,
"rotation":0,
"type":"point type",
"visible":true,
"width":0,
"x":14.7273,
"y":26.3636
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}
}],
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,68 @@
{ "compressionlevel":0,
"height":6,
"infinite":false,
"layers":[
{
"data":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48],
"height":6,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":8,
"x":0,
"y":0
}],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"orthogonal",
"properties":[
{
"name":"bool property - false",
"type":"bool",
"value":false
},
{
"name":"bool property - true",
"type":"bool",
"value":true
},
{
"name":"color property",
"type":"color",
"value":"#ff49fcff"
},
{
"name":"file property",
"type":"file",
"value":"..\/..\/..\/..\/..\/..\/var\/log\/syslog"
},
{
"name":"float property",
"type":"float",
"value":1.23456789
},
{
"name":"int property",
"type":"int",
"value":13
},
{
"name":"string property",
"type":"string",
"value":"Hello, World!!"
}],
"renderorder":"right-down",
"tiledversion":"1.3.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset_image.json"
}],
"tilewidth":32,
"type":"map",
"version":1.2,
"width":8
}

View File

@@ -0,0 +1,14 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.1",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,195 @@
{ "compressionlevel":0,
"height":6,
"infinite":true,
"layers":[
{
"chunks":[
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":-32,
"y":-32
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":-16,
"y":-32
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":0,
"y":-32
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":16,
"y":-32
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":-32,
"y":-16
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 1, 2, 3, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 9, 10, 11, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 17, 18, 19],
"height":16,
"width":16,
"x":-16,
"y":-16
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 4, 5, 6, 7, 8, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 12, 13, 14, 15, 16, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 20, 21, 22, 23, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":0,
"y":-16
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":16,
"y":-16
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":-32,
"y":0
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 25, 26, 27, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 33, 34, 35, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 41, 42, 43, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":-16,
"y":0
},
{
"data":[28, 29, 30, 31, 32, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 36, 37, 38, 39, 40, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 44, 45, 46, 47, 48, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":0,
"y":0
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":16,
"y":0
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":-32,
"y":16
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":-16,
"y":16
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":0,
"y":16
},
{
"data":[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
"height":16,
"width":16,
"x":16,
"y":16
}],
"height":64,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"startx":-32,
"starty":-32,
"type":"tilelayer",
"visible":true,
"width":64,
"x":0,
"y":0
},
{
"chunks":[
{
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"height":16,
"width":16,
"x":-32,
"y":-16
},
{
"data":[0, 0, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"height":16,
"width":16,
"x":16,
"y":-16
},
{
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"height":16,
"width":16,
"x":-16,
"y":0
},
{
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"height":16,
"width":16,
"x":16,
"y":0
},
{
"data":[28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"height":16,
"width":16,
"x":-16,
"y":16
}],
"height":48,
"id":2,
"name":"Tile Layer 2",
"opacity":1,
"startx":-32,
"starty":-16,
"type":"tilelayer",
"visible":true,
"width":64,
"x":0,
"y":0
}],
"nextlayerid":3,
"nextobjectid":1,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.3.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset_image.json"
}],
"tilewidth":32,
"type":"map",
"version":1.2,
"width":8
}

View File

@@ -0,0 +1,14 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.1",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,80 @@
{ "compressionlevel":0,
"height":6,
"infinite":false,
"layers":[
{
"data":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48],
"height":6,
"id":1,
"name":"Tile Layer 1",
"offsetx":16,
"offsety":-16.42,
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":8,
"x":0,
"y":0
}],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"orthogonal",
"properties":[
{
"name":"bool property - false",
"type":"bool",
"value":false
},
{
"name":"bool property - true",
"type":"bool",
"value":true
},
{
"name":"color property",
"type":"color",
"value":"#ff49fcff"
},
{
"name":"empty file",
"type":"file",
"value":""
},
{
"name":"empty string",
"type":"string",
"value":""
},
{
"name":"file_property",
"type":"file",
"value":"test_map_simple_offset.json"
},
{
"name":"float property",
"type":"float",
"value":1.23456789
},
{
"name":"int property",
"type":"int",
"value":13
},
{
"name":"string property",
"type":"string",
"value":"Hello, World!!"
}],
"renderorder":"right-down",
"tiledversion":"1.3.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset_image.json"
}],
"tilewidth":32,
"type":"map",
"version":1.2,
"width":8
}

View File

@@ -0,0 +1,14 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.1",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,120 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_object
EXPECTED = [
layer.TileLayer(
name="Tile Layer 1",
opacity=1,
visible=True,
id=1,
size=common_types.Size(8, 6),
offset=common_types.OrderedPair(1, 3),
properties={
"test": "test property",
},
data=[
[
1,
2,
3,
4,
5,
6,
7,
8,
],
[
9,
10,
11,
12,
13,
14,
15,
16,
],
[
17,
18,
19,
20,
21,
22,
23,
24,
],
[
25,
26,
27,
28,
29,
30,
31,
32,
],
[
33,
34,
35,
36,
37,
38,
39,
40,
],
[
41,
42,
43,
44,
45,
46,
47,
48,
],
],
),
layer.LayerGroup(
name="Group 1",
opacity=1,
visible=True,
id=4,
layers=[
layer.ObjectLayer(
name="Object Layer 1",
opacity=1,
visible=True,
id=2,
draw_order="topdown",
tiled_objects=[
tiled_object.Rectangle(
id=1,
name="",
rotation=0,
size=common_types.Size(69.3333333333333, 52.6666666666667),
coordinates=common_types.OrderedPair(46.3333333333333, 39),
visible=True,
type="",
)
],
),
],
),
layer.ImageLayer(
name="Image Layer 1",
opacity=1,
visible=True,
id=3,
image=Path("../../images/tile_04.png"),
transparent_color=common_types.Color(0, 0, 0, 255),
),
layer.ImageLayer(
name="Image Layer 2",
opacity=1,
visible=True,
id=5,
image=Path("../../images/tile_04.png"),
),
]

View File

@@ -0,0 +1,93 @@
{ "compressionlevel":-1,
"height":6,
"infinite":false,
"layers":[
{
"data":[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48],
"height":6,
"id":1,
"name":"Tile Layer 1",
"offsetx":1,
"offsety":3,
"opacity":1,
"properties":[
{
"name":"test",
"type":"string",
"value":"test property"
}],
"type":"tilelayer",
"visible":true,
"width":8,
"x":0,
"y":0
},
{
"id":4,
"layers":[
{
"draworder":"topdown",
"id":2,
"name":"Object Layer 1",
"objects":[
{
"height":52.6666666666667,
"id":1,
"name":"",
"rotation":0,
"type":"",
"visible":true,
"width":69.3333333333333,
"x":46.3333333333333,
"y":39
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}],
"name":"Group 1",
"opacity":1,
"type":"group",
"visible":true,
"x":0,
"y":0
},
{
"id":3,
"image":"..\/..\/images\/tile_04.png",
"name":"Image Layer 1",
"opacity":1,
"transparentcolor":"#000000",
"type":"imagelayer",
"visible":true,
"x":0,
"y":0
},
{
"id":5,
"image":"..\/..\/images\/tile_04.png",
"name":"Image Layer 2",
"opacity":1,
"type":"imagelayer",
"visible":true,
"x":0,
"y":0
}],
"nextlayerid":6,
"nextobjectid":3,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,22 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,109 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_object
EXPECTED = [
layer.TileLayer(
name="Tile Layer 1",
opacity=1,
visible=True,
id=1,
size=common_types.Size(8, 6),
data=[
[
1,
2,
3,
4,
5,
6,
7,
8,
],
[
9,
10,
11,
12,
13,
14,
15,
16,
],
[
17,
18,
19,
20,
21,
22,
23,
24,
],
[
25,
26,
27,
28,
29,
30,
31,
32,
],
[
33,
34,
35,
36,
37,
38,
39,
40,
],
[
41,
42,
43,
44,
45,
46,
47,
48,
],
],
),
layer.LayerGroup(
name="Group 1",
opacity=1,
visible=True,
id=4,
layers=[
layer.ObjectLayer(
name="Object Layer 1",
opacity=1,
visible=True,
id=2,
draw_order="topdown",
tiled_objects=[
tiled_object.Rectangle(
id=1,
name="",
rotation=0,
size=common_types.Size(69.3333333333333, 52.6666666666667),
coordinates=common_types.OrderedPair(46.3333333333333, 39),
visible=True,
type="",
)
],
),
],
),
layer.ImageLayer(
name="Image Layer 1",
opacity=1,
visible=True,
id=3,
image=Path("../../images/tile_04.png"),
transparent_color=common_types.Color(0, 0, 0, 255),
),
]

View File

@@ -0,0 +1,77 @@
{ "compressionlevel":-1,
"height":6,
"infinite":false,
"layers":[
{
"compression":"",
"data":"AQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAeAAAAHwAAACAAAAAhAAAAIgAAACMAAAAkAAAAJQAAACYAAAAnAAAAKAAAACkAAAAqAAAAKwAAACwAAAAtAAAALgAAAC8AAAAwAAAA",
"encoding":"base64",
"height":6,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":8,
"x":0,
"y":0
},
{
"id":4,
"layers":[
{
"draworder":"topdown",
"id":2,
"name":"Object Layer 1",
"objects":[
{
"height":52.6666666666667,
"id":1,
"name":"",
"rotation":0,
"type":"",
"visible":true,
"width":69.3333333333333,
"x":46.3333333333333,
"y":39
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}],
"name":"Group 1",
"opacity":1,
"type":"group",
"visible":true,
"x":0,
"y":0
},
{
"id":3,
"image":"..\/..\/images\/tile_04.png",
"name":"Image Layer 1",
"opacity":1,
"transparentcolor":"#000000",
"type":"imagelayer",
"visible":true,
"x":0,
"y":0
}],
"nextlayerid":5,
"nextobjectid":3,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"..\/all_layer_types\/tileset.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,22 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,109 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_object
EXPECTED = [
layer.TileLayer(
name="Tile Layer 1",
opacity=1,
visible=True,
id=1,
size=common_types.Size(8, 6),
data=[
[
1,
2,
3,
4,
5,
6,
7,
8,
],
[
9,
10,
11,
12,
13,
14,
15,
16,
],
[
17,
18,
19,
20,
21,
22,
23,
24,
],
[
25,
26,
27,
28,
29,
30,
31,
32,
],
[
33,
34,
35,
36,
37,
38,
39,
40,
],
[
41,
42,
43,
44,
45,
46,
47,
48,
],
],
),
layer.LayerGroup(
name="Group 1",
opacity=1,
visible=True,
id=4,
layers=[
layer.ObjectLayer(
name="Object Layer 1",
opacity=1,
visible=True,
id=2,
draw_order="topdown",
tiled_objects=[
tiled_object.Rectangle(
id=1,
name="",
rotation=0,
size=common_types.Size(69.3333333333333, 52.6666666666667),
coordinates=common_types.OrderedPair(46.3333333333333, 39),
visible=True,
type="",
)
],
),
],
),
layer.ImageLayer(
name="Image Layer 1",
opacity=1,
visible=True,
id=3,
image=Path("../../images/tile_04.png"),
transparent_color=common_types.Color(0, 0, 0, 255),
),
]

View File

@@ -0,0 +1,77 @@
{ "compressionlevel":-1,
"height":6,
"infinite":false,
"layers":[
{
"compression":"gzip",
"data":"H4sIAAAAAAAAAw3DBRKCQAAAwDMRA7BQLMTE9v+vY3dmWyGEth279uwbOTB26MixExNTM6fOnLtwae7KtYUbt+7ce7D0aOXJsxev3rxb+\/Dpy7cfv\/782wAcvDirwAAAAA==",
"encoding":"base64",
"height":6,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":8,
"x":0,
"y":0
},
{
"id":4,
"layers":[
{
"draworder":"topdown",
"id":2,
"name":"Object Layer 1",
"objects":[
{
"height":52.6666666666667,
"id":1,
"name":"",
"rotation":0,
"type":"",
"visible":true,
"width":69.3333333333333,
"x":46.3333333333333,
"y":39
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}],
"name":"Group 1",
"opacity":1,
"type":"group",
"visible":true,
"x":0,
"y":0
},
{
"id":3,
"image":"..\/..\/images\/tile_04.png",
"name":"Image Layer 1",
"opacity":1,
"transparentcolor":"#000000",
"type":"imagelayer",
"visible":true,
"x":0,
"y":0
}],
"nextlayerid":5,
"nextobjectid":3,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"..\/all_layer_types\/tileset.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,22 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,109 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_object
EXPECTED = [
layer.TileLayer(
name="Tile Layer 1",
opacity=1,
visible=True,
id=1,
size=common_types.Size(8, 6),
data=[
[
1,
2,
3,
4,
5,
6,
7,
8,
],
[
9,
10,
11,
12,
13,
14,
15,
16,
],
[
17,
18,
19,
20,
21,
22,
23,
24,
],
[
25,
26,
27,
28,
29,
30,
31,
32,
],
[
33,
34,
35,
36,
37,
38,
39,
40,
],
[
41,
42,
43,
44,
45,
46,
47,
48,
],
],
),
layer.LayerGroup(
name="Group 1",
opacity=1,
visible=True,
id=4,
layers=[
layer.ObjectLayer(
name="Object Layer 1",
opacity=1,
visible=True,
id=2,
draw_order="topdown",
tiled_objects=[
tiled_object.Rectangle(
id=1,
name="",
rotation=0,
size=common_types.Size(69.3333333333333, 52.6666666666667),
coordinates=common_types.OrderedPair(46.3333333333333, 39),
visible=True,
type="",
)
],
),
],
),
layer.ImageLayer(
name="Image Layer 1",
opacity=1,
visible=True,
id=3,
image=Path("../../images/tile_04.png"),
transparent_color=common_types.Color(0, 0, 0, 255),
),
]

View File

@@ -0,0 +1,77 @@
{ "compressionlevel":-1,
"height":6,
"infinite":false,
"layers":[
{
"compression":"zlib",
"data":"eJwNwwUSgkAAAMAzEQOwUCzExPb\/r2N3ZlshhLYdu\/bsGzkwdujIsRMTUzOnzpy7cGnuyrWFG7fu3Huw9GjlybMXr968W\/vw6cu3H7\/+\/NsAMw8EmQ==",
"encoding":"base64",
"height":6,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":8,
"x":0,
"y":0
},
{
"id":4,
"layers":[
{
"draworder":"topdown",
"id":2,
"name":"Object Layer 1",
"objects":[
{
"height":52.6666666666667,
"id":1,
"name":"",
"rotation":0,
"type":"",
"visible":true,
"width":69.3333333333333,
"x":46.3333333333333,
"y":39
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
}],
"name":"Group 1",
"opacity":1,
"type":"group",
"visible":true,
"x":0,
"y":0
},
{
"id":3,
"image":"..\/..\/images\/tile_04.png",
"name":"Image Layer 1",
"opacity":1,
"transparentcolor":"#000000",
"type":"imagelayer",
"visible":true,
"x":0,
"y":0
}],
"nextlayerid":5,
"nextobjectid":3,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"..\/all_layer_types\/tileset.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,22 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,127 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_object
EXPECTED = [
layer.TileLayer(
name="Tile Layer 1",
opacity=1,
visible=True,
id=1,
size=common_types.Size(16, 16),
offset=common_types.OrderedPair(163.089434111595, 116.462603878116),
properties={
"test": "test property",
},
chunks=[
layer.Chunk(
coordinates=common_types.OrderedPair(0, 0),
size=common_types.Size(4, 8),
data=[
[
1,
2,
3,
4,
],
[
9,
10,
11,
12,
],
[
17,
18,
19,
20,
],
[
25,
26,
27,
28,
],
[
33,
34,
35,
36,
],
[
41,
42,
43,
44,
],
[
0,
0,
0,
0,
],
[
0,
0,
0,
0,
],
],
),
layer.Chunk(
coordinates=common_types.OrderedPair(4, 0),
size=common_types.Size(4, 8),
data=[
[
5,
6,
7,
8,
],
[
13,
14,
15,
16,
],
[
21,
22,
23,
24,
],
[
29,
30,
31,
32,
],
[
37,
38,
39,
40,
],
[
45,
46,
47,
48,
],
[
0,
0,
0,
0,
],
[
0,
0,
0,
0,
],
],
),
],
)
]

View File

@@ -0,0 +1,68 @@
{ "compressionlevel":-1,
"editorsettings":
{
"chunksize":
{
"height":8,
"width":4
},
"export":
{
"target":"..\/all_layer_types"
}
},
"height":6,
"infinite":true,
"layers":[
{
"chunks":[
{
"data":[1, 2, 3, 4, 9, 10, 11, 12, 17, 18, 19, 20, 25, 26, 27, 28, 33, 34, 35, 36, 41, 42, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0],
"height":8,
"width":4,
"x":0,
"y":0
},
{
"data":[5, 6, 7, 8, 13, 14, 15, 16, 21, 22, 23, 24, 29, 30, 31, 32, 37, 38, 39, 40, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0],
"height":8,
"width":4,
"x":4,
"y":0
}],
"height":16,
"id":1,
"name":"Tile Layer 1",
"offsetx":163.089434111595,
"offsety":116.462603878116,
"opacity":1,
"properties":[
{
"name":"test",
"type":"string",
"value":"test property"
}],
"startx":0,
"starty":0,
"type":"tilelayer",
"visible":true,
"width":16,
"x":0,
"y":0
}],
"nextlayerid":6,
"nextobjectid":3,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"..\/all_layer_types\/tileset.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,41 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_object
EXPECTED = [
layer.TileLayer(
name="Tile Layer 1",
opacity=1,
visible=True,
id=1,
size=common_types.Size(16, 16),
offset=common_types.OrderedPair(1, 3),
properties={
"test": "test property",
},
chunks=[
layer.Chunk(
coordinates=common_types.OrderedPair(0, 0),
size=common_types.Size(16, 16),
data=[
[1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0],
[9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0],
[17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0],
[25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0],
[33, 34, 35, 36, 37, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0],
[41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
],
)
],
)
]

View File

@@ -0,0 +1,51 @@
{ "compressionlevel":-1,
"height":6,
"infinite":true,
"layers":[
{
"chunks":[
{
"data":"AQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAeAAAAHwAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJgAAACcAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApAAAAKgAAACsAAAAsAAAALQAAAC4AAAAvAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"height":16,
"width":16,
"x":0,
"y":0
}],
"compression":"",
"encoding":"base64",
"height":16,
"id":1,
"name":"Tile Layer 1",
"offsetx":1,
"offsety":3,
"opacity":1,
"properties":[
{
"name":"test",
"type":"string",
"value":"test property"
}],
"startx":0,
"starty":0,
"type":"tilelayer",
"visible":true,
"width":16,
"x":0,
"y":0
}],
"nextlayerid":6,
"nextobjectid":3,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"..\/all_layer_types\/tileset.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,5 @@
from typing import List
from pytiled_parser import layer
EXPECTED: List[layer.Layer] = []

View File

@@ -0,0 +1,63 @@
{ "compressionlevel":0,
"editorsettings":
{
"export":
{
"target":"."
}
},
"height":6,
"infinite":false,
"layers":[],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"orthogonal",
"properties":[
{
"name":"bool property - false",
"type":"bool",
"value":false
},
{
"name":"bool property - true",
"type":"bool",
"value":true
},
{
"name":"color property",
"type":"color",
"value":"#ff49fcff"
},
{
"name":"file property",
"type":"file",
"value":"..\/..\/..\/..\/..\/..\/var\/log\/syslog"
},
{
"name":"float property",
"type":"float",
"value":1.23456789
},
{
"name":"int property",
"type":"int",
"value":13
},
{
"name":"string property",
"type":"string",
"value":"Hello, World!!"
}],
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset_image.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,14 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.1",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,31 @@
from pathlib import Path
from pytiled_parser import common_types, tiled_map, tileset
EXPECTED = tiled_map.TiledMap(
infinite=False,
layers=[],
map_size=common_types.Size(8, 6),
next_layer_id=2,
next_object_id=1,
orientation="orthogonal",
render_order="right-down",
tiled_version="1.4.1",
tile_size=common_types.Size(32, 32),
version=1.4,
tilesets={
1: tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_width=265,
image_height=199,
margin=1,
spacing=1,
name="tileset",
tile_count=48,
tile_height=32,
tile_width=32,
firstgid=1,
)
},
)

View File

@@ -0,0 +1,36 @@
{ "compressionlevel":0,
"editorsettings":
{
"export":
{
"target":"."
}
},
"height":6,
"infinite":false,
"layers":[],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"columns":8,
"firstgid":1,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tileset",
"spacing":1,
"tilecount":48,
"tileheight":32,
"tilewidth":32
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,156 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_map, tileset
EXPECTED = tiled_map.TiledMap(
hex_side_length=6,
stagger_axis="y",
stagger_index="odd",
infinite=False,
layers=[
layer.TileLayer(
name="Tile Layer 1",
opacity=1,
visible=True,
size=common_types.Size(10, 10),
id=1,
data=[
[
3,
3,
3,
3,
9,
9,
9,
9,
17,
17,
],
[
3,
3,
3,
9,
9,
9,
9,
17,
17,
17,
],
[
3,
3,
3,
9,
9,
9,
9,
9,
17,
17,
],
[3, 3, 1, 7, 9, 9, 9, 15, 17, 17],
[
1,
1,
12,
5,
7,
7,
7,
15,
15,
15,
],
[
12,
1,
5,
5,
7,
7,
7,
15,
15,
15,
],
[
2,
2,
5,
5,
5,
5,
4,
14,
14,
14,
],
[
2,
2,
5,
5,
5,
4,
14,
14,
14,
14,
],
[
2,
2,
2,
5,
5,
5,
4,
14,
14,
14,
],
[
2,
2,
2,
2,
5,
5,
4,
4,
14,
14,
],
],
)
],
map_size=common_types.Size(10, 10),
next_layer_id=2,
next_object_id=1,
orientation="hexagonal",
render_order="right-down",
tiled_version="1.4.1",
tile_size=common_types.Size(14, 12),
version=1.4,
tilesets={
1: tileset.Tileset(
columns=5,
image=Path("../../images/hexmini.png"),
image_width=106,
image_height=72,
margin=0,
spacing=0,
name="tileset",
tile_count=20,
tiled_version="1.4.1",
tile_height=18,
tile_width=18,
version=1.4,
type="tileset",
tile_offset=common_types.OrderedPair(0, 1),
)
},
)

View File

@@ -0,0 +1,35 @@
{ "compressionlevel":-1,
"height":10,
"hexsidelength":6,
"infinite":false,
"layers":[
{
"data":[3, 3, 3, 3, 9, 9, 9, 9, 17, 17, 3, 3, 3, 9, 9, 9, 9, 17, 17, 17, 3, 3, 3, 9, 9, 9, 9, 9, 17, 17, 3, 3, 1, 7, 9, 9, 9, 15, 17, 17, 1, 1, 12, 5, 7, 7, 7, 15, 15, 15, 12, 1, 5, 5, 7, 7, 7, 15, 15, 15, 2, 2, 5, 5, 5, 5, 4, 14, 14, 14, 2, 2, 5, 5, 5, 4, 14, 14, 14, 14, 2, 2, 2, 5, 5, 5, 4, 14, 14, 14, 2, 2, 2, 2, 5, 5, 4, 4, 14, 14],
"height":10,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":10,
"x":0,
"y":0
}],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"hexagonal",
"renderorder":"right-down",
"staggeraxis":"y",
"staggerindex":"odd",
"tiledversion":"1.4.1",
"tileheight":12,
"tilesets":[
{
"firstgid":1,
"source":"tileset.json"
}],
"tilewidth":14,
"type":"map",
"version":1.4,
"width":10
}

View File

@@ -0,0 +1,19 @@
{ "columns":5,
"image":"..\/..\/images\/hexmini.png",
"imageheight":72,
"imagewidth":106,
"margin":0,
"name":"tileset",
"spacing":0,
"tilecount":20,
"tiledversion":"1.4.1",
"tileheight":18,
"tileoffset":
{
"x":0,
"y":1
},
"tilewidth":18,
"type":"tileset",
"version":1.4
}

View File

@@ -0,0 +1,33 @@
from pathlib import Path
from pytiled_parser import common_types, tiled_map, tileset
EXPECTED = tiled_map.TiledMap(
infinite=False,
layers=[],
map_size=common_types.Size(8, 6),
next_layer_id=2,
next_object_id=1,
orientation="orthogonal",
render_order="right-down",
tiled_version="1.4.1",
tile_size=common_types.Size(32, 32),
version=1.4,
tilesets={
1: tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_width=265,
image_height=199,
margin=1,
spacing=1,
name="tile_set_image",
tile_count=48,
tiled_version="1.3.1",
tile_height=32,
tile_width=32,
version=1.2,
type="tileset",
)
},
)

View File

@@ -0,0 +1,27 @@
{ "compressionlevel":0,
"editorsettings":
{
"export":
{
"target":"."
}
},
"height":6,
"infinite":false,
"layers":[],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset_image.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,14 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.1",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,42 @@
from pathlib import Path
from pytiled_parser import common_types, tiled_map, tileset
EXPECTED = tiled_map.TiledMap(
infinite=False,
layers=[],
map_size=common_types.Size(8, 6),
next_layer_id=2,
next_object_id=1,
orientation="orthogonal",
render_order="right-down",
tiled_version="1.4.1",
tile_size=common_types.Size(32, 32),
version=1.4,
background_color=common_types.Color(255, 0, 4, 255),
tilesets={
1: tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_width=265,
image_height=199,
margin=1,
spacing=1,
name="tile_set_image",
tile_count=48,
tiled_version="1.3.1",
tile_height=32,
tile_width=32,
version=1.2,
type="tileset",
)
},
properties={
"bool property - true": True,
"color property": common_types.Color(255, 73, 252, 255),
"file property": Path("../../../../../../var/log/syslog"),
"float property": 1.23456789,
"int property": 13,
"string property": "Hello, World!!",
},
)

View File

@@ -0,0 +1,59 @@
{ "backgroundcolor":"#ff0004",
"compressionlevel":0,
"editorsettings":
{
"export":
{
"target":"."
}
},
"height":6,
"infinite":false,
"layers":[],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"orthogonal",
"properties":[
{
"name":"bool property - true",
"type":"bool",
"value":true
},
{
"name":"color property",
"type":"color",
"value":"#ff49fcff"
},
{
"name":"file property",
"type":"file",
"value":"..\/..\/..\/..\/..\/..\/var\/log\/syslog"
},
{
"name":"float property",
"type":"float",
"value":1.23456789
},
{
"name":"int property",
"type":"int",
"value":13
},
{
"name":"string property",
"type":"string",
"value":"Hello, World!!"
}],
"renderorder":"right-down",
"tiledversion":"1.4.1",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset_image.json"
}],
"tilewidth":32,
"type":"map",
"version":1.4,
"width":8
}

View File

@@ -0,0 +1,14 @@
{ "columns":8,
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.1",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,18 @@
import pytest
from pytiled_parser.util import parse_color
def test_parse_color_wrong_format():
with pytest.raises(ValueError):
color = parse_color("#ff0000ff0")
def test_parse_color_no_hash():
color = parse_color("ff0000")
assert color == (255, 0, 0, 255)
def test_parse_color_no_alpha():
color = parse_color("#ff0000")
assert color == (255, 0, 0, 255)

View File

@@ -0,0 +1,19 @@
from pathlib import Path
from pytiled_parser import tileset
EXPECTED = tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_height=199,
image_width=265,
margin=1,
spacing=1,
name="tile_set_image",
tile_count=48,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
type="tileset",
)

View File

@@ -0,0 +1,22 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,21 @@
from pathlib import Path
from pytiled_parser import tileset
from pytiled_parser.common_types import Color
EXPECTED = tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_height=199,
image_width=265,
margin=1,
spacing=1,
name="tile_set_image",
tile_count=48,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
background_color=Color(85, 0, 255, 255),
type="tileset",
)

View File

@@ -0,0 +1,23 @@
{ "backgroundcolor":"#5500ff",
"columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,20 @@
from pathlib import Path
from pytiled_parser import tileset
EXPECTED = tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_height=199,
image_width=265,
margin=1,
spacing=1,
name="tile_set_image",
tile_count=48,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
grid=tileset.Grid(orientation="isometric", width=32, height=32),
type="tileset",
)

View File

@@ -0,0 +1,26 @@
{
"columns": 8,
"editorsettings": {
"export": {
"format": "",
"target": "../image"
}
},
"grid": {
"height": 32,
"orientation": "isometric",
"width": 32
},
"image": "../../images/tmw_desert_spacing.png",
"imageheight": 199,
"imagewidth": 265,
"margin": 1,
"name": "tile_set_image",
"spacing": 1,
"tilecount": 48,
"tiledversion": "1.3.5",
"tileheight": 32,
"tilewidth": 32,
"type": "tileset",
"version": 1.2
}

View File

@@ -0,0 +1,27 @@
from pathlib import Path
from pytiled_parser import tileset
from pytiled_parser.common_types import Color
EXPECTED = tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_height=199,
image_width=265,
margin=1,
spacing=1,
name="tile_set_image",
tile_count=48,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
properties={
"bool property": True,
"color property": Color(255, 0, 0, 255),
"float property": 5.6,
"int property": 5,
"string property": "testing",
},
type="tileset",
)

View File

@@ -0,0 +1,48 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"..\/image"
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"properties":[
{
"name":"bool property",
"type":"bool",
"value":true
},
{
"name":"color property",
"type":"color",
"value":"#ff0000ff"
},
{
"name":"float property",
"type":"float",
"value":5.6
},
{
"name":"int property",
"type":"int",
"value":5
},
{
"name":"string property",
"type":"string",
"value":"testing"
}],
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,21 @@
from pathlib import Path
from pytiled_parser import tileset
from pytiled_parser.common_types import Color, OrderedPair
EXPECTED = tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_height=199,
image_width=265,
margin=1,
spacing=1,
name="tile_set_image",
tile_count=48,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
tile_offset=OrderedPair(3, 5),
type="tileset",
)

View File

@@ -0,0 +1,27 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"..\/image"
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tile_set_image",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tileoffset":
{
"x":3,
"y":5
},
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,21 @@
from pathlib import Path
from pytiled_parser import tileset
from pytiled_parser.common_types import Color
EXPECTED = tileset.Tileset(
columns=8,
image=Path("../../images/tmw_desert_spacing.png"),
image_height=199,
image_width=265,
margin=1,
spacing=1,
name="tileset",
tile_count=48,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
transparent_color=Color(255, 0, 255, 255),
type="tileset",
)

View File

@@ -0,0 +1,23 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tileset",
"spacing":1,
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"transparentcolor":"#ff00ff",
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,86 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tiled_object, tileset
EXPECTED = tileset.Tileset(
columns=0,
margin=0,
spacing=0,
name="tileset",
tile_count=4,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
type="tileset",
grid=tileset.Grid(orientation="orthogonal", width=1, height=1),
tiles={
0: tileset.Tile(
animation=[
tileset.Frame(duration=100, tile_id=0),
tileset.Frame(duration=100, tile_id=1),
tileset.Frame(duration=100, tile_id=2),
tileset.Frame(duration=100, tile_id=3),
],
id=0,
image=Path("../../images/tile_01.png"),
image_height=32,
image_width=32,
properties={"float property": 2.2},
type="tile",
),
1: tileset.Tile(
id=1,
image=Path("../../images/tile_02.png"),
image_height=32,
image_width=32,
objects=layer.ObjectLayer(
name="",
opacity=1,
visible=True,
draw_order="index",
tiled_objects=[
tiled_object.Rectangle(
id=2,
name="",
size=common_types.Size(14.4766410408043, 13.7196924896511),
rotation=0,
type="",
visible=True,
coordinates=common_types.OrderedPair(
13.4358367829687, 13.5304553518628
),
),
tiled_object.Ellipse(
id=3,
name="",
size=common_types.Size(14.287403903016, 11.070372560615),
rotation=0,
type="",
visible=True,
coordinates=common_types.OrderedPair(
13.8143110585452, 1.98698994677705
),
),
],
),
properties={"string property": "testing"},
type="tile",
),
2: tileset.Tile(
id=2,
image=Path("../../images/tile_03.png"),
image_height=32,
image_width=32,
properties={"bool property": True},
type="tile",
),
3: tileset.Tile(
id=3,
image=Path("../../images/tile_04.png"),
image_height=32,
image_width=32,
type="tile",
),
},
)

View File

@@ -0,0 +1,123 @@
{ "columns":0,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"grid":
{
"height":1,
"orientation":"orthogonal",
"width":1
},
"margin":0,
"name":"tileset",
"spacing":0,
"tilecount":4,
"tiledversion":"1.3.5",
"tileheight":32,
"tiles":[
{
"animation":[
{
"duration":100,
"tileid":0
},
{
"duration":100,
"tileid":1
},
{
"duration":100,
"tileid":2
},
{
"duration":100,
"tileid":3
}],
"id":0,
"image":"..\/..\/images\/tile_01.png",
"imageheight":32,
"imagewidth":32,
"properties":[
{
"name":"float property",
"type":"float",
"value":2.2
}],
"type":"tile"
},
{
"id":1,
"image":"..\/..\/images\/tile_02.png",
"imageheight":32,
"imagewidth":32,
"objectgroup":
{
"draworder":"index",
"name":"",
"objects":[
{
"height":13.7196924896511,
"id":2,
"name":"",
"rotation":0,
"type":"",
"visible":true,
"width":14.4766410408043,
"x":13.4358367829687,
"y":13.5304553518628
},
{
"ellipse":true,
"height":11.070372560615,
"id":3,
"name":"",
"rotation":0,
"type":"",
"visible":true,
"width":14.287403903016,
"x":13.8143110585452,
"y":1.98698994677705
}],
"opacity":1,
"type":"objectgroup",
"visible":true,
"x":0,
"y":0
},
"properties":[
{
"name":"string property",
"type":"string",
"value":"testing"
}],
"type":"tile"
},
{
"id":2,
"image":"..\/..\/images\/tile_03.png",
"imageheight":32,
"imagewidth":32,
"properties":[
{
"name":"bool property",
"type":"bool",
"value":true
}],
"type":"tile"
},
{
"id":3,
"image":"..\/..\/images\/tile_04.png",
"imageheight":32,
"imagewidth":32,
"type":"tile"
}],
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,271 @@
from pathlib import Path
from pytiled_parser import common_types, layer, tileset
EXPECTED = tileset.Tileset(
columns=8,
margin=1,
spacing=1,
name="tileset",
image=Path("../../images/tmw_desert_spacing.png"),
image_height=199,
image_width=265,
tile_count=48,
tiled_version="1.3.5",
tile_height=32,
tile_width=32,
version=1.2,
type="tileset",
terrain_types=[
tileset.Terrain(
name="Sand",
tile=29,
properties={"terrain property": "test terrain property"},
),
tileset.Terrain(name="Cobblestone", tile=29),
tileset.Terrain(name="Pavement", tile=29),
tileset.Terrain(name="Dirt", tile=29),
],
tiles={
0: tileset.Tile(
id=0,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=0, bottom_right=1
),
),
1: tileset.Tile(
id=1,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=1, bottom_right=1
),
),
2: tileset.Tile(
id=2,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=1, bottom_right=0
),
),
3: tileset.Tile(
id=3,
terrain=tileset.TileTerrain(
top_left=3, top_right=3, bottom_left=3, bottom_right=0
),
),
4: tileset.Tile(
id=4,
terrain=tileset.TileTerrain(
top_left=3, top_right=3, bottom_left=0, bottom_right=3
),
),
5: tileset.Tile(
id=5,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=0, bottom_right=3
),
),
6: tileset.Tile(
id=6,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=3, bottom_right=3
),
),
7: tileset.Tile(
id=7,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=3, bottom_right=0
),
),
8: tileset.Tile(
id=8,
terrain=tileset.TileTerrain(
top_left=0, top_right=1, bottom_left=0, bottom_right=1
),
),
9: tileset.Tile(
id=9,
terrain=tileset.TileTerrain(
top_left=1, top_right=1, bottom_left=1, bottom_right=1
),
),
10: tileset.Tile(
id=10,
terrain=tileset.TileTerrain(
top_left=1, top_right=0, bottom_left=1, bottom_right=0
),
),
11: tileset.Tile(
id=11,
terrain=tileset.TileTerrain(
top_left=3, top_right=0, bottom_left=3, bottom_right=3
),
),
12: tileset.Tile(
id=12,
terrain=tileset.TileTerrain(
top_left=0, top_right=3, bottom_left=3, bottom_right=3
),
),
13: tileset.Tile(
id=13,
terrain=tileset.TileTerrain(
top_left=0, top_right=3, bottom_left=0, bottom_right=3
),
),
14: tileset.Tile(
id=14,
terrain=tileset.TileTerrain(
top_left=3, top_right=3, bottom_left=3, bottom_right=3
),
),
15: tileset.Tile(
id=15,
terrain=tileset.TileTerrain(
top_left=3, top_right=0, bottom_left=3, bottom_right=0
),
),
16: tileset.Tile(
id=16,
terrain=tileset.TileTerrain(
top_left=0, top_right=1, bottom_left=0, bottom_right=0
),
),
17: tileset.Tile(
id=17,
terrain=tileset.TileTerrain(
top_left=1, top_right=1, bottom_left=0, bottom_right=0
),
),
18: tileset.Tile(
id=18,
terrain=tileset.TileTerrain(
top_left=1, top_right=0, bottom_left=0, bottom_right=0
),
),
19: tileset.Tile(
id=19,
terrain=tileset.TileTerrain(
top_left=1, top_right=1, bottom_left=1, bottom_right=0
),
),
20: tileset.Tile(
id=20,
terrain=tileset.TileTerrain(
top_left=1, top_right=1, bottom_left=0, bottom_right=1
),
),
21: tileset.Tile(
id=21,
terrain=tileset.TileTerrain(
top_left=0, top_right=3, bottom_left=0, bottom_right=0
),
),
22: tileset.Tile(
id=22,
terrain=tileset.TileTerrain(
top_left=3, top_right=3, bottom_left=0, bottom_right=0
),
),
23: tileset.Tile(
id=23,
terrain=tileset.TileTerrain(
top_left=3, top_right=0, bottom_left=0, bottom_right=0
),
),
24: tileset.Tile(
id=24,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=0, bottom_right=2
),
),
25: tileset.Tile(
id=25,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=2, bottom_right=2
),
),
26: tileset.Tile(
id=26,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=2, bottom_right=0
),
),
27: tileset.Tile(
id=27,
terrain=tileset.TileTerrain(
top_left=1, top_right=0, bottom_left=1, bottom_right=1
),
),
28: tileset.Tile(
id=28,
terrain=tileset.TileTerrain(
top_left=0, top_right=1, bottom_left=1, bottom_right=1
),
),
29: tileset.Tile(
id=29,
terrain=tileset.TileTerrain(
top_left=0, top_right=0, bottom_left=0, bottom_right=0
),
),
32: tileset.Tile(
id=32,
terrain=tileset.TileTerrain(
top_left=0, top_right=2, bottom_left=0, bottom_right=2
),
),
33: tileset.Tile(
id=33,
terrain=tileset.TileTerrain(
top_left=2, top_right=2, bottom_left=2, bottom_right=2
),
),
34: tileset.Tile(
id=34,
terrain=tileset.TileTerrain(
top_left=2, top_right=0, bottom_left=2, bottom_right=0
),
),
35: tileset.Tile(
id=35,
terrain=tileset.TileTerrain(
top_left=2, top_right=2, bottom_left=2, bottom_right=0
),
),
36: tileset.Tile(
id=36,
terrain=tileset.TileTerrain(
top_left=2, top_right=2, bottom_left=0, bottom_right=2
),
),
40: tileset.Tile(
id=40,
terrain=tileset.TileTerrain(
top_left=0, top_right=2, bottom_left=0, bottom_right=0
),
),
41: tileset.Tile(
id=41,
terrain=tileset.TileTerrain(
top_left=2, top_right=2, bottom_left=0, bottom_right=0
),
),
42: tileset.Tile(
id=42,
terrain=tileset.TileTerrain(
top_left=2, top_right=0, bottom_left=0, bottom_right=0
),
),
43: tileset.Tile(
id=43,
terrain=tileset.TileTerrain(
top_left=2, top_right=0, bottom_left=2, bottom_right=2
),
),
44: tileset.Tile(
id=44,
terrain=tileset.TileTerrain(
top_left=0, top_right=2, bottom_left=2, bottom_right=2
),
),
},
)

View File

@@ -0,0 +1,206 @@
{ "columns":8,
"editorsettings":
{
"export":
{
"format":"",
"target":"."
}
},
"image":"..\/..\/images\/tmw_desert_spacing.png",
"imageheight":199,
"imagewidth":265,
"margin":1,
"name":"tileset",
"spacing":1,
"terrains":[
{
"name":"Sand",
"properties":[
{
"name":"terrain property",
"type":"string",
"value":"test terrain property"
}],
"tile":29
},
{
"name":"Cobblestone",
"tile":29
},
{
"name":"Pavement",
"tile":29
},
{
"name":"Dirt",
"tile":29
}],
"tilecount":48,
"tiledversion":"1.3.5",
"tileheight":32,
"tiles":[
{
"id":0,
"terrain":[0, 0, 0, 1]
},
{
"id":1,
"terrain":[0, 0, 1, 1]
},
{
"id":2,
"terrain":[0, 0, 1, 0]
},
{
"id":3,
"terrain":[3, 3, 3, 0]
},
{
"id":4,
"terrain":[3, 3, 0, 3]
},
{
"id":5,
"terrain":[0, 0, 0, 3]
},
{
"id":6,
"terrain":[0, 0, 3, 3]
},
{
"id":7,
"terrain":[0, 0, 3, 0]
},
{
"id":8,
"terrain":[0, 1, 0, 1]
},
{
"id":9,
"terrain":[1, 1, 1, 1]
},
{
"id":10,
"terrain":[1, 0, 1, 0]
},
{
"id":11,
"terrain":[3, 0, 3, 3]
},
{
"id":12,
"terrain":[0, 3, 3, 3]
},
{
"id":13,
"terrain":[0, 3, 0, 3]
},
{
"id":14,
"terrain":[3, 3, 3, 3]
},
{
"id":15,
"terrain":[3, 0, 3, 0]
},
{
"id":16,
"terrain":[0, 1, 0, 0]
},
{
"id":17,
"terrain":[1, 1, 0, 0]
},
{
"id":18,
"terrain":[1, 0, 0, 0]
},
{
"id":19,
"terrain":[1, 1, 1, 0]
},
{
"id":20,
"terrain":[1, 1, 0, 1]
},
{
"id":21,
"terrain":[0, 3, 0, 0]
},
{
"id":22,
"terrain":[3, 3, 0, 0]
},
{
"id":23,
"terrain":[3, 0, 0, 0]
},
{
"id":24,
"terrain":[0, 0, 0, 2]
},
{
"id":25,
"terrain":[0, 0, 2, 2]
},
{
"id":26,
"terrain":[0, 0, 2, 0]
},
{
"id":27,
"terrain":[1, 0, 1, 1]
},
{
"id":28,
"terrain":[0, 1, 1, 1]
},
{
"id":29,
"terrain":[0, 0, 0, 0]
},
{
"id":32,
"terrain":[0, 2, 0, 2]
},
{
"id":33,
"terrain":[2, 2, 2, 2]
},
{
"id":34,
"terrain":[2, 0, 2, 0]
},
{
"id":35,
"terrain":[2, 2, 2, 0]
},
{
"id":36,
"terrain":[2, 2, 0, 2]
},
{
"id":40,
"terrain":[0, 2, 0, 0]
},
{
"id":41,
"terrain":[2, 2, 0, 0]
},
{
"id":42,
"terrain":[2, 0, 0, 0]
},
{
"id":43,
"terrain":[2, 0, 2, 2]
},
{
"id":44,
"terrain":[0, 2, 2, 2]
}],
"tilewidth":32,
"type":"tileset",
"version":1.2
}

View File

@@ -0,0 +1,32 @@
{ "compressionlevel":-1,
"height":20,
"infinite":false,
"layers":[
{
"data":[35, 1, 57, 49, 48, 67, 75, 7, 61, 52, 70, 44, 81, 55, 59, 63, 10, 68, 63, 81, 22, 23, 72, 60, 61, 52, 79, 26, 72, 60, 53, 54, 54, 72, 60, 34, 22, 77, 60, 52, 59, 64, 75, 70, 61, 71, 78, 71, 46, 29, 30, 35, 33, 53, 63, 42, 35, 9, 69, 58, 55, 74, 5, 9, 28, 2, 77, 54, 55, 39, 25, 25, 26, 63, 63, 78, 25, 26, 54, 72, 65, 50, 45, 27, 24, 26, 1, 66, 61, 7, 70, 62, 72, 33, 34, 52, 70, 70, 70, 8, 48, 34, 7, 62, 60, 67, 23, 54, 64, 23, 46, 32, 73, 21, 25, 70, 80, 78, 7, 43, 71, 42, 13, 56, 66, 7, 31, 59, 6, 62, 63, 18, 46, 30, 31, 48, 80, 54, 42, 53, 79, 7, 16, 62, 54, 19, 11, 59, 42, 35, 36, 42, 61, 16, 43, 71, 51, 34, 4, 59, 76, 41, 37, 30, 61, 70, 13, 57, 80, 18, 15, 53, 36, 42, 52, 7, 70, 25, 13, 29, 79, 53, 6, 44, 64, 77, 42, 70, 80, 24, 22, 68, 24, 52, 70, 26, 54, 55, 39, 26, 54, 60, 17, 1, 5, 6, 80, 51, 76, 56, 65, 75, 34, 58, 5, 28, 56, 59, 51, 70, 61, 67, 14, 18, 24, 16, 49, 59, 81, 36, 9, 51, 26, 69, 40, 20, 32, 64, 66, 52, 33, 76, 21, 22, 68, 19, 59, 55, 50, 10, 21, 70, 70, 8, 51, 71, 18, 54, 78, 70, 42, 8, 60, 70, 4, 30, 31, 30, 31, 38, 32, 54, 46, 38, 57, 80, 24, 70, 53, 1, 53, 24, 58, 48, 43, 17, 18, 24, 43, 52, 22, 59, 33, 80, 63, 54, 33, 49, 59, 15, 35, 72, 33, 67, 75, 17, 42, 35, 1, 29, 68, 72, 42, 52, 61, 61, 26, 63, 36, 45, 45, 54, 42, 53, 73, 23, 73, 21, 44, 42, 76, 48, 76, 57, 62, 60, 70, 58, 23, 78, 48, 67, 75, 61, 79, 61, 52, 61, 79, 53, 54, 55, 75, 70, 34, 70, 7, 58, 66, 52, 33, 53, 51, 61, 8, 72, 60, 31, 74, 57, 70, 67, 3, 79, 22, 47, 12, 62, 51, 31, 43, 58, 68, 63, 15, 76, 65, 23, 54, 63, 6, 8, 19, 74, 57, 62, 24, 35, 60, 43],
"height":20,
"id":1,
"name":"Tile Layer 1",
"opacity":1,
"type":"tilelayer",
"visible":true,
"width":20,
"x":0,
"y":0
}],
"nextlayerid":2,
"nextobjectid":1,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.3.5",
"tileheight":32,
"tilesets":[
{
"firstgid":1,
"source":"tileset.json"
}],
"tilewidth":32,
"type":"map",
"version":1.2,
"width":20
}

View File

@@ -0,0 +1,607 @@
{ "columns":9,
"image":"..\/..\/images\/walkways.png",
"imageheight":288,
"imagewidth":288,
"margin":0,
"name":"tileset",
"spacing":0,
"tilecount":81,
"tiledversion":"1.3.5",
"tileheight":32,
"tilewidth":32,
"type":"tileset",
"version":1.2,
"wangsets":[
{
"cornercolors":[],
"edgecolors":[
{
"color":"#ff0000",
"name":"Path",
"probability":1,
"tile":-1
},
{
"color":"#00ff00",
"name":"Grass",
"probability":0.75,
"tile":-1
},
{
"color":"#0000ff",
"name":"WalkWay",
"probability":0.5,
"tile":-1
}],
"name":"My Wang Set",
"tile":-1,
"wangtiles":[
{
"dflip":false,
"hflip":false,
"tileid":0,
"vflip":false,
"wangid":[2, 0, 3, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":1,
"vflip":false,
"wangid":[2, 0, 3, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":2,
"vflip":false,
"wangid":[2, 0, 1, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":3,
"vflip":false,
"wangid":[2, 0, 3, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":4,
"vflip":false,
"wangid":[2, 0, 2, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":5,
"vflip":false,
"wangid":[2, 0, 1, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":6,
"vflip":false,
"wangid":[2, 0, 1, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":7,
"vflip":false,
"wangid":[2, 0, 2, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":8,
"vflip":false,
"wangid":[2, 0, 2, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":9,
"vflip":false,
"wangid":[3, 0, 3, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":10,
"vflip":false,
"wangid":[3, 0, 3, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":11,
"vflip":false,
"wangid":[3, 0, 1, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":12,
"vflip":false,
"wangid":[3, 0, 3, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":13,
"vflip":false,
"wangid":[3, 0, 2, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":14,
"vflip":false,
"wangid":[3, 0, 1, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":15,
"vflip":false,
"wangid":[3, 0, 1, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":16,
"vflip":false,
"wangid":[3, 0, 2, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":17,
"vflip":false,
"wangid":[3, 0, 2, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":18,
"vflip":false,
"wangid":[3, 0, 3, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":19,
"vflip":false,
"wangid":[3, 0, 3, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":20,
"vflip":false,
"wangid":[3, 0, 1, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":21,
"vflip":false,
"wangid":[3, 0, 3, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":22,
"vflip":false,
"wangid":[3, 0, 2, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":23,
"vflip":false,
"wangid":[3, 0, 1, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":24,
"vflip":false,
"wangid":[3, 0, 1, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":25,
"vflip":false,
"wangid":[3, 0, 2, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":26,
"vflip":false,
"wangid":[3, 0, 2, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":27,
"vflip":false,
"wangid":[1, 0, 3, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":28,
"vflip":false,
"wangid":[1, 0, 3, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":29,
"vflip":false,
"wangid":[1, 0, 1, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":30,
"vflip":false,
"wangid":[1, 0, 3, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":31,
"vflip":false,
"wangid":[1, 0, 2, 0, 3, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":32,
"vflip":false,
"wangid":[1, 0, 1, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":33,
"vflip":false,
"wangid":[1, 0, 1, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":34,
"vflip":false,
"wangid":[1, 0, 2, 0, 3, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":35,
"vflip":false,
"wangid":[1, 0, 2, 0, 3, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":36,
"vflip":false,
"wangid":[3, 0, 3, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":37,
"vflip":false,
"wangid":[3, 0, 3, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":38,
"vflip":false,
"wangid":[3, 0, 1, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":39,
"vflip":false,
"wangid":[3, 0, 3, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":40,
"vflip":false,
"wangid":[3, 0, 2, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":41,
"vflip":false,
"wangid":[3, 0, 1, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":42,
"vflip":false,
"wangid":[3, 0, 1, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":43,
"vflip":false,
"wangid":[3, 0, 2, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":44,
"vflip":false,
"wangid":[3, 0, 2, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":45,
"vflip":false,
"wangid":[2, 0, 3, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":46,
"vflip":false,
"wangid":[2, 0, 3, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":47,
"vflip":false,
"wangid":[2, 0, 1, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":48,
"vflip":false,
"wangid":[2, 0, 3, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":49,
"vflip":false,
"wangid":[2, 0, 2, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":50,
"vflip":false,
"wangid":[2, 0, 1, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":51,
"vflip":false,
"wangid":[2, 0, 1, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":52,
"vflip":false,
"wangid":[2, 0, 2, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":53,
"vflip":false,
"wangid":[2, 0, 2, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":54,
"vflip":false,
"wangid":[1, 0, 3, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":55,
"vflip":false,
"wangid":[1, 0, 3, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":56,
"vflip":false,
"wangid":[1, 0, 1, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":57,
"vflip":false,
"wangid":[1, 0, 3, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":58,
"vflip":false,
"wangid":[1, 0, 2, 0, 1, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":59,
"vflip":false,
"wangid":[1, 0, 1, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":60,
"vflip":false,
"wangid":[1, 0, 1, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":61,
"vflip":false,
"wangid":[1, 0, 2, 0, 1, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":62,
"vflip":false,
"wangid":[1, 0, 2, 0, 1, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":63,
"vflip":false,
"wangid":[1, 0, 3, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":64,
"vflip":false,
"wangid":[1, 0, 3, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":65,
"vflip":false,
"wangid":[1, 0, 1, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":66,
"vflip":false,
"wangid":[1, 0, 3, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":67,
"vflip":false,
"wangid":[1, 0, 2, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":68,
"vflip":false,
"wangid":[1, 0, 1, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":69,
"vflip":false,
"wangid":[1, 0, 1, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":70,
"vflip":false,
"wangid":[1, 0, 2, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":71,
"vflip":false,
"wangid":[1, 0, 2, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":72,
"vflip":false,
"wangid":[2, 0, 3, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":73,
"vflip":false,
"wangid":[2, 0, 3, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":74,
"vflip":false,
"wangid":[2, 0, 1, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":75,
"vflip":false,
"wangid":[2, 0, 3, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":76,
"vflip":false,
"wangid":[2, 0, 2, 0, 2, 0, 3, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":77,
"vflip":false,
"wangid":[2, 0, 1, 0, 2, 0, 2, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":78,
"vflip":false,
"wangid":[2, 0, 1, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":79,
"vflip":false,
"wangid":[2, 0, 2, 0, 2, 0, 1, 0]
},
{
"dflip":false,
"hflip":false,
"tileid":80,
"vflip":false,
"wangid":[2, 0, 2, 0, 2, 0, 2, 0]
}]
}]
}

43
tests/test_layer.py Normal file
View File

@@ -0,0 +1,43 @@
"""Tests for tilesets"""
import importlib.util
import json
import os
from pathlib import Path
import pytest
from pytiled_parser import layer
TESTS_DIR = Path(os.path.dirname(os.path.abspath(__file__)))
TEST_DATA = TESTS_DIR / "test_data"
LAYER_TESTS = TEST_DATA / "layer_tests"
ALL_LAYER_TESTS = [
LAYER_TESTS / "all_layer_types",
LAYER_TESTS / "b64",
LAYER_TESTS / "b64_gzip",
LAYER_TESTS / "b64_zlib",
LAYER_TESTS / "no_layers",
LAYER_TESTS / "infinite_map",
LAYER_TESTS / "infinite_map_b64",
]
@pytest.mark.parametrize("layer_test", ALL_LAYER_TESTS)
def test_layer_integration(layer_test):
# it's a PITA to import like this, don't do it
# https://stackoverflow.com/a/67692/1342874
spec = importlib.util.spec_from_file_location(
"expected", layer_test / "expected.py"
)
expected = importlib.util.module_from_spec(spec)
spec.loader.exec_module(expected)
raw_layers_path = layer_test / "map.json"
with open(raw_layers_path) as raw_layers_file:
raw_layers = json.load(raw_layers_file)["layers"]
layers = [layer.cast(raw_layer) for raw_layer in raw_layers]
assert layers == expected.EXPECTED

Some files were not shown because too many files have changed in this diff Show More