Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Arcade [PyPi Release History](https://pypi.org/project/arcade/#history) page.
### Misc Changes
- Sped up sprite collision checks. Sprites that pass the quick distance check are now compared by cached hit box bounds before the polygon test, and the polygon test skips horizontal and vertical edges, which the bounds check already covers. Checks that reach the polygon test are about 2-4x faster, e.g. 8.0 to 2.3 µs for two box hit boxes and 21.6 to 10.2 µs for two default octagon hit boxes. `are_polygons_intersecting` is also faster (7.3 to 1.6 µs for two rectangles).
- Sped up collision checks further by caching each hit box's distinct edge directions. Parallel edges (such as opposite sides of the default octagon hit boxes, or matching edges on two sprites with the same angle) are only tested once, and the cache is kept when a sprite moves. Two unrotated octagon hit boxes go from 12.0 to 4.6 µs, and two rotated 30° from 20.8 to 6.9 µs.
- `SpatialHash` now uses the hit box's cached bounds to find a sprite's grid cells, so they're shared with collision checks. Adding, removing, and querying for sprites that haven't moved is about 33-40% faster.
- Added collision benchmark scripts in `benchmarks/collisions/` (`micro.py`, `hit_box.py`, and `compare_reference.py`, which checks collision results against a simple reference on random sprite pairs) and `benchmarks/spatial_hash/queries.py`.
- Updated the optional `pymunk` extra to 7.3.0 (from 7.2.0). Packaging-only release (free-threaded CPython and pyodide wheels, improved type hints) with no breaking changes or deprecations.

Expand Down
9 changes: 4 additions & 5 deletions arcade/sprite_list/spatial_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ def reset(self):

def _get_cell_bounds(self, sprite: BasicSprite) -> tuple[IPoint, IPoint]:
"""Get the min and max cells covered by a sprite's hit box."""
# One pass over the points instead of using left/right/bottom/top,
# which each fetch and scan the hit box points separately.
x_points, y_points = zip(*sprite.hit_box.get_adjusted_points())
min_point = self.hash((trunc(min(x_points)), trunc(min(y_points))))
max_point = self.hash((trunc(max(x_points)), trunc(max(y_points))))
# The hit box caches its bounds, so collision checks can reuse them
left, right, bottom, top = sprite.hit_box.get_adjusted_bounds()
min_point = self.hash((trunc(left), trunc(bottom)))
max_point = self.hash((trunc(right), trunc(top)))
return min_point, max_point

def add(self, sprite: SpriteType) -> None:
Expand Down
Loading