tilemap-parser 2.0.0__tar.gz → 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tilemap_parser-2.0.0/src/tilemap_parser.egg-info → tilemap_parser-2.0.1}/PKG-INFO +1 -1
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/pyproject.toml +1 -1
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser/collision_runner.py +2 -2
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1/src/tilemap_parser.egg-info}/PKG-INFO +1 -1
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser.egg-info/SOURCES.txt +2 -1
- tilemap_parser-2.0.1/tests/test_collision_runner.py +110 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/LICENSE +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/README.md +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/setup.cfg +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser/__init__.py +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser/animation.py +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser/collision.py +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser/map_loader.py +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser/map_parse.py +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser/renderer.py +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser.egg-info/dependency_links.txt +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser.egg-info/requires.txt +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser.egg-info/top_level.txt +0 -0
- {tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/tests/test_collision.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tilemap-parser"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.1"
|
|
8
8
|
description = "Standalone parser/loader for tilemap-editor JSON maps and sprite animation JSON."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -67,8 +67,8 @@ def point_in_polygon(point: Point, vertices: List[Point]) -> bool:
|
|
|
67
67
|
if x <= max(p1x, p2x):
|
|
68
68
|
if p1y != p2y:
|
|
69
69
|
xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
if p1x == p2x or x <= xinters:
|
|
71
|
+
inside = not inside
|
|
72
72
|
p1x, p1y = p2x, p2y
|
|
73
73
|
|
|
74
74
|
return inside
|
|
@@ -13,4 +13,5 @@ src/tilemap_parser.egg-info/SOURCES.txt
|
|
|
13
13
|
src/tilemap_parser.egg-info/dependency_links.txt
|
|
14
14
|
src/tilemap_parser.egg-info/requires.txt
|
|
15
15
|
src/tilemap_parser.egg-info/top_level.txt
|
|
16
|
-
tests/test_collision.py
|
|
16
|
+
tests/test_collision.py
|
|
17
|
+
tests/test_collision_runner.py
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for tilemap_parser.collision_runner — focusing on correctness of
|
|
3
|
+
geometric utilities, especially the xinters bug fix in point_in_polygon.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
|
12
|
+
|
|
13
|
+
from tilemap_parser.collision_runner import point_in_polygon, CollisionRunner, MovementMode
|
|
14
|
+
from tilemap_parser.collision import CollisionCache, RectangleShape
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# ===========================================================================
|
|
18
|
+
# point_in_polygon
|
|
19
|
+
# ===========================================================================
|
|
20
|
+
|
|
21
|
+
# Simple axis-aligned square: (0,0) -> (10,0) -> (10,10) -> (0,10)
|
|
22
|
+
SQUARE = [(0.0, 0.0), (10.0, 0.0), (10.0, 10.0), (0.0, 10.0)]
|
|
23
|
+
|
|
24
|
+
# Triangle with a horizontal bottom edge — this is what triggered the xinters bug
|
|
25
|
+
# vertices: (0,0), (10,0), (5,10)
|
|
26
|
+
TRIANGLE_HORIZ_BASE = [(0.0, 0.0), (10.0, 0.0), (5.0, 10.0)]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TestPointInPolygon:
|
|
30
|
+
def test_inside_square(self):
|
|
31
|
+
assert point_in_polygon((5.0, 5.0), SQUARE) is True
|
|
32
|
+
|
|
33
|
+
def test_outside_square(self):
|
|
34
|
+
assert point_in_polygon((15.0, 5.0), SQUARE) is False
|
|
35
|
+
assert point_in_polygon((-1.0, 5.0), SQUARE) is False
|
|
36
|
+
assert point_in_polygon((5.0, -1.0), SQUARE) is False
|
|
37
|
+
assert point_in_polygon((5.0, 15.0), SQUARE) is False
|
|
38
|
+
|
|
39
|
+
def test_inside_triangle(self):
|
|
40
|
+
assert point_in_polygon((5.0, 5.0), TRIANGLE_HORIZ_BASE) is True
|
|
41
|
+
|
|
42
|
+
def test_outside_triangle(self):
|
|
43
|
+
assert point_in_polygon((0.5, 9.0), TRIANGLE_HORIZ_BASE) is False
|
|
44
|
+
assert point_in_polygon((9.5, 9.0), TRIANGLE_HORIZ_BASE) is False
|
|
45
|
+
|
|
46
|
+
# --- xinters bug regression tests ---
|
|
47
|
+
# A polygon with a horizontal edge at y=0. When the ray is cast from a point
|
|
48
|
+
# whose y equals the horizontal edge's y, the old code would read an
|
|
49
|
+
# uninitialised / stale xinters and flip `inside` incorrectly.
|
|
50
|
+
|
|
51
|
+
def test_horizontal_edge_does_not_use_stale_xinters(self):
|
|
52
|
+
# Point well inside — must not be flipped by the horizontal base edge
|
|
53
|
+
assert point_in_polygon((5.0, 5.0), TRIANGLE_HORIZ_BASE) is True
|
|
54
|
+
|
|
55
|
+
def test_point_below_horizontal_edge(self):
|
|
56
|
+
# y=-1 is outside regardless
|
|
57
|
+
assert point_in_polygon((5.0, -1.0), TRIANGLE_HORIZ_BASE) is False
|
|
58
|
+
|
|
59
|
+
def test_polygon_with_multiple_horizontal_edges(self):
|
|
60
|
+
# Rectangle has horizontal top and bottom edges
|
|
61
|
+
rect = [(0.0, 0.0), (20.0, 0.0), (20.0, 10.0), (0.0, 10.0)]
|
|
62
|
+
assert point_in_polygon((10.0, 5.0), rect) is True
|
|
63
|
+
assert point_in_polygon((10.0, 15.0), rect) is False
|
|
64
|
+
assert point_in_polygon((-1.0, 5.0), rect) is False
|
|
65
|
+
|
|
66
|
+
def test_first_iteration_no_unbound_xinters(self):
|
|
67
|
+
# Polygon whose very first edge is horizontal — this is the case that
|
|
68
|
+
# caused an UnboundLocalError before the fix (xinters never assigned
|
|
69
|
+
# yet when the stale-read branch was reached on i=1).
|
|
70
|
+
horiz_first = [(0.0, 5.0), (10.0, 5.0), (10.0, 0.0), (0.0, 0.0)]
|
|
71
|
+
# Point inside
|
|
72
|
+
assert point_in_polygon((5.0, 2.0), horiz_first) is True
|
|
73
|
+
# Point outside
|
|
74
|
+
assert point_in_polygon((5.0, 8.0), horiz_first) is False
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# ===========================================================================
|
|
78
|
+
# CollisionRunner construction
|
|
79
|
+
# ===========================================================================
|
|
80
|
+
|
|
81
|
+
class TestCollisionRunnerConstruction:
|
|
82
|
+
def test_from_game_type_platformer(self):
|
|
83
|
+
cache = CollisionCache()
|
|
84
|
+
runner = CollisionRunner.from_game_type("platformer", cache, (32, 32))
|
|
85
|
+
assert runner.mode == MovementMode.PLATFORMER
|
|
86
|
+
assert runner.gravity > 0
|
|
87
|
+
|
|
88
|
+
def test_from_game_type_topdown(self):
|
|
89
|
+
cache = CollisionCache()
|
|
90
|
+
runner = CollisionRunner.from_game_type("topdown", cache, (32, 32))
|
|
91
|
+
assert runner.mode == MovementMode.SLIDE
|
|
92
|
+
assert runner.gravity == 0.0
|
|
93
|
+
|
|
94
|
+
def test_from_game_type_rpg(self):
|
|
95
|
+
cache = CollisionCache()
|
|
96
|
+
runner = CollisionRunner.from_game_type("rpg", cache, (32, 32))
|
|
97
|
+
assert runner.mode == MovementMode.RPG
|
|
98
|
+
assert runner.gravity == 0.0
|
|
99
|
+
|
|
100
|
+
def test_unknown_game_type_raises(self):
|
|
101
|
+
cache = CollisionCache()
|
|
102
|
+
with pytest.raises(ValueError):
|
|
103
|
+
CollisionRunner.from_game_type("unknown", cache, (32, 32))
|
|
104
|
+
|
|
105
|
+
def test_platformer_zero_gravity_raises(self):
|
|
106
|
+
cache = CollisionCache()
|
|
107
|
+
runner = CollisionRunner.from_game_type("platformer", cache, (32, 32))
|
|
108
|
+
runner.gravity = 0.0
|
|
109
|
+
with pytest.raises(ValueError):
|
|
110
|
+
runner.validate_config()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_parser-2.0.0 → tilemap_parser-2.0.1}/src/tilemap_parser.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|