123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- # coding: utf-8
- import typing
-
- import tmx
-
- from synergine2_xyz.exceptions import ImproperlyConfiguredMap
-
-
- class XYZTile(object):
- def __init__(self, tile: tmx.Tile) -> None:
- self.tile = tile
-
- def property(self, name: str) -> typing.Union[str, int, float]:
- for property in self.tile.properties:
- if property.name == name:
- return property.value
-
- raise ImproperlyConfiguredMap('Tile with id "{}" don\'t contains "{}" property'.format(
- self.tile.id,
- name,
- ))
-
-
- class UnconstructedTile(XYZTile):
- pass
-
-
- class TMXMap(object):
- xyz_tile_class = XYZTile
- transform_zero_y_to_bottom = True
-
- """
- Define default tileset name for layer. key: layer name, value: tileset name
- """
- default_layer_tilesets = {} # type: typing.Dict[str, str]
-
- def __init__(self, map_file_path: str) -> None:
- self.tmx_map = tmx.TileMap.load(map_file_path)
- self.tmx_layers = {} # type: typing.Dict[str, tmx.Layer]
- self.tmx_layer_tiles = {} # type: typing.Dict[str, typing.Dict[str, XYZTile]]
- self.tmx_tilesets = {} # type: typing.Dict[str, tmx.Tileset]
- self.tmx_tiles = {} # type: typing.Dict[int, XYZTile]
- self._load()
-
- @property
- def height(self) -> int:
- return self.tmx_map.height
-
- @property
- def width(self) -> int:
- return self.tmx_map.width
-
- def get_default_tileset(self) -> tmx.Tileset:
- return list(self.tmx_tilesets.values())[0]
-
- def get_default_tile(self, layer_name: str=None) -> XYZTile:
- """
- Return thirst tile of default tileset or thirst tile of given layer default tileset.
- :param layer: if layer given, thirst tile of it's default tileset will be returned
- :return: a Tile
- """
- if layer_name and layer_name in self.default_layer_tilesets:
- tileset_name = self.default_layer_tilesets[layer_name]
- tileset = self.tileset(tileset_name)
- else:
- tileset = self.get_default_tileset()
-
- return self.xyz_tile_class(tileset.tiles[0])
-
- def _load(self) -> None:
- self._load_layers()
- self._load_tilesets()
- self._load_tiles()
-
- def _load_layers(self) -> None:
- for layer in self.tmx_map.layers:
- self.tmx_layers[layer.name] = layer
-
- def _load_tilesets(self) -> None:
- for tileset in self.tmx_map.tilesets:
- self.tmx_tilesets[tileset.name] = tileset
- for tile in tileset.tiles:
- self.tmx_tiles[tileset.firstgid + tile.id] = self.xyz_tile_class(tile)
-
- def _load_tiles(self) -> None:
- for layer_name, layer in self.tmx_layers.items():
- x = -1
- y = 0 if not self.transform_zero_y_to_bottom else self.height - 1
- y_modifier = 1 if not self.transform_zero_y_to_bottom else -1
-
- self.tmx_layer_tiles[layer_name] = {}
-
- # no tiles
- if not isinstance(layer, tmx.Layer):
- continue
-
- for layer_tile in layer.tiles:
- x += 1
-
- if x == self.width:
- x = 0
- y += y_modifier
-
- position_key = '{}.{}'.format(x, y)
-
- if not layer_tile.gid:
- tile = self.get_default_tile(layer_name=layer_name)
- elif not layer_tile.gid in self.tmx_tiles:
- # tile = UnconstructedTile()
- tile = self.get_default_tile(layer_name=layer_name)
- else:
- tile = self.tmx_tiles[layer_tile.gid]
-
- self.tmx_layer_tiles[layer_name][position_key] = tile
-
- def layer(self, name: str) -> tmx.Layer:
- return self.tmx_layers[name]
-
- def tileset(self, name: str) -> tmx.Tileset:
- return self.tmx_tilesets[name]
-
- def tile(self, gid: int, allow_default_tile: bool=False, default_tile: tmx.LayerTile=None) -> XYZTile:
- try:
- return self.tmx_tiles[gid]
- except KeyError:
- if default_tile:
- return default_tile
- if allow_default_tile:
- return self.get_default_tile()
- raise
-
- def layer_tiles(self, name: str) -> typing.Dict[str, XYZTile]:
- return self.tmx_layer_tiles[name]
|