tilemap-parser 3.1.18__tar.gz → 3.1.20__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-3.1.18 → tilemap_parser-3.1.20}/PKG-INFO +2 -2
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/README.md +1 -1
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/pyproject.toml +1 -1
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/object_collision.py +100 -14
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/tile_collision.py +1 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser.egg-info/PKG-INFO +2 -2
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/tests/test_object_collision.py +122 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/LICENSE +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/setup.cfg +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/__init__.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/__init__.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/animation.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/collision.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/collision_loader.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/map_parse.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/node_parse.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/particle.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/__init__.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/animation_player.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/area_node.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/collision_cache.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/map_loader.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/particles.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/renderer.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/utils/__init__.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/utils/geometry.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser.egg-info/SOURCES.txt +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser.egg-info/dependency_links.txt +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser.egg-info/requires.txt +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser.egg-info/top_level.txt +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/tests/test_collision.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/tests/test_geometry.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/tests/test_map_loader.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/tests/test_object_surfaces.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/tests/test_render_scale.py +0 -0
- {tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/tests/test_tile_collision.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-parser
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.20
|
|
4
4
|
Summary: Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and collision detection runtime.
|
|
5
5
|
Author: tilemap parser contributors
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -706,7 +706,7 @@ Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and co
|
|
|
706
706
|
- **Map parsing**: Load and query tilemaps, layers, objects, and autotile data from JSON
|
|
707
707
|
- **Animation**: Frame-based sprite animation with `AnimationPlayer`
|
|
708
708
|
- **Collision (tile-based)**: Polygon collision detection for tilemaps with slide, platformer, and RPG movement modes via `CollisionRunner`
|
|
709
|
-
- **Collision (object-to-object)**:
|
|
709
|
+
- **Collision (object-to-object)**: Spatial-grid mixed-shape collision detection (rect, circle, capsule, polygon) with layer filtering via `ObjectCollisionManager`
|
|
710
710
|
- **Capsule support**: Full capsule collision against all shape types
|
|
711
711
|
- **Hit helpers**: `CollisionHit.resolve()`, `involves()`, `other()` for ergonomic separation
|
|
712
712
|
|
|
@@ -7,7 +7,7 @@ Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and co
|
|
|
7
7
|
- **Map parsing**: Load and query tilemaps, layers, objects, and autotile data from JSON
|
|
8
8
|
- **Animation**: Frame-based sprite animation with `AnimationPlayer`
|
|
9
9
|
- **Collision (tile-based)**: Polygon collision detection for tilemaps with slide, platformer, and RPG movement modes via `CollisionRunner`
|
|
10
|
-
- **Collision (object-to-object)**:
|
|
10
|
+
- **Collision (object-to-object)**: Spatial-grid mixed-shape collision detection (rect, circle, capsule, polygon) with layer filtering via `ObjectCollisionManager`
|
|
11
11
|
- **Capsule support**: Full capsule collision against all shape types
|
|
12
12
|
- **Hit helpers**: `CollisionHit.resolve()`, `involves()`, `other()` for ergonomic separation
|
|
13
13
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tilemap-parser"
|
|
7
|
-
version = "3.1.
|
|
7
|
+
version = "3.1.20"
|
|
8
8
|
description = "Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and collision detection runtime."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
{tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/object_collision.py
RENAMED
|
@@ -9,7 +9,8 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
import warnings
|
|
11
11
|
from dataclasses import dataclass
|
|
12
|
-
from
|
|
12
|
+
from math import floor, isfinite
|
|
13
|
+
from typing import Dict, Iterable, Iterator, List, Optional, Protocol, Set, Tuple, Union
|
|
13
14
|
|
|
14
15
|
from ..parser.collision import (
|
|
15
16
|
CapsuleShape,
|
|
@@ -310,16 +311,47 @@ class ObjectCollisionManager:
|
|
|
310
311
|
- All-vs-all and one-vs-all queries
|
|
311
312
|
- Layer filtering
|
|
312
313
|
|
|
313
|
-
|
|
314
|
-
|
|
314
|
+
Uses a uniform-grid spatial broadphase and exact shape narrowphase.
|
|
315
|
+
The grid is rebuilt for each query so moved objects are always indexed
|
|
316
|
+
at their current world positions.
|
|
315
317
|
"""
|
|
316
318
|
|
|
317
|
-
def __init__(
|
|
319
|
+
def __init__(
|
|
320
|
+
self,
|
|
321
|
+
objects: Optional[Iterable[ICollidableObject]] = None,
|
|
322
|
+
*,
|
|
323
|
+
cell_size: float = 128.0,
|
|
324
|
+
) -> None:
|
|
325
|
+
if not isfinite(cell_size) or cell_size <= 0:
|
|
326
|
+
raise ValueError("cell_size must be a finite positive number")
|
|
327
|
+
|
|
318
328
|
self.objects: List[ICollidableObject] = []
|
|
329
|
+
self.cell_size = float(cell_size)
|
|
330
|
+
if objects is not None:
|
|
331
|
+
for obj in objects:
|
|
332
|
+
self.add_object(obj)
|
|
333
|
+
|
|
334
|
+
def __len__(self) -> int:
|
|
335
|
+
"""Return the number of objects currently managed."""
|
|
336
|
+
return len(self.objects)
|
|
337
|
+
|
|
338
|
+
def __iter__(self) -> Iterator[ICollidableObject]:
|
|
339
|
+
"""Iterate over managed objects in insertion order."""
|
|
340
|
+
return iter(self.objects)
|
|
341
|
+
|
|
342
|
+
def __contains__(self, obj: object) -> bool:
|
|
343
|
+
"""Return True if the exact object instance is managed."""
|
|
344
|
+
return any(existing is obj for existing in self.objects)
|
|
345
|
+
|
|
346
|
+
def _find_object_index(self, obj: ICollidableObject) -> int:
|
|
347
|
+
for index, existing in enumerate(self.objects):
|
|
348
|
+
if existing is obj:
|
|
349
|
+
return index
|
|
350
|
+
return -1
|
|
319
351
|
|
|
320
352
|
def add_object(self, obj: ICollidableObject) -> None:
|
|
321
353
|
"""Add an object to the collision system."""
|
|
322
|
-
if obj
|
|
354
|
+
if self._find_object_index(obj) != -1:
|
|
323
355
|
warnings.warn(
|
|
324
356
|
f"Object {obj} is already in the collision manager, skipping.",
|
|
325
357
|
UserWarning,
|
|
@@ -330,27 +362,78 @@ class ObjectCollisionManager:
|
|
|
330
362
|
|
|
331
363
|
def remove_object(self, obj: ICollidableObject) -> None:
|
|
332
364
|
"""Remove an object from the collision system."""
|
|
333
|
-
|
|
365
|
+
index = self._find_object_index(obj)
|
|
366
|
+
if index == -1:
|
|
334
367
|
warnings.warn(
|
|
335
368
|
f"Object {obj} is not in the collision manager, skipping.",
|
|
336
369
|
UserWarning,
|
|
337
370
|
stacklevel=2,
|
|
338
371
|
)
|
|
339
372
|
return
|
|
340
|
-
self.objects
|
|
373
|
+
del self.objects[index]
|
|
374
|
+
|
|
375
|
+
def clear(self) -> None:
|
|
376
|
+
"""Remove all objects from the collision system."""
|
|
377
|
+
self.objects.clear()
|
|
378
|
+
|
|
379
|
+
def _cells_for_aabb(
|
|
380
|
+
self,
|
|
381
|
+
aabb: tuple[float, float, float, float],
|
|
382
|
+
) -> Iterator[Tuple[int, int]]:
|
|
383
|
+
left, top, right, bottom = aabb
|
|
384
|
+
min_cell_x = floor(left / self.cell_size)
|
|
385
|
+
max_cell_x = floor(right / self.cell_size)
|
|
386
|
+
min_cell_y = floor(top / self.cell_size)
|
|
387
|
+
max_cell_y = floor(bottom / self.cell_size)
|
|
388
|
+
|
|
389
|
+
for cell_y in range(min_cell_y, max_cell_y + 1):
|
|
390
|
+
for cell_x in range(min_cell_x, max_cell_x + 1):
|
|
391
|
+
yield (cell_x, cell_y)
|
|
392
|
+
|
|
393
|
+
def _object_aabb(
|
|
394
|
+
self,
|
|
395
|
+
obj: ICollidableObject,
|
|
396
|
+
) -> tuple[float, float, float, float]:
|
|
397
|
+
return get_shape_aabb(obj.x, obj.y, obj.collision_shape)
|
|
398
|
+
|
|
399
|
+
def _build_spatial_index(
|
|
400
|
+
self,
|
|
401
|
+
) -> tuple[Tuple[ICollidableObject, ...], Dict[Tuple[int, int], List[int]]]:
|
|
402
|
+
objects = tuple(self.objects)
|
|
403
|
+
grid: Dict[Tuple[int, int], List[int]] = {}
|
|
404
|
+
|
|
405
|
+
for index, obj in enumerate(objects):
|
|
406
|
+
for cell in self._cells_for_aabb(self._object_aabb(obj)):
|
|
407
|
+
grid.setdefault(cell, []).append(index)
|
|
408
|
+
|
|
409
|
+
return objects, grid
|
|
410
|
+
|
|
411
|
+
def _candidate_indices(
|
|
412
|
+
self,
|
|
413
|
+
obj: ICollidableObject,
|
|
414
|
+
grid: Dict[Tuple[int, int], List[int]],
|
|
415
|
+
) -> Set[int]:
|
|
416
|
+
candidates: Set[int] = set()
|
|
417
|
+
for cell in self._cells_for_aabb(self._object_aabb(obj)):
|
|
418
|
+
candidates.update(grid.get(cell, ()))
|
|
419
|
+
return candidates
|
|
341
420
|
|
|
342
421
|
def check_all_collisions(self) -> List[CollisionHit]:
|
|
343
422
|
"""
|
|
344
|
-
Check every
|
|
423
|
+
Check every potentially colliding pair.
|
|
345
424
|
|
|
346
425
|
Returns a list of CollisionHit for all colliding pairs.
|
|
347
426
|
Each pair appears at most once (i, j) with j > i.
|
|
348
427
|
"""
|
|
428
|
+
objects, grid = self._build_spatial_index()
|
|
349
429
|
hits: List[CollisionHit] = []
|
|
350
|
-
|
|
351
|
-
for i in
|
|
352
|
-
|
|
353
|
-
|
|
430
|
+
|
|
431
|
+
for i, obj in enumerate(objects):
|
|
432
|
+
candidate_indices = self._candidate_indices(obj, grid)
|
|
433
|
+
for j in sorted(candidate_indices):
|
|
434
|
+
if j <= i:
|
|
435
|
+
continue
|
|
436
|
+
hit = check_collision(objects[i], objects[j])
|
|
354
437
|
if hit is not None:
|
|
355
438
|
hits.append(hit)
|
|
356
439
|
return hits
|
|
@@ -359,10 +442,13 @@ class ObjectCollisionManager:
|
|
|
359
442
|
"""
|
|
360
443
|
Check one object against all others.
|
|
361
444
|
|
|
362
|
-
|
|
445
|
+
The queried object does not need to be managed. If it is managed,
|
|
446
|
+
comparison with itself is skipped by identity.
|
|
363
447
|
"""
|
|
448
|
+
objects, grid = self._build_spatial_index()
|
|
364
449
|
hits: List[CollisionHit] = []
|
|
365
|
-
for
|
|
450
|
+
for index in sorted(self._candidate_indices(obj, grid)):
|
|
451
|
+
other = objects[index]
|
|
366
452
|
if other is obj:
|
|
367
453
|
continue
|
|
368
454
|
hit = check_collision(obj, other)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-parser
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.20
|
|
4
4
|
Summary: Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and collision detection runtime.
|
|
5
5
|
Author: tilemap parser contributors
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -706,7 +706,7 @@ Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and co
|
|
|
706
706
|
- **Map parsing**: Load and query tilemaps, layers, objects, and autotile data from JSON
|
|
707
707
|
- **Animation**: Frame-based sprite animation with `AnimationPlayer`
|
|
708
708
|
- **Collision (tile-based)**: Polygon collision detection for tilemaps with slide, platformer, and RPG movement modes via `CollisionRunner`
|
|
709
|
-
- **Collision (object-to-object)**:
|
|
709
|
+
- **Collision (object-to-object)**: Spatial-grid mixed-shape collision detection (rect, circle, capsule, polygon) with layer filtering via `ObjectCollisionManager`
|
|
710
710
|
- **Capsule support**: Full capsule collision against all shape types
|
|
711
711
|
- **Hit helpers**: `CollisionHit.resolve()`, `involves()`, `other()` for ergonomic separation
|
|
712
712
|
|
|
@@ -21,6 +21,7 @@ from tilemap_parser.parser.collision import (
|
|
|
21
21
|
CollisionPolygon,
|
|
22
22
|
RectangleShape,
|
|
23
23
|
)
|
|
24
|
+
import tilemap_parser.runtime.object_collision as object_collision_runtime
|
|
24
25
|
from tilemap_parser.runtime.object_collision import (
|
|
25
26
|
CollisionHit,
|
|
26
27
|
ObjectCollisionManager,
|
|
@@ -257,6 +258,22 @@ class TestManagerAddRemove:
|
|
|
257
258
|
assert "already" in str(w[0].message).lower()
|
|
258
259
|
assert len(mgr.objects) == 1
|
|
259
260
|
|
|
261
|
+
def test_add_value_equal_distinct_objects(self):
|
|
262
|
+
class EqualObject(_DummyObject):
|
|
263
|
+
def __eq__(self, other):
|
|
264
|
+
return isinstance(other, EqualObject)
|
|
265
|
+
|
|
266
|
+
mgr = ObjectCollisionManager()
|
|
267
|
+
a = EqualObject(0, 0)
|
|
268
|
+
b = EqualObject(20, 0)
|
|
269
|
+
|
|
270
|
+
mgr.add_object(a)
|
|
271
|
+
mgr.add_object(b)
|
|
272
|
+
|
|
273
|
+
assert len(mgr.objects) == 2
|
|
274
|
+
assert mgr.objects[0] is a
|
|
275
|
+
assert mgr.objects[1] is b
|
|
276
|
+
|
|
260
277
|
def test_remove_nonexistent_warns(self):
|
|
261
278
|
mgr = ObjectCollisionManager()
|
|
262
279
|
obj = _make_rect(0, 0, 10, 10)
|
|
@@ -267,8 +284,49 @@ class TestManagerAddRemove:
|
|
|
267
284
|
assert issubclass(w[0].category, UserWarning)
|
|
268
285
|
assert "not" in str(w[0].message).lower()
|
|
269
286
|
|
|
287
|
+
def test_remove_uses_identity_not_equality(self):
|
|
288
|
+
class EqualObject(_DummyObject):
|
|
289
|
+
def __eq__(self, other):
|
|
290
|
+
return isinstance(other, EqualObject)
|
|
291
|
+
|
|
292
|
+
mgr = ObjectCollisionManager()
|
|
293
|
+
a = EqualObject(0, 0)
|
|
294
|
+
b = EqualObject(20, 0)
|
|
295
|
+
mgr.add_object(a)
|
|
296
|
+
mgr.add_object(b)
|
|
297
|
+
|
|
298
|
+
mgr.remove_object(b)
|
|
299
|
+
|
|
300
|
+
assert len(mgr.objects) == 1
|
|
301
|
+
assert mgr.objects[0] is a
|
|
302
|
+
|
|
303
|
+
def test_construct_with_objects(self):
|
|
304
|
+
a = _make_rect(0, 0, 10, 10)
|
|
305
|
+
b = _make_rect(20, 0, 10, 10)
|
|
306
|
+
|
|
307
|
+
mgr = ObjectCollisionManager([a, b])
|
|
308
|
+
|
|
309
|
+
assert len(mgr) == 2
|
|
310
|
+
objects = list(mgr)
|
|
311
|
+
assert objects[0] is a
|
|
312
|
+
assert objects[1] is b
|
|
313
|
+
assert a in mgr
|
|
314
|
+
assert b in mgr
|
|
315
|
+
|
|
316
|
+
def test_clear(self):
|
|
317
|
+
mgr = ObjectCollisionManager([_make_rect(0, 0, 10, 10)])
|
|
318
|
+
|
|
319
|
+
mgr.clear()
|
|
320
|
+
|
|
321
|
+
assert len(mgr) == 0
|
|
322
|
+
assert mgr.objects == []
|
|
323
|
+
|
|
270
324
|
|
|
271
325
|
class TestManagerCheckAll:
|
|
326
|
+
def test_invalid_cell_size_raises(self):
|
|
327
|
+
with pytest.raises(ValueError, match="cell_size"):
|
|
328
|
+
ObjectCollisionManager(cell_size=0)
|
|
329
|
+
|
|
272
330
|
def test_no_duplicates(self):
|
|
273
331
|
"""Three overlapping circles — should produce exactly 3 pairs."""
|
|
274
332
|
mgr = ObjectCollisionManager()
|
|
@@ -286,6 +344,56 @@ class TestManagerCheckAll:
|
|
|
286
344
|
mgr.add_object(_make_rect(0, 0, 10, 10))
|
|
287
345
|
assert mgr.check_all_collisions() == []
|
|
288
346
|
|
|
347
|
+
def test_spatial_broadphase_skips_distant_pairs(self, monkeypatch):
|
|
348
|
+
mgr = ObjectCollisionManager(cell_size=16)
|
|
349
|
+
a = _make_rect(0, 0, 10, 10)
|
|
350
|
+
b = _make_rect(100, 0, 10, 10)
|
|
351
|
+
mgr.add_object(a)
|
|
352
|
+
mgr.add_object(b)
|
|
353
|
+
calls = []
|
|
354
|
+
|
|
355
|
+
def fake_check_collision(obj_a, obj_b):
|
|
356
|
+
calls.append((obj_a, obj_b))
|
|
357
|
+
return None
|
|
358
|
+
|
|
359
|
+
monkeypatch.setattr(
|
|
360
|
+
object_collision_runtime,
|
|
361
|
+
"check_collision",
|
|
362
|
+
fake_check_collision,
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
assert mgr.check_all_collisions() == []
|
|
366
|
+
assert calls == []
|
|
367
|
+
|
|
368
|
+
def test_large_object_spanning_cells_collides(self):
|
|
369
|
+
mgr = ObjectCollisionManager(cell_size=16)
|
|
370
|
+
large = _make_rect(0, 0, 64, 16)
|
|
371
|
+
small = _make_rect(48, 0, 8, 8)
|
|
372
|
+
mgr.add_object(large)
|
|
373
|
+
mgr.add_object(small)
|
|
374
|
+
|
|
375
|
+
hits = mgr.check_all_collisions()
|
|
376
|
+
|
|
377
|
+
assert len(hits) == 1
|
|
378
|
+
assert hits[0].object_a is large
|
|
379
|
+
assert hits[0].object_b is small
|
|
380
|
+
|
|
381
|
+
def test_moved_objects_are_reindexed_per_query(self):
|
|
382
|
+
mgr = ObjectCollisionManager(cell_size=16)
|
|
383
|
+
a = _make_rect(0, 0, 10, 10)
|
|
384
|
+
b = _make_rect(100, 0, 10, 10)
|
|
385
|
+
mgr.add_object(a)
|
|
386
|
+
mgr.add_object(b)
|
|
387
|
+
|
|
388
|
+
assert mgr.check_all_collisions() == []
|
|
389
|
+
|
|
390
|
+
b.x = 8
|
|
391
|
+
hits = mgr.check_all_collisions()
|
|
392
|
+
|
|
393
|
+
assert len(hits) == 1
|
|
394
|
+
assert hits[0].involves(a)
|
|
395
|
+
assert hits[0].involves(b)
|
|
396
|
+
|
|
289
397
|
|
|
290
398
|
class TestManagerCheckObject:
|
|
291
399
|
def test_returns_hits(self):
|
|
@@ -316,6 +424,20 @@ class TestManagerCheckObject:
|
|
|
316
424
|
hits = mgr.check_object(a)
|
|
317
425
|
assert hits == []
|
|
318
426
|
|
|
427
|
+
def test_unmanaged_query_object(self):
|
|
428
|
+
mgr = ObjectCollisionManager(cell_size=16)
|
|
429
|
+
query = _make_rect(0, 0, 10, 10)
|
|
430
|
+
managed = _make_rect(8, 0, 10, 10)
|
|
431
|
+
far = _make_rect(100, 0, 10, 10)
|
|
432
|
+
mgr.add_object(managed)
|
|
433
|
+
mgr.add_object(far)
|
|
434
|
+
|
|
435
|
+
hits = mgr.check_object(query)
|
|
436
|
+
|
|
437
|
+
assert len(hits) == 1
|
|
438
|
+
assert hits[0].object_a is query
|
|
439
|
+
assert hits[0].object_b is managed
|
|
440
|
+
|
|
319
441
|
|
|
320
442
|
# ---------------------------------------------------------------------------
|
|
321
443
|
# CollisionHit helpers
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/parser/collision_loader.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/animation_player.py
RENAMED
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser/runtime/collision_cache.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.18 → tilemap_parser-3.1.20}/src/tilemap_parser.egg-info/dependency_links.txt
RENAMED
|
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
|