Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
msg = 'layer data not in expected format ({})'
logger.error(msg.format(type(data)))
raise Exception
init = lambda: [0] * self.width
reg = self.parent.register_gid
# H (16-bit) may be a limitation for very detailed maps
self.data = tuple(array.array('H', init()) for i in range(self.height))
for (y, x) in product(range(self.height), range(self.width)):
self.data[y][x] = reg(*decode_gid(next(next_gid)))
return self
class TiledObjectGroup(TiledElement, list):
""" Represents a Tiled ObjectGroup
Supports any operation of a normal list.
"""
def __init__(self, parent, node):
TiledElement.__init__(self)
self.parent = parent
# defaults from the specification
self.name = None
self.color = None
self.opacity = 1
self.visible = 1
self.offsetx = 0
self.offsety = 0
if points:
x1 = x2 = y1 = y2 = 0
for x, y in points:
if x < x1: x1 = x
if x > x2: x2 = x
if y < y1: y1 = y
if y > y2: y2 = y
self.width = abs(x1) + abs(x2)
self.height = abs(y1) + abs(y2)
self.points = tuple(
[(i[0] + self.x, i[1] + self.y) for i in points])
return self
class TiledImageLayer(TiledElement):
""" Represents Tiled Image Layer
The image associated with this layer will be loaded and assigned a GID.
"""
def __init__(self, parent, node):
TiledElement.__init__(self)
self.parent = parent
self.source = None
self.trans = None
self.gid = 0
# defaults from the specification
self.name = None
self.opacity = 1
self.visible = 1
self.parse_xml(node)
def parse_xml(self, node):
""" Parse an Object Group from ElementTree xml node
:param node: ElementTree xml node
:return: self
"""
self._set_properties(node)
self.extend(TiledObject(self.parent, child)
for child in node.findall('object'))
return self
class TiledObject(TiledElement):
""" Represents a any Tiled Object
Supported types: Box, Ellipse, Tile Object, Polyline, Polygon
"""
def __init__(self, parent, node):
TiledElement.__init__(self)
self.parent = parent
# defaults from the specification
self.id = 0
self.name = None
self.type = None
self.x = 0
self.y = 0
self.width = 0
""" WIP. need to refactor the gid code
:param tiled_gid:
:return:
"""
tiled_gid = int(tiled_gid)
# gidmap is a default dict, so cannot trust to raise KeyError
if tiled_gid in self.gidmap:
return self.gidmap[tiled_gid]
else:
gid = self.register_gid(tiled_gid)
return [(gid, None)]
class TiledTileset(TiledElement):
""" Represents a Tiled Tileset
External tilesets are supported. GID/ID's from Tiled are not guaranteed to
be the same after loaded.
"""
def __init__(self, parent, node):
TiledElement.__init__(self)
self.parent = parent
self.offset = (0, 0)
# defaults from the specification
self.firstgid = 0
self.source = None
self.name = None
self.tilewidth = 0
""" Parse an Image Layer from ElementTree xml node
:param node: ElementTree xml node
:return: self
"""
self._set_properties(node)
self.name = node.get('name', None)
self.opacity = node.get('opacity', self.opacity)
self.visible = node.get('visible', self.visible)
image_node = node.find('image')
self.source = image_node.get('source', None)
self.trans = image_node.get('trans', None)
return self
class TiledProperty(TiledElement):
""" Represents Tiled Property
"""
def __init__(self, parent, node):
TiledElement.__init__(self)
# defaults from the specification
self.name = None
self.type = None
self.value = None
self.parse_xml(node)
def parse_xml(self, node):
pass
image_node = node.find('image')
if image_node is not None:
self.source = image_node.get('source')
# When loading from tsx, tileset image path is relative to the tsx file, not the tmx:
if source:
self.source = os.path.join(os.path.dirname(source), self.source)
self.trans = image_node.get('trans', None)
self.width = int(image_node.get('width'))
self.height = int(image_node.get('height'))
return self
class TiledTileLayer(TiledElement):
""" Represents a TileLayer
To just get the tile images, use TiledTileLayer.tiles()
"""
def __init__(self, parent, node):
TiledElement.__init__(self)
self.parent = parent
self.data = list()
# defaults from the specification
self.name = None
self.width = 0
self.height = 0
self.opacity = 1.0
self.visible = True
self._log_property_error_message()
raise ValueError("Reserved names and duplicate names are not allowed. Please rename your property inside the .tmx-file")
self.properties = properties
def __getattr__(self, item):
try:
return self.properties[item]
except KeyError:
raise AttributeError
def __repr__(self):
return '<{0}: "{1}">'.format(self.__class__.__name__, self.name)
class TiledMap(TiledElement):
"""Contains the layers, objects, and images from a Tiled TMX map
This class is meant to handle most of the work you need to do to use a map.
"""
def __init__(self, filename=None, image_loader=default_image_loader, **kwargs):
""" Create new TiledMap
:param filename: filename of tiled map to load
:param image_loader: function that will load images (see below)
:param optional_gids: load specific tile image GID, even if never used
:param invert_y: invert the y axis
:param load_all_tiles: load all tile images, even if never used
:param allow_duplicate_names: allow duplicates in objects' metatdata
image_loader:
image_loader:
this must be a reference to a function that will accept a tuple:
(filename of image, bounding rect of tile in image, flags)
the function must return a reference to to the tile.
"""
TiledElement.__init__(self)
self.filename = filename
self.image_loader = image_loader
# optional keyword arguments checked here
self.optional_gids = kwargs.get('optional_gids', set())
self.load_all_tiles = kwargs.get('load_all', True)
self.invert_y = kwargs.get('invert_y', True)
# allow duplicate names to be parsed and loaded
TiledElement.allow_duplicate_names = \
kwargs.get('allow_duplicate_names', False)
self.layers = list() # all layers in proper order
self.tilesets = list() # TiledTileset objects
self.tile_properties = dict() # tiles that have properties
self.layernames = dict()
# only used tiles are actually loaded, so there will be a difference
# between the GIDs in the Tiled map data (tmx) and the data in this
# object and the layers. This dictionary keeps track of that.
self.gidmap = defaultdict(list)
self.imagemap = dict() # mapping of gid and trans flags to real gids
self.tiledgidmap = dict() # mapping of tiledgid to pytmx gid
self.maxgid = 1
# should be filled in by a loader function