def _parse_tile_layer(element: etree.Element, ) -> objects.TileLayer: """Parses tile layer element. Args: element: The layer element to be parsed. Raises: ValueError: Element has no child data element. Returns: TileLayer: The tile layer object. """ id_, name, offset, opacity, properties = _parse_layer(element) width = int(element.attrib["width"]) height = int(element.attrib["height"]) size = objects.Size(width, height) data_element = element.find("./data") assert data_element is not None layer_data: objects.LayerData = _parse_data(data_element, width) return objects.TileLayer( id_=id_, name=name, offset=offset, opacity=opacity, properties=properties, size=size, layer_data=layer_data, )
def _parse_image_element(image_element: etree.Element) -> objects.Image: """Parse image element given. Args: image_element (etree.Element): Image element to be parsed. Returns: objects.Image: FIXME what is this? """ # FIXME doc image = objects.Image(image_element.attrib["source"]) width_attrib = image_element.attrib.get("width") height_attrib = image_element.attrib.get("height") if width_attrib and height_attrib: image.size = objects.Size(int(width_attrib), int(height_attrib)) try: image.trans = image_element.attrib["trans"] except KeyError: pass return image
def parse_tile_map(tmx_file: Union[str, Path]) -> objects.TileMap: """Parse tile map. Args: tmx_file: TMX file to be parsed. Returns: objects.TileMap: TileMap object generated from the TMX file provided. """ # setting up XML parsing map_tree = etree.parse(str(tmx_file)) map_element = map_tree.getroot() # positional arguments for TileMap parent_dir = Path(tmx_file).parent version = map_element.attrib["version"] tiled_version = map_element.attrib["tiledversion"] orientation = map_element.attrib["orientation"] render_order = map_element.attrib["renderorder"] map_width = int(map_element.attrib["width"]) map_height = int(map_element.attrib["height"]) map_size = objects.Size(map_width, map_height) tile_width = int(map_element.attrib["tilewidth"]) tile_height = int(map_element.attrib["tileheight"]) tile_size = objects.Size(tile_width, tile_height) infinite_attribute = map_element.attrib["infinite"] infinite = bool(infinite_attribute == "1") if "nextlayerid" in map_element.attrib: 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) layers = _get_layers(map_element) tile_map = objects.TileMap( parent_dir, tmx_file, version, tiled_version, orientation, render_order, map_size, tile_size, infinite, next_layer_id, next_object_id, tile_sets, layers, ) try: tile_map.hex_side_length = int(map_element.attrib["hexsidelength"]) except KeyError: pass try: tile_map.stagger_axis = map_element.attrib["staggeraxis"] except KeyError: pass try: tile_map.stagger_index = map_element.attrib["staggerindex"] except KeyError: pass try: color = parse_color(map_element.attrib["backgroundcolor"]) tile_map.background_color = (color.red, color.green, color.blue) except KeyError: pass properties_element = map_tree.find("./properties") if properties_element is not None: tile_map.properties = _parse_properties_element(properties_element) return tile_map
def _parse_tile_set(tile_set_element: etree.Element) -> objects.TileSet: """Parses a tile set that is embedded into a TMX. Args: tile_set_element: Element to be parsed. Returns: objects.TileSet: Tile Set from element. """ # get all basic attributes name = tile_set_element.attrib["name"] max_tile_width = int(tile_set_element.attrib["tilewidth"]) max_tile_height = int(tile_set_element.attrib["tileheight"]) max_tile_size = objects.Size(max_tile_width, max_tile_height) spacing = None try: spacing = int(tile_set_element.attrib["spacing"]) except KeyError: pass margin = None try: margin = int(tile_set_element.attrib["margin"]) except KeyError: pass tile_count = None try: tile_count = int(tile_set_element.attrib["tilecount"]) except KeyError: pass columns = None try: columns = int(tile_set_element.attrib["columns"]) except KeyError: pass tile_offset = None tileoffset_element = tile_set_element.find("./tileoffset") if tileoffset_element is not None: tile_offset_x = int(tileoffset_element.attrib["x"]) tile_offset_y = int(tileoffset_element.attrib["y"]) tile_offset = objects.OrderedPair(tile_offset_x, tile_offset_y) grid = None grid_element = tile_set_element.find("./grid") if grid_element is not None: grid_orientation = grid_element.attrib["orientation"] grid_width = int(grid_element.attrib["width"]) grid_height = int(grid_element.attrib["height"]) grid = objects.Grid(grid_orientation, grid_width, grid_height) properties = None properties_element = tile_set_element.find("./properties") if properties_element is not None: properties = _parse_properties_element(properties_element) terrain_types: Optional[List[objects.Terrain]] = None terrain_types_element = tile_set_element.find("./terraintypes") if terrain_types_element is not None: terrain_types = [] for terrain in terrain_types_element.findall("./terrain"): name = terrain.attrib["name"] terrain_tile = int(terrain.attrib["tile"]) terrain_types.append(objects.Terrain(name, terrain_tile)) image = None image_element = tile_set_element.find("./image") if image_element is not None: image = _parse_image_element(image_element) tile_element_list = tile_set_element.findall("./tile") tiles = _parse_tiles(tile_element_list) tileset = objects.TileSet( name, max_tile_size, spacing, margin, tile_count, columns, tile_offset, grid, properties, image, terrain_types, tiles, ) # Go back and create a circular link so tiles know what tileset they are # part of. Needed for animation. for id_, tile in tiles.items(): tile.tileset = tileset return tileset
def _parse_objects( object_elements: List[etree.Element]) -> List[objects.TiledObject]: """Parses objects found in the 'objectgroup' element. Args: object_elements: List of object elements to be parsed. Returns: list: List of parsed tiled objects. """ tiled_objects: List[objects.TiledObject] = [] for object_element in object_elements: id_ = int(object_element.attrib["id"]) location_x = float(object_element.attrib["x"]) location_y = float(object_element.attrib["y"]) location = objects.OrderedPair(location_x, location_y) tiled_object = objects.TiledObject(id_=id_, location=location) try: tiled_object.gid = int(object_element.attrib["gid"]) except KeyError: tiled_object.gid = None try: width = float(object_element.attrib["width"]) except KeyError: width = 0.0 try: height = float(object_element.attrib["height"]) except KeyError: height = 0.0 tiled_object.size = objects.Size(width, height) try: tiled_object.opacity = float(object_element.attrib["opacity"]) except KeyError: pass try: tiled_object.rotation = int(object_element.attrib["rotation"]) except KeyError: pass try: tiled_object.name = object_element.attrib["name"] except KeyError: pass try: tiled_object.type = object_element.attrib["type"] except KeyError: pass properties_element = object_element.find("./properties") if properties_element is not None: tiled_object.properties = _parse_properties_element( properties_element) tiled_objects.append(tiled_object) return tiled_objects