diff --git a/apps/benchmark.py b/apps/benchmark.py index 9a20edc..8dda42d 100644 --- a/apps/benchmark.py +++ b/apps/benchmark.py @@ -29,14 +29,14 @@ logger.setLevel(logging.INFO) -def init_screen(width, height): +def init_screen(width: int, height: int) -> pygame.Surface: """Set the screen mode This function is used to handle window resize events """ return pygame.display.set_mode((width, height), pygame.RESIZABLE) -class TiledRenderer(object): +class TiledRenderer: """ Super simple way to render a tiled map """ @@ -55,7 +55,7 @@ def __init__(self, filename) -> None: print(i) continue - def render_map(self, surface) -> None: + def render_map(self, surface: pygame.Surface) -> None: """Render our map to a pygame surface Feel free to use this as a starting point for your pygame app. @@ -84,7 +84,7 @@ def render_map(self, surface) -> None: elif isinstance(layer, TiledImageLayer): self.render_image_layer(surface, layer) - def render_tile_layer(self, surface, layer) -> None: + def render_tile_layer(self, surface: pygame.Surface, layer: TiledTileLayer) -> None: """Render all TiledTiles in this layer""" # deref these heavily used references for speed tw = self.tmx_data.tilewidth @@ -95,7 +95,9 @@ def render_tile_layer(self, surface, layer) -> None: for x, y, image in layer.tiles(): surface_blit(image, (x * tw, y * th)) - def render_object_layer(self, surface, layer) -> None: + def render_object_layer( + self, surface: pygame.Surface, layer: TiledObjectGroup + ) -> None: """Render all TiledObjects contained in this layer""" # deref these heavily used references for speed draw_rect = pygame.draw.rect @@ -125,12 +127,14 @@ def render_object_layer(self, surface, layer) -> None: else: draw_rect(surface, rect_color, (obj.x, obj.y, obj.width, obj.height), 3) - def render_image_layer(self, surface, layer) -> None: + def render_image_layer( + self, surface: pygame.Surface, layer: TiledImageLayer + ) -> None: if layer.image: surface.blit(layer.image, (0, 0)) -class SimpleTest(object): +class SimpleTest: """Basic app to display a rendered Tiled map""" def __init__(self, filename) -> None: @@ -144,7 +148,7 @@ def load_map(self, filename) -> None: """Create a renderer, load data, and print some debug info""" self.renderer = TiledRenderer(filename) - def draw(self, surface) -> None: + def draw(self, surface: pygame.Surface) -> None: """Draw our map to some surface (probably the display)""" # first we make a temporary surface that will accommodate the entire # size of the map. @@ -161,7 +165,7 @@ def draw(self, surface) -> None: # display a bit of use info on the display f = pygame.font.Font(pygame.font.get_default_font(), 20) - i = f.render("press any key for next map or ESC to quit", 1, (180, 180, 0)) + i = f.render("press any key for next map or ESC to quit", True, (180, 180, 0)) surface.blit(i, (0, 0)) def handle_input(self) -> None: @@ -187,11 +191,11 @@ def handle_input(self) -> None: self.exit_status = 0 self.running = False - def run(self): + def run(self) -> bool: """This is our app main loop""" self.dirty = True self.running = True - self.exit_status = 1 + self.exit_status = True while self.running: self.handle_input() diff --git a/apps/pygame_demo.py b/apps/pygame_demo.py index 5e8c375..ab2c698 100644 --- a/apps/pygame_demo.py +++ b/apps/pygame_demo.py @@ -27,14 +27,14 @@ logger = logging.getLogger(__name__) -def init_screen(width, height): +def init_screen(width: int, height: int) -> pygame.Surface: """Set the screen mode This function is used to handle window resize events """ return pygame.display.set_mode((width, height), pygame.RESIZABLE) -class TiledRenderer(object): +class TiledRenderer: """ Super simple way to render a tiled map """ @@ -47,7 +47,7 @@ def __init__(self, filename) -> None: self.pixel_size = tm.width * tm.tilewidth, tm.height * tm.tileheight self.tmx_data = tm - def render_map(self, surface) -> None: + def render_map(self, surface: pygame.Surface) -> None: """Render our map to a pygame surface Feel free to use this as a starting point for your pygame app. @@ -76,7 +76,7 @@ def render_map(self, surface) -> None: elif isinstance(layer, TiledImageLayer): self.render_image_layer(surface, layer) - def render_tile_layer(self, surface, layer) -> None: + def render_tile_layer(self, surface: pygame.Surface, layer: TiledTileLayer) -> None: """Render all TiledTiles in this layer""" # deref these heavily used references for speed tw = self.tmx_data.tilewidth @@ -96,7 +96,9 @@ def render_tile_layer(self, surface, layer) -> None: sy = x * th2 + y * th2 surface_blit(image, (sx + ox, sy)) - def render_object_layer(self, surface, layer) -> None: + def render_object_layer( + self, surface: pygame.Surface, layer: TiledObjectGroup + ) -> None: """Render all TiledObjects contained in this layer""" # deref these heavily used references for speed draw_lines = pygame.draw.lines @@ -122,12 +124,14 @@ def render_object_layer(self, surface, layer) -> None: surface, rect_color, obj.closed, obj.apply_transformations(), 3 ) - def render_image_layer(self, surface, layer) -> None: + def render_image_layer( + self, surface: pygame.Surface, layer: TiledImageLayer + ) -> None: if layer.image: surface.blit(layer.image, (0, 0)) -class SimpleTest(object): +class SimpleTest: """Basic app to display a rendered Tiled map""" def __init__(self, filename) -> None: @@ -155,7 +159,7 @@ def load_map(self, filename) -> None: for k, v in self.renderer.tmx_data.get_tile_colliders(): logger.info("%s\t%s", k, list(v)) - def draw(self, surface) -> None: + def draw(self, surface: pygame.Surface) -> None: """Draw our map to some surface (probably the display)""" # first we make a temporary surface that will accommodate the entire # size of the map. @@ -172,7 +176,7 @@ def draw(self, surface) -> None: # display a bit of use info on the display f = pygame.font.Font(pygame.font.get_default_font(), 20) - i = f.render("press any key for next map or ESC to quit", 1, (180, 180, 0)) + i = f.render("press any key for next map or ESC to quit", True, (180, 180, 0)) surface.blit(i, (0, 0)) def handle_input(self) -> None: @@ -198,11 +202,11 @@ def handle_input(self) -> None: self.exit_status = 0 self.running = False - def run(self): + def run(self) -> bool: """This is our app main loop""" self.dirty = True self.running = True - self.exit_status = 1 + self.exit_status = True while self.running: self.handle_input() diff --git a/apps/pygame_sdl2_demo.py b/apps/pygame_sdl2_demo.py index 7ad7578..3f5dedf 100644 --- a/apps/pygame_sdl2_demo.py +++ b/apps/pygame_sdl2_demo.py @@ -26,7 +26,7 @@ class GameContext: renderer: Renderer -class TiledRenderer(object): +class TiledRenderer: """ Super simple way to render a tiled map @@ -136,10 +136,10 @@ def handle_input(self) -> None: self.exit_status = 0 self.running = False - def run(self): + def run(self) -> bool: """This is our app main loop""" self.running = True - self.exit_status = 1 + self.exit_status = True while self.running: self.handle_input() diff --git a/apps/pysdl2_demo.py b/apps/pysdl2_demo.py index fec4feb..72c0a28 100644 --- a/apps/pysdl2_demo.py +++ b/apps/pysdl2_demo.py @@ -36,7 +36,7 @@ from pytmx.util_pysdl2 import load_pysdl2 -class TiledRenderer(object): +class TiledRenderer: """ Super simple way to render a tiled map with pyglet @@ -81,7 +81,7 @@ def render_map(self) -> None: self.render_tile_layer(layer) -class SimpleTest(object): +class SimpleTest: def __init__(self, filename, window) -> None: self.running = False self.dirty = False diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index 7d40621..4e0b6c8 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -27,12 +27,12 @@ import zlib from base64 import b64decode from collections import defaultdict, namedtuple -from collections.abc import Iterable, Sequence +from collections.abc import Generator, Iterable, Sequence from copy import deepcopy from itertools import chain, product from math import cos, radians, sin from operator import attrgetter -from typing import Optional, Union +from typing import Any, Optional, Union from xml.etree import ElementTree # for type hinting @@ -136,10 +136,7 @@ def decode_gid(raw_gid: int) -> tuple[int, TileFlags]: ) -def reshape_data( - gids: list[int], - width: int, -) -> list[list[int]]: +def reshape_data(gids: list[int], width: int) -> list[list[int]]: """Change 1D list to 2d list Args: @@ -418,7 +415,9 @@ def _log_property_error_message() -> None: msg = "Some name are reserved for {0} objects and cannot be used." logger.error(msg) - def _set_properties(self, node: ElementTree.Element, customs=None) -> None: + def _set_properties( + self, node: ElementTree.Element, customs: Optional[dict] = None + ) -> None: """Set properties from xml data Reads the xml attributes and Tiled "properties" from an XML node and fills @@ -449,7 +448,7 @@ def __getattr__(self, item): else: raise AttributeError("Element has no property {0}".format(item)) - def __repr__(self): + def __repr__(self) -> str: if hasattr(self, "id"): return '<{}[{}]: "{}">'.format(self.__class__.__name__, self.id, self.name) else: @@ -506,8 +505,8 @@ def __init__( # 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.layers: list[TiledLayer] = [] # all layers in proper order + self.tilesets: list[TiledTileset] = [] # TiledTileset objects self.tile_properties = dict() # tiles that have properties self.layernames = dict() self.objects_by_id = dict() @@ -550,7 +549,7 @@ def __init__( if filename: self.parse_xml(ElementTree.parse(self.filename).getroot()) - def __repr__(self): + def __repr__(self) -> str: return '<{0}: "{1}">'.format(self.__class__.__name__, self.filename) # iterate over layers and objects in map @@ -1046,11 +1045,11 @@ def objects(self) -> Iterable[TiledObject]: return chain(*self.objectgroups) @property - def visible_layers(self): + def visible_layers(self) -> Iterable[TiledLayer]: """Returns iterator of Layer objects that are set "visible". Returns: - ???: Iterator of Layer objects that are set "visible". + Iterable[TiledLayer, None, None]: Layer objects that are set "visible". """ @@ -1178,11 +1177,11 @@ class TiledTileset(TiledElement): """ - def __init__(self, parent, node) -> None: + def __init__(self, parent: TiledMap, node: ElementTree.Element) -> None: """Represents a Tiled Tileset Args: - parent (???): ???. + parent (TiledMap): ???. node (ElementTree.Element): ???. """ @@ -1208,7 +1207,7 @@ def __init__(self, parent, node) -> None: self.parse_xml(node) - def parse_xml(self, node: ElementTree.Element) -> "TiledTileset": + def parse_xml(self, node: ElementTree.Element) -> TiledTileset: """Parse a Tileset from ElementTree xml element. A bit of mangling is done here so that tilesets that have @@ -1320,21 +1319,21 @@ def parse_xml(self, node: ElementTree.Element) -> "TiledTileset": class TiledGroupLayer(TiledElement): - def __init__(self, parent, node: ElementTree.Element) -> None: + def __init__(self, parent: TiledMap, node: ElementTree.Element) -> None: """ Args: - parent (???): ???. + parent (TiledMap): ???. node (ElementTree.Element): ???. """ TiledElement.__init__(self) self.parent = parent self.name = None - self.visible = 1 + self.visible = True self.parse_xml(node) - def parse_xml(self, node) -> "TiledGroupLayer": + def parse_xml(self, node: ElementTree.Element) -> TiledGroupLayer: """ Parse a TiledGroup layer from ElementTree xml node. @@ -1357,10 +1356,10 @@ class TiledTileLayer(TiledElement): """ - def __init__(self, parent, node) -> None: + def __init__(self, parent: TiledMap, node: ElementTree.Element) -> None: TiledElement.__init__(self) self.parent = parent - self.data = list() + self.data: list[list[int]] = [] # defaults from the specification self.name = None @@ -1373,7 +1372,7 @@ def __init__(self, parent, node) -> None: self.parse_xml(node) - def __iter__(self): + def __iter__(self) -> Iterable[tuple[int, int, int]]: return self.iter_data() def iter_data(self) -> Iterable[tuple[int, int, int]]: @@ -1387,7 +1386,7 @@ def iter_data(self) -> Iterable[tuple[int, int, int]]: for x, gid in enumerate(row): yield x, y, gid - def tiles(self): + def tiles(self) -> Generator[tuple[int, int, Any], Any, None]: """Yields X, Y, Image tuples for each tile in the layer. Yields: @@ -1407,7 +1406,7 @@ def _set_properties(self, node) -> None: self.height = int(self.height) self.width = int(self.width) - def parse_xml(self, node: ElementTree.Element) -> "TiledTileLayer": + def parse_xml(self, node: ElementTree.Element) -> TiledTileLayer: """Parse a Tile Layer from ElementTree xml node. Args: @@ -1451,7 +1450,12 @@ class TiledObjectGroup(TiledElement, list): """ - def __init__(self, parent, node, customs) -> None: + def __init__( + self, + parent: TiledMap, + node: ElementTree.Element, + customs: Optional[dict] = None, + ) -> None: TiledElement.__init__(self) self.parent = parent @@ -1459,7 +1463,7 @@ def __init__(self, parent, node, customs) -> None: self.name = None self.color = None self.opacity = 1 - self.visible = 1 + self.visible = True self.offsetx = 0 self.offsety = 0 self.custom_types = customs @@ -1467,7 +1471,7 @@ def __init__(self, parent, node, customs) -> None: self.parse_xml(node) - def parse_xml(self, node: ElementTree.Element) -> "TiledObjectGroup": + def parse_xml(self, node: ElementTree.Element) -> TiledObjectGroup: """Parse an Object Group from ElementTree xml node Args: @@ -1490,7 +1494,12 @@ class TiledObject(TiledElement): """ - def __init__(self, parent, node, custom_types) -> None: + def __init__( + self, + parent: TiledMap, + node: ElementTree.Element, + custom_types: Optional[dict] = None, + ) -> None: TiledElement.__init__(self) self.parent = parent @@ -1504,7 +1513,7 @@ def __init__(self, parent, node, custom_types) -> None: self.height = 0 self.rotation = 0 self.gid = 0 - self.visible = 1 + self.visible = True self.closed = True self.template = None self.custom_types = custom_types @@ -1523,7 +1532,7 @@ def image(self): return self.parent.images[self.gid] return None - def parse_xml(self, node: ElementTree.Element) -> "TiledObject": + def parse_xml(self, node: ElementTree.Element) -> TiledObject: """Parse an Object from ElementTree xml node. Args: @@ -1602,7 +1611,7 @@ class TiledImageLayer(TiledElement): """ - def __init__(self, parent, node: ElementTree.Element) -> None: + def __init__(self, parent: TiledMap, node: ElementTree.Element) -> None: TiledElement.__init__(self) self.parent = parent self.source = None @@ -1612,7 +1621,7 @@ def __init__(self, parent, node: ElementTree.Element) -> None: # defaults from the specification self.name = None self.opacity = 1 - self.visible = 1 + self.visible = True self.parse_xml(node) @@ -1633,7 +1642,7 @@ def parse_xml(self, node: ElementTree.Element): self._set_properties(node) self.name = node.get("name", None) self.opacity = node.get("opacity", self.opacity) - self.visible = node.get("visible", self.visible) + self.visible = bool(node.get("visible", self.visible)) image_node = node.find("image") self.source = image_node.get("source", None) self.trans = image_node.get("trans", None) @@ -1643,7 +1652,7 @@ def parse_xml(self, node: ElementTree.Element): class TiledProperty(TiledElement): """Represents Tiled Property.""" - def __init__(self, parent, node: ElementTree.Element) -> None: + def __init__(self, parent: TiledMap, node: ElementTree.Element) -> None: TiledElement.__init__(self) # defaults from the specification diff --git a/pytmx/util_pygame.py b/pytmx/util_pygame.py index f1dc2ac..d563586 100644 --- a/pytmx/util_pygame.py +++ b/pytmx/util_pygame.py @@ -240,8 +240,8 @@ def build_rects( layer_data = tmxmap.get_layer_data(layer) elif isinstance(layer, str): try: - layer = [l for l in tmxmap.layers if l.name == layer].pop() - layer_data = layer.data + _layer = [l for l in tmxmap.layers if l.name == layer].pop() + layer_data = _layer.data except IndexError: msg = 'Layer "{0}" not found in map {1}.' logger.debug(msg.format(layer, tmxmap))