mirror of
https://github.com/OMGeeky/pytiled_parser.git
synced 2026-02-13 21:18:20 +01:00
Merge pull request #7 from pvcraven/master
Update for including hitboxes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -102,3 +102,4 @@ venv.bak/
|
|||||||
|
|
||||||
# mypy
|
# mypy
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
|
.idea/
|
||||||
|
|||||||
24
README.md
24
README.md
@@ -1,4 +1,22 @@
|
|||||||
# pytiled_parser
|
# PyTiled Parser
|
||||||
Python Library for parsing Tiled Map Editor maps.
|
|
||||||
|
|
||||||
NOT READY FOR USE
|
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 not tied to any particular graphics library, and can be used
|
||||||
|
with [Arcade](http://arcade.academy),
|
||||||
|
[Pyglet](https://pyglet.readthedocs.io/en/pyglet-1.3-maintenance/),
|
||||||
|
[Pygame](https://www.pygame.org/news), etc.
|
||||||
|
|
||||||
|
* Documentation available at: https://pytiled-parser.readthedocs.io/
|
||||||
|
* GitHub project at: https://github.com/pvcraven/pytiled_parser
|
||||||
|
* PiPy: https://pypi.org/project/pytiled-parser/
|
||||||
|
|
||||||
|
The [Arcade](http://arcade.academy) library has
|
||||||
|
[supporting code](http://arcade.academy/arcade.html#module-arcade.tilemap) to
|
||||||
|
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).
|
||||||
|
|||||||
20
docs/Makefile
Normal file
20
docs/Makefile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Minimal makefile for Sphinx documentation
|
||||||
|
#
|
||||||
|
|
||||||
|
# You can set these variables from the command line, and also
|
||||||
|
# from the environment for the first two.
|
||||||
|
SPHINXOPTS ?=
|
||||||
|
SPHINXBUILD ?= sphinx-build
|
||||||
|
SOURCEDIR = source
|
||||||
|
BUILDDIR = build
|
||||||
|
|
||||||
|
# Put it first so that "make" without argument is like "make help".
|
||||||
|
help:
|
||||||
|
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||||
|
|
||||||
|
.PHONY: help Makefile
|
||||||
|
|
||||||
|
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||||
|
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||||
|
%: Makefile
|
||||||
|
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||||
35
docs/make.bat
Normal file
35
docs/make.bat
Normal file
@@ -0,0 +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
|
||||||
BIN
docs/source/10_ladders_and_more.png
Normal file
BIN
docs/source/10_ladders_and_more.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
23
docs/source/api.rst
Normal file
23
docs/source/api.rst
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
.. _pytiled-api:
|
||||||
|
|
||||||
|
PyTiled Parser API
|
||||||
|
==================
|
||||||
|
|
||||||
|
This page documents the Application Programming Interface (API)
|
||||||
|
for the PyTiled Parser library.
|
||||||
|
|
||||||
|
.. automodule:: pytiled_parser.xml_parser
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. automodule:: pytiled_parser.objects
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
|
.. automodule:: pytiled_parser.utilities
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
68
docs/source/conf.py
Normal file
68
docs/source/conf.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# -- Path setup --------------------------------------------------------------
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# 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('../..'))
|
||||||
|
|
||||||
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
|
# 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',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
source_suffix = '.rst'
|
||||||
|
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
pygments_style = 'sphinx'
|
||||||
|
|
||||||
|
# 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 = []
|
||||||
|
|
||||||
|
|
||||||
|
# -- 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'
|
||||||
|
|
||||||
|
# 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']
|
||||||
36
docs/source/index.rst
Normal file
36
docs/source/index.rst
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
PyTiled Parser
|
||||||
|
==============
|
||||||
|
|
||||||
|
.. image:: 10_ladders_and_more.png
|
||||||
|
:width: 50%
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
API Documentation
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
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/>`_
|
||||||
130
make.bat
Normal file
130
make.bat
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
@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
|
||||||
@@ -10,7 +10,8 @@ import attr
|
|||||||
|
|
||||||
|
|
||||||
class Color(NamedTuple):
|
class Color(NamedTuple):
|
||||||
"""Color object.
|
"""
|
||||||
|
Color object.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
red (int): Red, between 1 and 255.
|
red (int): Red, between 1 and 255.
|
||||||
@@ -68,7 +69,8 @@ class Template:
|
|||||||
|
|
||||||
@attr.s(auto_attribs=True)
|
@attr.s(auto_attribs=True)
|
||||||
class Chunk:
|
class Chunk:
|
||||||
"""Chunk object for infinite maps.
|
"""
|
||||||
|
Chunk object for infinite maps.
|
||||||
|
|
||||||
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#chunk
|
See: https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#chunk
|
||||||
|
|
||||||
@@ -76,8 +78,7 @@ class Chunk:
|
|||||||
location (OrderedPair): Location of chunk in tiles.
|
location (OrderedPair): Location of chunk in tiles.
|
||||||
width (int): The width of the chunk in tiles.
|
width (int): The width of the chunk in tiles.
|
||||||
height (int): The height of the chunk in tiles.
|
height (int): The height of the chunk in tiles.
|
||||||
layer_data (List[List(int)]): The global tile IDs in chunky
|
layer_data (List[List(int)]): The global tile IDs in chunky according to row.
|
||||||
according to row.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
location: OrderedPair
|
location: OrderedPair
|
||||||
@@ -88,17 +89,15 @@ class Chunk:
|
|||||||
|
|
||||||
@attr.s(auto_attribs=True)
|
@attr.s(auto_attribs=True)
|
||||||
class Image:
|
class Image:
|
||||||
"""Image object.
|
"""
|
||||||
|
Image object.
|
||||||
|
|
||||||
This module does not support embedded data in image elements.
|
This module does not support embedded data in image elements.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
source (Optional[str]): The reference to the tileset image file.
|
source (Optional[str]): The reference to the tileset image file. Note that this is a relative path compared to FIXME
|
||||||
Not that this is a relative path compared to FIXME
|
trans (Optional[Color]): Defines a specific color that is treated as transparent.
|
||||||
trans (Optional[Color]): Defines a specific color that is treated
|
width (Optional[str]): The image width in pixels (optional, used for tile index correction when the image changes).
|
||||||
as transparent.
|
|
||||||
width (Optional[str]): The image width in pixels
|
|
||||||
(optional, used for tile index correction when the image changes).
|
|
||||||
height (Optional[str]): The image height in pixels (optional).
|
height (Optional[str]): The image height in pixels (optional).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -128,8 +127,7 @@ class Terrain(NamedTuple):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): The name of the terrain type.
|
name (str): The name of the terrain type.
|
||||||
tile (int): The local tile-id of the tile that represents the
|
tile (int): The local tile-id of the tile that represents the terrain visually.
|
||||||
terrain visually.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
@@ -174,25 +172,26 @@ class TileTerrain:
|
|||||||
|
|
||||||
@attr.s(auto_attribs=True, kw_only=True)
|
@attr.s(auto_attribs=True, kw_only=True)
|
||||||
class Layer:
|
class Layer:
|
||||||
"""Class that all layers inherret from.
|
"""
|
||||||
|
Class that all layers inherit from.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
id: Unique ID of the layer. Each layer that added to a map gets a
|
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
|
unique id. Even if a layer is deleted, no layer ever gets the same \
|
||||||
ID.
|
ID.
|
||||||
name: The name of the layer object.
|
name: The name of the layer object.
|
||||||
tiled_objects: List of tiled_objects in the layer.
|
tiled_objects: List of tiled_objects in the layer.
|
||||||
offset: Rendering offset of the layer object in pixels.
|
offset: Rendering offset of the layer object in pixels.
|
||||||
opacity: Decimal value between 0 and 1 to determine opacity. 1 is
|
opacity: Decimal value between 0 and 1 to determine opacity. 1 is \
|
||||||
completely opaque, 0 is completely transparent.
|
completely opaque, 0 is completely transparent.
|
||||||
properties: Properties for the layer.
|
properties: Properties for the layer.
|
||||||
color: The color used to display the objects in this group.
|
color: The color used to display the objects in this group.
|
||||||
FIXME: editor only?
|
draworder: Whether the objects are drawn according to the order of the \
|
||||||
draworder: Whether the objects are drawn according to the order of the
|
object elements in the object group element ('manual'), or sorted \
|
||||||
object elements in the object group element ('manual'), or sorted
|
by their y-coordinate ('topdown'). Defaults to 'topdown'. See: \
|
||||||
by their y-coordinate ('topdown'). Defaults to 'topdown'. See:
|
https://doc.mapeditor.org/en/stable/manual/objects/#changing-stacking-order \
|
||||||
https://doc.mapeditor.org/en/stable/manual/objects/#changing-stacking-order
|
for more info.
|
||||||
for more info.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
id_: int
|
id_: int
|
||||||
@@ -237,15 +236,13 @@ class TiledObject:
|
|||||||
https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#object
|
https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#object
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
id_ (int): Unique ID of the object. Each object that is placed on a
|
id (int): Unique ID of the object. Each object that is placed on a \
|
||||||
map gets a unique id. Even if an object was deleted, no object
|
map gets a unique id. Even if an object was deleted, no object \
|
||||||
gets the same ID.
|
gets the same ID.
|
||||||
gid (Optional[int]): Global tiled object ID
|
gid (Optional[int]): Global tiled object ID
|
||||||
location (OrderedPair): The location of the object in pixels.
|
location (OrderedPair): The location of the object in pixels.
|
||||||
size (Size): The width of the object in pixels
|
size (Size): The width of the object in pixels (default: (0, 0)).
|
||||||
(default: (0, 0)).
|
rotation (int): The rotation of the object in degrees clockwise (default: 0).
|
||||||
rotation (int): The rotation of the object in degrees clockwise
|
|
||||||
(default: 0).
|
|
||||||
opacity (int): The opacity of the object. (default: 255)
|
opacity (int): The opacity of the object. (default: 255)
|
||||||
name (Optional[str]): The name of the object.
|
name (Optional[str]): The name of the object.
|
||||||
type (Optional[str]): The type of the object.
|
type (Optional[str]): The type of the object.
|
||||||
@@ -374,7 +371,8 @@ class TextObject(TiledObject):
|
|||||||
|
|
||||||
@attr.s(auto_attribs=True, kw_only=True)
|
@attr.s(auto_attribs=True, kw_only=True)
|
||||||
class ObjectLayer(Layer):
|
class ObjectLayer(Layer):
|
||||||
"""TiledObject Group Object.
|
"""
|
||||||
|
TiledObject Group Object.
|
||||||
|
|
||||||
The object group is in fact a map layer, and is hence called \
|
The object group is in fact a map layer, and is hence called \
|
||||||
"object layer" in Tiled.
|
"object layer" in Tiled.
|
||||||
@@ -385,13 +383,13 @@ class ObjectLayer(Layer):
|
|||||||
Args:
|
Args:
|
||||||
tiled_objects: List of tiled_objects in the layer.
|
tiled_objects: List of tiled_objects in the layer.
|
||||||
offset: Rendering offset of the layer object in pixels.
|
offset: Rendering offset of the layer object in pixels.
|
||||||
color: The color used to display the objects in this group.
|
color: The color used to display the objects in this group. FIXME: editor only?
|
||||||
FIXME: editor only?
|
draworder: Whether the objects are drawn according to the order of the \
|
||||||
draworder: Whether the objects are drawn according to the order of the
|
object elements in the object group element ('manual'), or sorted \
|
||||||
object elements in the object group element ('manual'), or sorted
|
by their y-coordinate ('topdown'). Defaults to 'topdown'. See: \
|
||||||
by their y-coordinate ('topdown'). Defaults to 'topdown'. See:
|
https://doc.mapeditor.org/en/stable/manual/objects/#changing-stacking-order \
|
||||||
https://doc.mapeditor.org/en/stable/manual/objects/#changing-stacking-order
|
for more info.
|
||||||
for more info.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
tiled_objects: List[TiledObject]
|
tiled_objects: List[TiledObject]
|
||||||
@@ -425,26 +423,25 @@ class TileSet:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): The name of this tileset.
|
name (str): The name of this tileset.
|
||||||
max_tile_size (Size): The maximum size of a tile in this
|
max_tile_size (Size): The maximum size of a tile in this tile set in pixels.
|
||||||
tile set in pixels.
|
spacing (int): The spacing in pixels between the tiles in this \
|
||||||
spacing (int): The spacing in pixels between the tiles in this
|
|
||||||
tileset (applies to the tileset image).
|
tileset (applies to the tileset image).
|
||||||
margin (int): The margin around the tiles in this tileset
|
margin (int): The margin around the tiles in this tileset \
|
||||||
(applies to the tileset image).
|
(applies to the tileset image).
|
||||||
tile_count (int): The number of tiles in this tileset.
|
tile_count (int): The number of tiles in this tileset.
|
||||||
columns (int): The number of tile columns in the tileset.
|
columns (int): The number of tile columns in the tileset. \
|
||||||
For image collection tilesets it is editable and is used when
|
For image collection tilesets it is editable and is used when \
|
||||||
displaying the tileset.
|
displaying the tileset.
|
||||||
grid (Grid): Only used in case of isometric orientation, and
|
grid (Grid): Only used in case of isometric orientation, and \
|
||||||
determines how tile overlays for terrain and collision information
|
determines how tile overlays for terrain and collision information \
|
||||||
are rendered.
|
are rendered.
|
||||||
tileoffset (Optional[OrderedPair]): Used to specify an offset in
|
tileoffset (Optional[OrderedPair]): Used to specify an offset in \
|
||||||
pixels when drawing a tile from the tileset. When not present, no
|
pixels when drawing a tile from the tileset. When not present, no \
|
||||||
offset is applied.
|
offset is applied.
|
||||||
image (Image): Used for spritesheet tile sets.
|
image (Image): Used for spritesheet tile sets.
|
||||||
terrain_types (Dict[str, int]): List of of terrain types which
|
terrain_types (Dict[str, int]): List of of terrain types which \
|
||||||
can be referenced from the terrain attribute of the tile object.
|
can be referenced from the terrain attribute of the tile object. \
|
||||||
Ordered according to the terrain element's appearance in the TSX
|
Ordered according to the terrain element's appearance in the TSX \
|
||||||
file.
|
file.
|
||||||
tiles (Optional[Dict[int, Tile]]): Dict of Tile objects by Tile.id.
|
tiles (Optional[Dict[int, Tile]]): Dict of Tile objects by Tile.id.
|
||||||
"""
|
"""
|
||||||
@@ -484,9 +481,13 @@ class Tile:
|
|||||||
type_: Optional[str] = None
|
type_: Optional[str] = None
|
||||||
terrain: Optional[TileTerrain] = None
|
terrain: Optional[TileTerrain] = None
|
||||||
animation: Optional[List[Frame]] = None
|
animation: Optional[List[Frame]] = None
|
||||||
|
objectgroup: Optional[List[TiledObject]] = None
|
||||||
image: Optional[Image] = None
|
image: Optional[Image] = None
|
||||||
properties: Optional[List[Property]] = None
|
properties: Optional[List[Property]] = None
|
||||||
tileset: Optional[TileSet] = None
|
tileset: Optional[TileSet] = None
|
||||||
|
flipped_horizontally: bool = False
|
||||||
|
flipped_diagonally: bool = False
|
||||||
|
flipped_vertically: bool = False
|
||||||
|
|
||||||
|
|
||||||
@attr.s(auto_attribs=True)
|
@attr.s(auto_attribs=True)
|
||||||
@@ -528,6 +529,7 @@ class TileMap:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
parent_dir: Path
|
parent_dir: Path
|
||||||
|
tmx_file: Union[str, Path]
|
||||||
|
|
||||||
version: str
|
version: str
|
||||||
tiled_version: str
|
tiled_version: str
|
||||||
@@ -545,6 +547,6 @@ class TileMap:
|
|||||||
hex_side_length: Optional[int] = None
|
hex_side_length: Optional[int] = None
|
||||||
stagger_axis: Optional[int] = None
|
stagger_axis: Optional[int] = None
|
||||||
stagger_index: Optional[int] = None
|
stagger_index: Optional[int] = None
|
||||||
background_color: Optional[str] = None
|
background_color: Optional[Color] = None
|
||||||
|
|
||||||
properties: Optional[Properties] = None
|
properties: Optional[Properties] = None
|
||||||
|
|||||||
@@ -60,8 +60,7 @@ def get_tile_by_gid(
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
objects.Tile: The Tile object reffered to by the global tile ID.
|
objects.Tile: The Tile object reffered to by the global tile ID.
|
||||||
None: If there is no objects.Tile object in the tile_set.tiles dict
|
None: If there is no objects.Tile object in the tile_set.tiles dict for the associated gid.
|
||||||
for the associated gid.
|
|
||||||
"""
|
"""
|
||||||
tile_set_key = _get_tile_set_key(gid, list(tile_sets.keys()))
|
tile_set_key = _get_tile_set_key(gid, list(tile_sets.keys()))
|
||||||
tile_set = tile_sets[tile_set_key]
|
tile_set = tile_sets[tile_set_key]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from pathlib import Path
|
|||||||
from typing import Callable, Dict, List, Optional, Tuple, Union
|
from typing import Callable, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
import pytiled_parser.objects as objects
|
import pytiled_parser.objects as objects
|
||||||
|
from pytiled_parser.utilities import parse_color
|
||||||
|
|
||||||
def _decode_base64_data(
|
def _decode_base64_data(
|
||||||
data_text: str, layer_width: int, compression: Optional[str] = None
|
data_text: str, layer_width: int, compression: Optional[str] = None
|
||||||
@@ -192,7 +192,10 @@ def _parse_layer(
|
|||||||
Returns:
|
Returns:
|
||||||
FIXME
|
FIXME
|
||||||
"""
|
"""
|
||||||
id_ = int(layer_element.attrib["id"])
|
if "id" in layer_element:
|
||||||
|
id_ = int(layer_element.attrib["id"])
|
||||||
|
else:
|
||||||
|
id_ = None
|
||||||
|
|
||||||
name = layer_element.attrib["name"]
|
name = layer_element.attrib["name"]
|
||||||
|
|
||||||
@@ -464,6 +467,19 @@ def _parse_external_tile_set(
|
|||||||
return _parse_tile_set(tile_set_tree)
|
return _parse_tile_set(tile_set_tree)
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_points(point_string: str) -> List[objects.OrderedPair]:
|
||||||
|
str_pairs = point_string.split(" ")
|
||||||
|
|
||||||
|
points = []
|
||||||
|
for str_pair in str_pairs:
|
||||||
|
xys = str_pair.split(",")
|
||||||
|
x = float(xys[0])
|
||||||
|
y = float(xys[1])
|
||||||
|
points.append((x, y))
|
||||||
|
|
||||||
|
return points
|
||||||
|
|
||||||
|
|
||||||
def _parse_tiles(
|
def _parse_tiles(
|
||||||
tile_element_list: List[etree.Element]
|
tile_element_list: List[etree.Element]
|
||||||
) -> Dict[int, objects.Tile]:
|
) -> Dict[int, objects.Tile]:
|
||||||
@@ -488,6 +504,7 @@ def _parse_tiles(
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
terrain = None
|
||||||
try:
|
try:
|
||||||
tile_terrain_attrib = tile_element.attrib["terrain"]
|
tile_terrain_attrib = tile_element.attrib["terrain"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -529,11 +546,70 @@ def _parse_tiles(
|
|||||||
frames = tile_animation_element.findall("./frame")
|
frames = tile_animation_element.findall("./frame")
|
||||||
for frame in frames:
|
for frame in frames:
|
||||||
# tileid refers to the Tile.id of the animation frame
|
# tileid refers to the Tile.id of the animation frame
|
||||||
id_ = int(frame.attrib["tileid"])
|
animated_id = int(frame.attrib["tileid"])
|
||||||
# duration is in MS. Should perhaps be converted to seconds.
|
# duration is in MS. Should perhaps be converted to seconds.
|
||||||
# FIXME: make decision
|
# FIXME: make decision
|
||||||
duration = int(frame.attrib["duration"])
|
duration = int(frame.attrib["duration"])
|
||||||
animation.append(objects.Frame(id_, duration))
|
animation.append(objects.Frame(animated_id, duration))
|
||||||
|
|
||||||
|
# tile element optional sub-elements
|
||||||
|
objectgroup: Optional[List[objects.TiledObject]] = None
|
||||||
|
objectgroup_element = tile_element.find("./objectgroup")
|
||||||
|
if objectgroup_element:
|
||||||
|
objectgroup = []
|
||||||
|
object_list = objectgroup_element.findall("./object")
|
||||||
|
for object in object_list:
|
||||||
|
my_id = object.attrib["id"]
|
||||||
|
my_x = float(object.attrib["x"])
|
||||||
|
my_y = float(object.attrib["y"])
|
||||||
|
if "width" in object.attrib:
|
||||||
|
my_width = float(object.attrib["width"])
|
||||||
|
else:
|
||||||
|
my_width = None
|
||||||
|
if "height" in object.attrib:
|
||||||
|
my_height = float(object.attrib["height"])
|
||||||
|
else:
|
||||||
|
my_height = None
|
||||||
|
|
||||||
|
# This is where it would be nice if we could assume a walrus
|
||||||
|
# operator was part of our Python distribution.
|
||||||
|
|
||||||
|
my_object = None
|
||||||
|
|
||||||
|
polygon = object.findall("./polygon")
|
||||||
|
|
||||||
|
if polygon and len(polygon) > 0:
|
||||||
|
points = _parse_points(polygon[0].attrib["points"])
|
||||||
|
my_object = objects.PolygonObject(id_=my_id,
|
||||||
|
location=(my_x, my_y),
|
||||||
|
size=(my_width, my_height),
|
||||||
|
points=points)
|
||||||
|
|
||||||
|
if my_object is None:
|
||||||
|
polyline = object.findall("./polyline")
|
||||||
|
|
||||||
|
if polyline and len(polyline) > 0:
|
||||||
|
points = _parse_points(polyline[0].attrib["points"])
|
||||||
|
my_object = objects.PolylineObject(id_=my_id,
|
||||||
|
location=(my_x, my_y),
|
||||||
|
size=(my_width, my_height),
|
||||||
|
points=points)
|
||||||
|
|
||||||
|
if my_object is None:
|
||||||
|
ellipse = object.findall("./ellipse")
|
||||||
|
|
||||||
|
if ellipse and len(ellipse):
|
||||||
|
my_object = objects.ElipseObject(id_=my_id,
|
||||||
|
location=(my_x, my_y),
|
||||||
|
size=(my_width, my_height))
|
||||||
|
|
||||||
|
|
||||||
|
if my_object is None:
|
||||||
|
my_object = objects.RectangleObject(id_=my_id,
|
||||||
|
location=(my_x, my_y),
|
||||||
|
size=(my_width, my_height))
|
||||||
|
|
||||||
|
objectgroup.append(my_object)
|
||||||
|
|
||||||
# if this is None, then the Tile is part of a spritesheet
|
# if this is None, then the Tile is part of a spritesheet
|
||||||
image = None
|
image = None
|
||||||
@@ -541,6 +617,8 @@ def _parse_tiles(
|
|||||||
if image_element is not None:
|
if image_element is not None:
|
||||||
image = _parse_image_element(image_element)
|
image = _parse_image_element(image_element)
|
||||||
|
|
||||||
|
# print(f"Adding '{id_}', {image}, {objectgroup}")
|
||||||
|
|
||||||
tiles[id_] = objects.Tile(
|
tiles[id_] = objects.Tile(
|
||||||
id_=id_,
|
id_=id_,
|
||||||
type_=_type,
|
type_=_type,
|
||||||
@@ -549,6 +627,7 @@ def _parse_tiles(
|
|||||||
image=image,
|
image=image,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
tileset=None,
|
tileset=None,
|
||||||
|
objectgroup=objectgroup
|
||||||
)
|
)
|
||||||
|
|
||||||
return tiles
|
return tiles
|
||||||
@@ -804,8 +883,15 @@ def parse_tile_map(tmx_file: Union[str, Path]) -> objects.TileMap:
|
|||||||
infinite_attribute = map_element.attrib["infinite"]
|
infinite_attribute = map_element.attrib["infinite"]
|
||||||
infinite = bool(infinite_attribute == "true")
|
infinite = bool(infinite_attribute == "true")
|
||||||
|
|
||||||
next_layer_id = int(map_element.attrib["nextlayerid"])
|
if "nextlayerid" in map_element.attrib:
|
||||||
next_object_id = int(map_element.attrib["nextobjectid"])
|
next_layer_id = int(map_element.attrib["nextlayerid"])
|
||||||
|
else:
|
||||||
|
next_layer_id = None
|
||||||
|
|
||||||
|
if "nextobjectid" in map_element.attrib:
|
||||||
|
next_object_id = int(map_element.attrib["nextobjectid"])
|
||||||
|
else:
|
||||||
|
next_object_id = None
|
||||||
|
|
||||||
tile_sets = _get_tile_sets(map_element, parent_dir)
|
tile_sets = _get_tile_sets(map_element, parent_dir)
|
||||||
|
|
||||||
@@ -813,6 +899,7 @@ def parse_tile_map(tmx_file: Union[str, Path]) -> objects.TileMap:
|
|||||||
|
|
||||||
tile_map = objects.TileMap(
|
tile_map = objects.TileMap(
|
||||||
parent_dir,
|
parent_dir,
|
||||||
|
tmx_file,
|
||||||
version,
|
version,
|
||||||
tiled_version,
|
tiled_version,
|
||||||
orientation,
|
orientation,
|
||||||
@@ -842,7 +929,8 @@ def parse_tile_map(tmx_file: Union[str, Path]) -> objects.TileMap:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tile_map.background_color = map_element.attrib["backgroundcolor"]
|
color = parse_color(map_element.attrib["backgroundcolor"])
|
||||||
|
tile_map.background_color = (color.red, color.green, color.blue)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user