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 @@ -36,6 +36,7 @@ Arcade [PyPi Release History](https://pypi.org/project/arcade/#history) page.
- Added a "Drawing Text" page to the programming guide: choosing between `draw_text`, `Text`, `TextPool`, and `create_text_sprite`, what's slow and fast to change, batches, fonts (names, font files, and the bundled Kenney and Liberation fonts), and styles. Updated the text section of the performance tips, and the `draw_text` warning and docstring, which overstated how slow it is.
- Tile maps no longer use Pillow's `Image.getdata()`, which is deprecated and will be removed in Pillow 14, to apply an image layer's transparent color. It's done with Pillow operations instead, which is also faster (a 1024x600 image went from 76 ms to 4 ms).
- Sped up removing many sprites from a large `SpriteList`, such as every bullet that hit something this frame. `SpriteList.remove()`, and so `Sprite.remove_from_sprite_lists()` and `kill()`, used to search the whole list for each sprite. Removals now wait until the list is next used, and many are applied in one pass: removing 100 sprites from 41,000 went from 19 ms to 3.3 ms, and 500 from 166,000 went from 630 ms to 17 ms. Drawing order is kept, and a few removals cost the same as before.
- Documented choosing a spatial hash cell size (`spatial_hash_cell_size`) in the performance tips and the `SpriteList` docs: about the size of the sprites in the list. With 4 pixel sprites, collision checks were 16 times faster with 8 pixel cells than with the default of 128.

## 4.0.0.dev8

Expand Down
10 changes: 8 additions & 2 deletions arcade/sprite_list/sprite_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ class SpriteList(SpriteSequence[SpriteType]):
with items in the SpriteList. Great for doing collision detection
with static walls/platforms in large maps.
spatial_hash_cell_size:
The cell size of the spatial hash (default: 128)
The cell size of the spatial hash, in pixels (default: 128).
Choose a size close to the size of the sprites in the list: much
bigger cells make collision checks slower, and much smaller ones
make adding and moving sprites slower. See
:ref:`collision_detection_performance_cell_size`.
atlas:
(Advanced) The texture atlas for this sprite list. If no
atlas is supplied the global/default one will be used.
Expand Down Expand Up @@ -898,7 +902,9 @@ def enable_spatial_hashing(self, spatial_hash_cell_size: int = 128) -> None:
Turn on spatial hashing unless it is already enabled with the same cell size.

Args:
spatial_hash_cell_size: The size of the cell in the spatial hash.
spatial_hash_cell_size: The size of the cell in the spatial hash,
in pixels. Choose a size close to the size of the sprites in
the list. See :ref:`collision_detection_performance_cell_size`.
"""
if self.spatial_hash is None or self.spatial_hash.cell_size != spatial_hash_cell_size:
from .spatial_hash import SpatialHash
Expand Down
51 changes: 51 additions & 0 deletions doc/programming_guide/performance_tips.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,57 @@ and storing the list inside a :py:class:`~arcade.Window` or
self.spritelist_with_hashing = arcade.SpriteList(use_spatial_hash=True)


.. _collision_detection_performance_cell_size:

Choosing a Cell Size
""""""""""""""""""""

The ``spatial_hash_cell_size`` argument sets the size of the grid
squares, in pixels. The default of 128 works well for typical tiles of
64 to 128 pixels. For other sprites, choose a cell size about the size of
the sprites in the list:

* **Cells much bigger than the sprites** make each collision check look at
every sprite in the nearby cells. With 4 pixel sprites, 128 pixel cells
hold about a thousand of them each.
* **Cells much smaller than the sprites** put each sprite in many cells, so
adding and moving sprites gets slower.

For example, measured on one desktop computer:

.. list-table::
:header-rows: 1

* - Sprites in the list
- Cell size 8
- Cell size 16
- Cell size 64
- Cell size 128 (default)
* - 4 pixels: 200 collision checks
- **2.1 ms**
- 2.8 ms
- 12.2 ms
- 33.4 ms
* - 64 pixels: 200 collision checks
- 5.7 ms
- 2.6 ms
- **2.3 ms**
- 3.1 ms
* - 64 pixels: adding 2,400 sprites
- 50.7 ms
- 22.9 ms
- 13.6 ms
- **11.6 ms**

.. code-block:: python

# Lots of small sprites, such as pixels or bullets
self.pixels = arcade.SpriteList(use_spatial_hash=True, spatial_hash_cell_size=16)

See :ref:`sprite_pixel_demolition` for an example with tens of thousands
of 3 pixel sprites.


Spatial Hashing and Tiled Maps
""""""""""""""""""""""""""""""
There is also a way to enable spatial hashing when loading Tiled maps. For
Expand Down
Loading