From ec662ae9c5ae63f71cfe9b1443731a85d7a7e49c Mon Sep 17 00:00:00 2001 From: Peter Nearing Date: Thu, 15 Aug 2024 11:45:41 -0400 Subject: [PATCH 01/13] Update Copyright Years and Object Types Changed the copyright years in multiple files for consistency. Adjusted object types in `pytmx.py` to include additional types such as ellipse, point, and text, along with their respective attributes. Refined imports and typing hints across various modules for clarity and efficiency. --- pytmx/__init__.py | 5 ++++- pytmx/pytmx.py | 32 +++++++++++++++++++++++++++++++- pytmx/util_pygame.py | 14 +++++++------- pytmx/util_pygame_sdl2.py | 14 ++++++-------- pytmx/util_pyglet.py | 4 ++-- pytmx/util_pysdl2.py | 2 +- 6 files changed, 51 insertions(+), 20 deletions(-) diff --git a/pytmx/__init__.py b/pytmx/__init__.py index 056a051..ba40067 100644 --- a/pytmx/__init__.py +++ b/pytmx/__init__.py @@ -1,5 +1,5 @@ """ -Copyright (C) 2012-2024, Leif Theden +Copyright (C) 2012-2023, Leif Theden This file is part of pytmx. @@ -28,3 +28,6 @@ logger.debug("cannot import pygame tools") __version__ = (3, 32) +__author__ = "bitcraft" +__author_email__ = "leif.theden@gmail.com" +__description__ = "Map loader for TMX Files - Python 3.3 +" diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index 7d40621..e3ef95d 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -1103,6 +1103,7 @@ def register_gid( flags = TileFlags(0, 0, 0) if tiled_gid: + try: return self.imagemap[(tiled_gid, flags)][0] except KeyError: @@ -1112,7 +1113,6 @@ def register_gid( self.gidmap[tiled_gid].append((gid, flags)) self.tiledgidmap[gid] = tiled_gid return gid - else: return 0 @@ -1498,6 +1498,7 @@ def __init__(self, parent, node, custom_types) -> None: self.id = 0 self.name = None self.type = None + self.object_type = 'rectangle' self.x = 0 self.y = 0 self.width = 0 @@ -1550,14 +1551,43 @@ def read_points(text): points = None polygon = node.find("polygon") if polygon is not None: + self.object_type = "polygon" points = read_points(polygon.get("points")) self.closed = True polyline = node.find("polyline") if polyline is not None: + self.object_type = "polyline" points = read_points(polyline.get("points")) self.closed = False + ellipse = node.find("ellipse") + if ellipse is not None: + self.object_type = "ellipse" + + point = node.find("point") + if point is not None: + self.object_type = "point" + + text = node.find("text") + if text is not None: + self.object_type = 'text' + # NOTE: The defaults have been taken from the tiled editor version 1.11.0 + setattr(self, 'text', text.text) + setattr(self, 'font_family', text.get('fontfamily', 'Sans Serif')) + # Not sure if this is really font size or not, but it's called + # pixel size in the .tmx file. + setattr(self, 'pixel_size', int(text.get('pixelsize', 16))) + setattr(self, 'wrap', bool(text.get('wrap', False))) + setattr(self, 'bold', bool(text.get('bold', False))) + setattr(self, 'italic', bool(text.get('italic', False))) + setattr(self, 'underline', bool(text.get('underline', False))) + setattr(self, 'strike_out', bool(text.get('strikeout', False))) + setattr(self, 'kerning', bool(text.get('kerning', True))) + setattr(self, 'h_align', text.get('halign', 'left')) + setattr(self, 'v_align', text.get('valign', 'top')) + setattr(self, 'color', text.get("color", "#000000FF")) + if points: x1 = x2 = y1 = y2 = 0 for x, y in points: diff --git a/pytmx/util_pygame.py b/pytmx/util_pygame.py index f1dc2ac..5489f4f 100644 --- a/pytmx/util_pygame.py +++ b/pytmx/util_pygame.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Copyright (C) 2012-2024, Leif Theden +Copyright (C) 2012-2023, Leif Theden This file is part of pytmx. @@ -19,7 +19,7 @@ """ import itertools import logging -from typing import Optional, Union +from typing import Optional, Union, List import pytmx from pytmx.pytmx import ColorLike, PointLike @@ -27,8 +27,8 @@ logger = logging.getLogger(__name__) try: - import pygame from pygame.transform import flip, rotate + import pygame except ImportError: logger.error("cannot import pygame (is it installed?)") raise @@ -188,7 +188,7 @@ def build_rects( layer: Union[int, str], tileset: Optional[Union[int, str]], real_gid: Optional[int], -) -> list[pygame.Rect]: +) -> List[pygame.Rect]: """ Generate a set of non-overlapping rects that represents the distribution of the specified gid. @@ -258,10 +258,10 @@ def build_rects( def simplify( - all_points: list[PointLike], + all_points: List[PointLike], tilewidth: int, tileheight: int, -) -> list[pygame.Rect]: +) -> List[pygame.Rect]: """Given a list of points, return list of rects that represent them kludge: @@ -304,7 +304,7 @@ def simplify( making a list of rects, one for each tile on the map! """ - def pick_rect(points, rects) -> None: + def pick_rect(points, rects): ox, oy = sorted([(sum(p), p) for p in points])[0][1] x = ox y = oy diff --git a/pytmx/util_pygame_sdl2.py b/pytmx/util_pygame_sdl2.py index 48e389a..dc1e2b0 100644 --- a/pytmx/util_pygame_sdl2.py +++ b/pytmx/util_pygame_sdl2.py @@ -1,5 +1,5 @@ """ -Copyright (C) 2012-2024, Leif Theden +Copyright (C) 2012-2022, Leif Theden This file is part of pytmx. @@ -19,7 +19,7 @@ import dataclasses import logging from functools import partial -from typing import Any, Optional +from typing import Tuple from pygame.rect import Rect @@ -28,8 +28,8 @@ logger = logging.getLogger(__name__) try: + from pygame._sdl2 import Texture, Image, Renderer, Window import pygame - from pygame._sdl2 import Image, Renderer, Texture, Window except ImportError: logger.error("cannot import pygame (is it installed?)") raise @@ -39,14 +39,14 @@ class PygameSDL2Tile: texture: Texture srcrect: Rect - size: tuple[int, int] + size: Tuple[int, int] angle: float = 0.0 center: None = None flipx: bool = False flipy: bool = False -def handle_flags(flags: Optional[pytmx.TileFlags]) -> tuple[float, bool, bool]: +def handle_flags(flags: pytmx.TileFlags): """ Return angle and flip values for the SDL2 renderer @@ -94,9 +94,7 @@ def load_image(rect=None, flags=None) -> PygameSDL2Tile: return load_image -def load_pygame_sdl2( - renderer: Renderer, filename: str, *args: Any, **kwargs: Any -) -> pytmx.TiledMap: +def load_pygame_sdl2(renderer: Renderer, filename: str, *args, **kwargs): """ Load a TMX file, images, and return a TiledMap class diff --git a/pytmx/util_pyglet.py b/pytmx/util_pyglet.py index 6e2334a..906b7e5 100644 --- a/pytmx/util_pyglet.py +++ b/pytmx/util_pyglet.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Copyright (C) 2012-2024, Leif Theden +Copyright (C) 2012-2017, Leif Theden This file is part of pytmx. @@ -46,7 +46,7 @@ def pyglet_image_loader(filename, colorkey, **kwargs): if colorkey: logger.debug("colorkey not implemented") - image = pyglet.resource.image(filename) + image = pyglet.image.load(filename) def load_image(rect=None, flags=None): if rect: diff --git a/pytmx/util_pysdl2.py b/pytmx/util_pysdl2.py index 7c2de85..872e9e4 100644 --- a/pytmx/util_pysdl2.py +++ b/pytmx/util_pysdl2.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Copyright (C) 2012-2024, Leif Theden +Copyright (C) 2012-2017, Leif Theden This file is part of pytmx. From f5e022857e332853825efc518d864b46d93d461f Mon Sep 17 00:00:00 2001 From: Peter Nearing Date: Thu, 15 Aug 2024 12:26:18 -0400 Subject: [PATCH 02/13] Adopt consistent string quoting in pytmx module Changed all single quotes to double quotes for string literals in pytmx.py. This ensures uniformity in the codebase and improves readability and maintainability of the code. No functional changes were made. --- pytmx/__init__.py | 1 + pytmx/pytmx.py | 29 +++++++++++++++-------------- pytmx/util_pygame_sdl2.py | 1 + 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/pytmx/__init__.py b/pytmx/__init__.py index ba40067..dc7bc52 100644 --- a/pytmx/__init__.py +++ b/pytmx/__init__.py @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with pytmx. If not, see . """ + import logging from .pytmx import * diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index e3ef95d..c1cff4f 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -17,6 +17,7 @@ License along with pytmx. If not, see . """ + from __future__ import annotations import gzip @@ -1498,7 +1499,7 @@ def __init__(self, parent, node, custom_types) -> None: self.id = 0 self.name = None self.type = None - self.object_type = 'rectangle' + self.object_type = "rectangle" self.x = 0 self.y = 0 self.width = 0 @@ -1571,22 +1572,22 @@ def read_points(text): text = node.find("text") if text is not None: - self.object_type = 'text' + self.object_type = "text" # NOTE: The defaults have been taken from the tiled editor version 1.11.0 - setattr(self, 'text', text.text) - setattr(self, 'font_family', text.get('fontfamily', 'Sans Serif')) + setattr(self, "text", text.text) + setattr(self, "font_family", text.get("fontfamily", "Sans Serif")) # Not sure if this is really font size or not, but it's called # pixel size in the .tmx file. - setattr(self, 'pixel_size', int(text.get('pixelsize', 16))) - setattr(self, 'wrap', bool(text.get('wrap', False))) - setattr(self, 'bold', bool(text.get('bold', False))) - setattr(self, 'italic', bool(text.get('italic', False))) - setattr(self, 'underline', bool(text.get('underline', False))) - setattr(self, 'strike_out', bool(text.get('strikeout', False))) - setattr(self, 'kerning', bool(text.get('kerning', True))) - setattr(self, 'h_align', text.get('halign', 'left')) - setattr(self, 'v_align', text.get('valign', 'top')) - setattr(self, 'color', text.get("color", "#000000FF")) + setattr(self, "pixel_size", int(text.get("pixelsize", 16))) + setattr(self, "wrap", bool(text.get("wrap", False))) + setattr(self, "bold", bool(text.get("bold", False))) + setattr(self, "italic", bool(text.get("italic", False))) + setattr(self, "underline", bool(text.get("underline", False))) + setattr(self, "strike_out", bool(text.get("strikeout", False))) + setattr(self, "kerning", bool(text.get("kerning", True))) + setattr(self, "h_align", text.get("halign", "left")) + setattr(self, "v_align", text.get("valign", "top")) + setattr(self, "color", text.get("color", "#000000FF")) if points: x1 = x2 = y1 = y2 = 0 diff --git a/pytmx/util_pygame_sdl2.py b/pytmx/util_pygame_sdl2.py index dc1e2b0..0ee0d91 100644 --- a/pytmx/util_pygame_sdl2.py +++ b/pytmx/util_pygame_sdl2.py @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with pytmx. If not, see . """ + import dataclasses import logging from functools import partial From 1faa259b259d55d753a3d6989bab03e218fd14d3 Mon Sep 17 00:00:00 2001 From: Peter Nearing Date: Sat, 17 Aug 2024 14:18:56 -0400 Subject: [PATCH 03/13] Revert "Update Copyright Years and Object Types" This reverts commit ec662ae9 --- pytmx/__init__.py | 5 +---- pytmx/util_pygame.py | 14 +++++++------- pytmx/util_pygame_sdl2.py | 14 ++++++++------ pytmx/util_pyglet.py | 4 ++-- pytmx/util_pysdl2.py | 2 +- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/pytmx/__init__.py b/pytmx/__init__.py index dc7bc52..63f596b 100644 --- a/pytmx/__init__.py +++ b/pytmx/__init__.py @@ -1,5 +1,5 @@ """ -Copyright (C) 2012-2023, Leif Theden +Copyright (C) 2012-2024, Leif Theden This file is part of pytmx. @@ -29,6 +29,3 @@ logger.debug("cannot import pygame tools") __version__ = (3, 32) -__author__ = "bitcraft" -__author_email__ = "leif.theden@gmail.com" -__description__ = "Map loader for TMX Files - Python 3.3 +" diff --git a/pytmx/util_pygame.py b/pytmx/util_pygame.py index 5489f4f..f1dc2ac 100644 --- a/pytmx/util_pygame.py +++ b/pytmx/util_pygame.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Copyright (C) 2012-2023, Leif Theden +Copyright (C) 2012-2024, Leif Theden This file is part of pytmx. @@ -19,7 +19,7 @@ """ import itertools import logging -from typing import Optional, Union, List +from typing import Optional, Union import pytmx from pytmx.pytmx import ColorLike, PointLike @@ -27,8 +27,8 @@ logger = logging.getLogger(__name__) try: - from pygame.transform import flip, rotate import pygame + from pygame.transform import flip, rotate except ImportError: logger.error("cannot import pygame (is it installed?)") raise @@ -188,7 +188,7 @@ def build_rects( layer: Union[int, str], tileset: Optional[Union[int, str]], real_gid: Optional[int], -) -> List[pygame.Rect]: +) -> list[pygame.Rect]: """ Generate a set of non-overlapping rects that represents the distribution of the specified gid. @@ -258,10 +258,10 @@ def build_rects( def simplify( - all_points: List[PointLike], + all_points: list[PointLike], tilewidth: int, tileheight: int, -) -> List[pygame.Rect]: +) -> list[pygame.Rect]: """Given a list of points, return list of rects that represent them kludge: @@ -304,7 +304,7 @@ def simplify( making a list of rects, one for each tile on the map! """ - def pick_rect(points, rects): + def pick_rect(points, rects) -> None: ox, oy = sorted([(sum(p), p) for p in points])[0][1] x = ox y = oy diff --git a/pytmx/util_pygame_sdl2.py b/pytmx/util_pygame_sdl2.py index 0ee0d91..c549205 100644 --- a/pytmx/util_pygame_sdl2.py +++ b/pytmx/util_pygame_sdl2.py @@ -1,5 +1,5 @@ """ -Copyright (C) 2012-2022, Leif Theden +Copyright (C) 2012-2024, Leif Theden This file is part of pytmx. @@ -20,7 +20,7 @@ import dataclasses import logging from functools import partial -from typing import Tuple +from typing import Any, Optional from pygame.rect import Rect @@ -29,8 +29,8 @@ logger = logging.getLogger(__name__) try: - from pygame._sdl2 import Texture, Image, Renderer, Window import pygame + from pygame._sdl2 import Image, Renderer, Texture, Window except ImportError: logger.error("cannot import pygame (is it installed?)") raise @@ -40,14 +40,14 @@ class PygameSDL2Tile: texture: Texture srcrect: Rect - size: Tuple[int, int] + size: tuple[int, int] angle: float = 0.0 center: None = None flipx: bool = False flipy: bool = False -def handle_flags(flags: pytmx.TileFlags): +def handle_flags(flags: Optional[pytmx.TileFlags]) -> tuple[float, bool, bool]: """ Return angle and flip values for the SDL2 renderer @@ -95,7 +95,9 @@ def load_image(rect=None, flags=None) -> PygameSDL2Tile: return load_image -def load_pygame_sdl2(renderer: Renderer, filename: str, *args, **kwargs): +def load_pygame_sdl2( + renderer: Renderer, filename: str, *args: Any, **kwargs: Any +) -> pytmx.TiledMap: """ Load a TMX file, images, and return a TiledMap class diff --git a/pytmx/util_pyglet.py b/pytmx/util_pyglet.py index 906b7e5..6e2334a 100644 --- a/pytmx/util_pyglet.py +++ b/pytmx/util_pyglet.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Copyright (C) 2012-2017, Leif Theden +Copyright (C) 2012-2024, Leif Theden This file is part of pytmx. @@ -46,7 +46,7 @@ def pyglet_image_loader(filename, colorkey, **kwargs): if colorkey: logger.debug("colorkey not implemented") - image = pyglet.image.load(filename) + image = pyglet.resource.image(filename) def load_image(rect=None, flags=None): if rect: diff --git a/pytmx/util_pysdl2.py b/pytmx/util_pysdl2.py index 872e9e4..7c2de85 100644 --- a/pytmx/util_pysdl2.py +++ b/pytmx/util_pysdl2.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Copyright (C) 2012-2017, Leif Theden +Copyright (C) 2012-2024, Leif Theden This file is part of pytmx. From 8c62957c23ea73020bdcb7b32128f08eec9a135b Mon Sep 17 00:00:00 2001 From: Peter Nearing Date: Sat, 17 Aug 2024 14:25:06 -0400 Subject: [PATCH 04/13] Add get_tile_flags_by_gid method to pytmx.py Introduce a new method, get_tile_flags_by_gid, to fetch tile flags using the global tile ID (GID). This improves the convenience of accessing tile properties directly by their GID. --- pytmx/pytmx.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index c1cff4f..d0c36de 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -1023,6 +1023,15 @@ def get_tile_colliders(self) -> Iterable[tuple[int, list[dict]]]: if colliders: yield gid, colliders + def get_tile_flags_by_gid(self, gid: int) -> TileFlags: + real_gid = self.tiledgidmap[gid] + flags_list = self.gidmap[real_gid] + for tile_gid, flags in flags_list: + if gid == tile_gid: + return flags + + + def pixels_to_tile_pos(self, position: tuple[int, int]) -> tuple[int, int]: return int(position[0] / self.tilewidth), int(position[1] / self.tileheight) From aa5c33e63326a194c6e7d7becfba223e3dda414f Mon Sep 17 00:00:00 2001 From: Peter Nearing <118986842+pnearing@users.noreply.github.com> Date: Mon, 12 May 2025 12:27:24 -0400 Subject: [PATCH 05/13] Update pytmx.py Remove unnecessary changes --- pytmx/pytmx.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index d0c36de..134bf70 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -1030,8 +1030,6 @@ def get_tile_flags_by_gid(self, gid: int) -> TileFlags: if gid == tile_gid: return flags - - def pixels_to_tile_pos(self, position: tuple[int, int]) -> tuple[int, int]: return int(position[0] / self.tilewidth), int(position[1] / self.tileheight) @@ -1113,7 +1111,6 @@ def register_gid( flags = TileFlags(0, 0, 0) if tiled_gid: - try: return self.imagemap[(tiled_gid, flags)][0] except KeyError: @@ -1123,6 +1120,7 @@ def register_gid( self.gidmap[tiled_gid].append((gid, flags)) self.tiledgidmap[gid] = tiled_gid return gid + else: return 0 From 50bb173de0f85e6d0deb052f7e1e947aa0d17776 Mon Sep 17 00:00:00 2001 From: Peter Nearing <118986842+pnearing@users.noreply.github.com> Date: Mon, 12 May 2025 12:28:19 -0400 Subject: [PATCH 06/13] Update util_pygame_sdl2.py Remove unnecessary change --- pytmx/util_pygame_sdl2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pytmx/util_pygame_sdl2.py b/pytmx/util_pygame_sdl2.py index c549205..48e389a 100644 --- a/pytmx/util_pygame_sdl2.py +++ b/pytmx/util_pygame_sdl2.py @@ -16,7 +16,6 @@ You should have received a copy of the GNU Lesser General Public License along with pytmx. If not, see . """ - import dataclasses import logging from functools import partial From e52d0d3a80258991acf27e8ae7ebfe664839f4fd Mon Sep 17 00:00:00 2001 From: Peter N Date: Mon, 12 May 2025 12:59:03 -0400 Subject: [PATCH 07/13] Move from using setattr to setting the properties directly. --- pytmx/pytmx.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index 134bf70..2fbb712 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -1554,6 +1554,7 @@ def read_points(text): # correctly handle "tile objects" (object with gid set) if self.gid: + self.object_type = "tile" self.gid = self.parent.register_gid_check_flags(self.gid) points = None @@ -1581,20 +1582,20 @@ def read_points(text): if text is not None: self.object_type = "text" # NOTE: The defaults have been taken from the tiled editor version 1.11.0 - setattr(self, "text", text.text) - setattr(self, "font_family", text.get("fontfamily", "Sans Serif")) + self.text = text.text + self.font_family = text.get("fontfamily", "Sans Serif") # Not sure if this is really font size or not, but it's called # pixel size in the .tmx file. - setattr(self, "pixel_size", int(text.get("pixelsize", 16))) - setattr(self, "wrap", bool(text.get("wrap", False))) - setattr(self, "bold", bool(text.get("bold", False))) - setattr(self, "italic", bool(text.get("italic", False))) - setattr(self, "underline", bool(text.get("underline", False))) - setattr(self, "strike_out", bool(text.get("strikeout", False))) - setattr(self, "kerning", bool(text.get("kerning", True))) - setattr(self, "h_align", text.get("halign", "left")) - setattr(self, "v_align", text.get("valign", "top")) - setattr(self, "color", text.get("color", "#000000FF")) + self.pixel_size = int(text.get("pixelsize", 16)) + self.wrap = bool(text.get("wrap", False)) + self.bold = bool(text.get("bold", False)) + self.italic = bool(text.get("italic", False)) + self.underline = bool(text.get("underline", False)) + self.strike_out = bool(text.get("strikeout", False)) + self.kerning = bool(text.get("kerning", True)) + self.h_align = text.get("halign", "left") + self.v_align = text.get("valign", "top") + self.color = text.get("color", "#000000FF") if points: x1 = x2 = y1 = y2 = 0 From e4f9e7abfad61b0c6edcbdf9e71c2daa9c963101 Mon Sep 17 00:00:00 2001 From: Peter N Date: Tue, 13 May 2025 20:23:48 -0400 Subject: [PATCH 08/13] feat: add points calculation for rectangle objects in TMX parser --- pytmx/pytmx.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index 2fbb712..76dc5c9 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -1554,7 +1554,7 @@ def read_points(text): # correctly handle "tile objects" (object with gid set) if self.gid: - self.object_type = "tile" + self.object_type = "tile" # set the object type to tile self.gid = self.parent.register_gid_check_flags(self.gid) points = None @@ -1611,6 +1611,16 @@ def read_points(text): self.width = abs(x1) + abs(x2) self.height = abs(y1) + abs(y2) self.points = tuple([Point(i[0] + self.x, i[1] + self.y) for i in points]) + # Set the points for a rectangle + elif self.object_type == "rectangle": + self.points = tuple( + [ + Point(self.x, self.y), + Point(self.x + self.width, self.y), + Point(self.x + self.width, self.y + self.height), + Point(self.x, self.y + self.height), + ] + ) return self From 829df4dd3247d43158d18193d40c10d0bf67eff0 Mon Sep 17 00:00:00 2001 From: Peter N Date: Sat, 24 May 2025 13:09:07 -0400 Subject: [PATCH 09/13] feat: add TiledGroupLayer to public API exports --- pytmx/pytmx.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index 76dc5c9..3056833 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -47,6 +47,7 @@ "TiledElement", "TiledImageLayer", "TiledMap", + "TiledGroupLayer", "TiledObject", "TiledObjectGroup", "TiledTileLayer", From a9501b46bae0cd03db1c6b7c91bb4863e94fdaaf Mon Sep 17 00:00:00 2001 From: Peter N Date: Thu, 24 Jul 2025 11:43:15 -0400 Subject: [PATCH 10/13] refactor: simplify polygon bounds calculation using zip and min/max --- pytmx/pytmx.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index 3056833..e74a04c 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -1599,18 +1599,9 @@ def read_points(text): self.color = text.get("color", "#000000FF") 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) + xs, ys = zip(*points) + self.width = max(xs) - min(xs) + self.height = max(ys) - min(ys) self.points = tuple([Point(i[0] + self.x, i[1] + self.y) for i in points]) # Set the points for a rectangle elif self.object_type == "rectangle": From 07cba5351861b8dc3b01328710ccdae8fcc3f595 Mon Sep 17 00:00:00 2001 From: Peter N Date: Mon, 18 Aug 2025 08:59:04 -0400 Subject: [PATCH 11/13] feat: add rotation handling for tilemap objects based on GID flags --- pytmx/pytmx.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pytmx/pytmx.py b/pytmx/pytmx.py index e74a04c..12fa923 100644 --- a/pytmx/pytmx.py +++ b/pytmx/pytmx.py @@ -623,6 +623,10 @@ def parse_xml(self, node: ElementTree.Element) -> None: # iterate through tile objects and handle the image for o in [o for o in self.objects if o.gid]: + # Decode rotation and flipping flags from the GID + gid, flags = decode_gid(o.gid) + rotation = self.get_rotation_from_flags(flags) # Get rotation based on flags + # gids might also have properties assigned to them # in that case, assign the gid properties to the object as well p = self.get_tile_properties_by_gid(o.gid) @@ -630,12 +634,32 @@ def parse_xml(self, node: ElementTree.Element) -> None: for key in p: o.properties.setdefault(key, p[key]) + # Adjust based on rotation + if rotation == 90: + o.x, o.y = o.x + o.height, o.y + elif rotation == 180: + o.x, o.y = o.x + o.width, o.y + o.height + elif rotation == 270: + o.x, o.y = o.x, o.y + o.width + + # Adjust Y-coordinate if invert_y is enabled if self.invert_y: o.y -= o.height self.reload_images() return self - + + def get_rotation_from_flags(self, flags: TileFlags) -> int: + """Determine the rotation angle from TileFlags.""" + if flags.flipped_diagonally: + if flags.flipped_horizontally and not flags.flipped_vertically: + return 90 + elif flags.flipped_horizontally and flags.flipped_vertically: + return 180 + elif not flags.flipped_horizontally and flags.flipped_vertically: + return 270 + return 0 + def reload_images(self) -> None: """Load or reload the map images from disk. From 8fca4f5f3ad4b6727db6edeffdc3875322d24421 Mon Sep 17 00:00:00 2001 From: Peter N Date: Mon, 18 Aug 2025 09:05:56 -0400 Subject: [PATCH 12/13] ci: remove GitHub Actions test workflow configuration --- .github/workflows/test.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 6048d2b..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: test - -on: - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - test: - runs-on: [ubuntu-latest] - strategy: - matrix: - python-version: ['3.9', '3.10', '3.11', '3.12'] - dependencies: - - pygame pyglet - - pygame - - pyglet - - "null" - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install Requirements - if: ${{ matrix.dependencies != 'null' }} - run: pip install ${{ matrix.dependencies }} - - name: Run Tests - run: python -m unittest tests/pytmx/test_pytmx.py From 3bac202c6c4d39fbee5f26b9168f7ab8ac968dee Mon Sep 17 00:00:00 2001 From: Peter N Date: Mon, 18 Aug 2025 09:06:09 -0400 Subject: [PATCH 13/13] chore: add .venv directory to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5688433..aa82534 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ thumbs.db build dist venv +.venv/ \ No newline at end of file