Collision Filter Module
This module provides a CollisionFilter class for managing collision filtering parameters along with a CollisionCategoryRegistry class that handles the creation and lookup of named collision categories.
- Features:
Named category creation via a registry.
Methods that accept multiple categories at once.
Operator overloading (|) for combining CollisionFilter instances.
Introspection support (list_categories) for debugging.
Optional auto-creation of categories when unknown strings are encountered.
- Example usage:
>>> # With auto_create enabled, new categories are defined automatically: >>> filter_a = CollisionFilter(category="player", mask="enemy", group=0) >>> filter_a CollisionFilter(category=0x1, mask=0x2, group=0)
- class box2d.collision_filter.CollisionCategoryRegistry(auto_create: bool = False)[source]
A registry to manage named collision categories.
Each category is automatically assigned a unique bit. The valid bits run from 0x0001 to 0x8000, which gives up to 16 unique categories.
By default, auto_create is disabled (False) so that category names must be explicitly defined. This prevents typos from inadvertently creating new categories. However, the default registry below is created with auto_create=True for easier prototyping.
- define(name: str) int[source]
Define a new collision category with a unique bit, or return the existing bit if already defined.
- Parameters:
name – The name of the collision category.
- Returns:
The bitmask value assigned to this category.
- Raises:
ValueError if the maximum number of categories (16) is exceeded. –
Example
>>> reg = CollisionCategoryRegistry() >>> reg.define("player") 1 >>> reg.define("player") 1
- get(name: str) int[source]
Get the bitmask for a named category.
- Parameters:
name – The name of the collision category.
- Returns:
The bitmask associated with the category.
- Raises:
ValueError if the category has not been defined. –
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> reg.define("player") 1 >>> reg.get("player") 1
- list_categories() dict[source]
Return a copy of the defined categories.
- Returns:
A dictionary mapping category names to their bitmask values.
- Return type:
dict
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> reg.define("player") 1 >>> reg.list_categories() {'player': 1}
- parse(cat) int[source]
Convert a category provided as a string (name) or integer into an integer bitmask. When auto_create is enabled, automatically define new categories that haven’t been defined.
- Parameters:
cat – A collision category as a name or a bitmask.
- Returns:
The corresponding bitmask.
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> reg.parse("enemy") 1 >>> reg.parse("player") 2 >>> reg.parse(4) 4
- class box2d.collision_filter.CollisionFilter(category: int | str | list[int | str] | tuple[int | str] = 1, mask: int | str | list[int | str] | tuple[int | str] = 65535, group: int = 0, registry: CollisionCategoryRegistry = None)[source]
A helper class for managing Box2D collision filtering parameters.
- category
Bitmask representing the collision categories that this shape belongs to. It is used in combination with the mask to determine which collisions occur.
- Type:
int
- mask
Bitmask representing which collision categories this shape is allowed to interact with. When the bitwise AND of one shape’s category and another shape’s mask is nonzero, a collision is possible (subject to group filtering).
- Type:
int
- group
Collision group index for this shape. The group overrides normal category/mask filtering:
A value of 0 (the default) means no grouping; collision is determined solely by category and mask.
If both shapes share a nonzero group: - A positive value forces them to always collide. - A negative value forces them to never collide.
If the group values differ (or only one is nonzero), the standard category/mask rules are applied.
- Type:
int
The API is chainable and accepts categories (and masks) as either integers or names (resolved via a registry). The group is strictly an integer.
- Examples (Fluent Interface):
>>> f1 = CollisionFilter("player").allow_collision_with("enemy") >>> f2 = CollisionFilter("enemy").allow_collision_with("player") >>> f3 = CollisionFilter("ally").allow_collision_with("enemy") >>> f1 & f2 # checks if two collision filters would collide True >>> f1 & f3 True >>> f1 = f1.block_collision_with("ally") >>> f1 & f3 False
- __init__(category: int | str | list[int | str] | tuple[int | str] = 1, mask: int | str | list[int | str] | tuple[int | str] = 65535, group: int = 0, registry: CollisionCategoryRegistry = None)[source]
Initialize a new CollisionFilter.
- Parameters:
category (int or str or list) – The collision category bitmask, name, or list of names/bitmasks. If string(s) are provided, they are resolved via the registry. If a list is provided, all categories are combined with bitwise OR.
mask (int or str or list) – The collision mask bitmask, name, or list of names/bitmasks. Similarly, string(s) are resolved via the registry. If a list is provided, all masks are combined with bitwise OR.
group (int) –
The collision group index.
0 indicates no grouping; standard category/mask rules apply.
A nonzero value overrides the usual filtering, as follows: - If both shapes have the same nonzero positive group, they always collide. - If both shapes have the same nonzero negative group, they never collide.
registry (CollisionCategoryRegistry, optional) – The registry used for resolving category names. Defaults to the module-level default.
- Returns:
A new instance with the specified filtering parameters.
- Return type:
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> filter_a = CollisionFilter(category=0x1, mask=CollisionFilter.ALL, group=0, registry=reg) >>> filter_a CollisionFilter(category=0x1, mask=0xFFFF, group=0) >>> filter_b = CollisionFilter(category=["player", "ally"], mask=["enemy", "projectile"], registry=reg) >>> filter_b CollisionFilter(category=0x3, mask=0xC, group=0)
- add_category(*cats) CollisionFilter[source]
Add one or more collision categories to this filter.
- Parameters:
*cats – One or more collision categories (int or str) to be added.
- Returns:
Self, to allow chaining.
- Return type:
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> filter_a = CollisionFilter(category="player", registry=reg) >>> filter_a.add_category("ally", "powerup") CollisionFilter(category=0x7, mask=0xFFFF, group=0)
- allow_collision_with(*cats) CollisionFilter[source]
Allow collisions with one or more categories by including them in the mask.
- Parameters:
*cats – Collision categories (int or str) to allow.
- Returns:
Self, to allow chaining.
- Return type:
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> # Start with a filter whose mask is initially 0. >>> filter_a = CollisionFilter(category="player", mask=0, registry=reg) >>> filter_a.allow_collision_with("enemy") CollisionFilter(category=0x1, mask=0x2, group=0)
- property b2Filter
Convert this CollisionFilter into a Box2D b2Filter C structure.
- Returns:
A newly created b2Filter structure with the appropriate category, mask, and group values.
- Return type:
b2Filter
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> c_filter = CollisionFilter(category="player", mask="enemy", group=0, registry=reg).b2Filter >>> c_filter.categoryBits == 1 True >>> c_filter.maskBits == 2 True >>> c_filter.groupIndex == 0 True
- property b2QueryFilter
Convert this CollisionFilter into a Box2D b2QueryFilter C structure. The group is not included in the query filter.
- Returns:
A newly created b2QueryFilter structure with the appropriate category and mask values.
- Return type:
b2QueryFilter
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> c_filter = CollisionFilter(category="player", mask="enemy", group=0, registry=reg).b2QueryFilter >>> c_filter.categoryBits == 1 True >>> c_filter.maskBits == 2 True
- block_collision_with(*cats) CollisionFilter[source]
Block collisions with the specified categories.
This method updates the filter so that it does not allow collisions with the given categories. Unlike allow_collision_with(), which adds categories to the list of permitted collisions, this method marks the provided categories as blocked. In other words, it prevents interactions with those categories regardless of previous settings.
- Parameters:
*cats – One or more collision categories (int or str) to block.
- Returns:
Self, to allow chaining.
- Return type:
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> filter_a = CollisionFilter(category="player", mask=0xFFFF, registry=reg) >>> filter_a.block_collision_with("enemy") CollisionFilter(category=0x1, mask=0xFFFD, group=0)
- remove_category(*cats) CollisionFilter[source]
Remove one or more collision categories from this filter.
- Parameters:
*cats – Collision categories (int or str) to remove.
- Returns:
Self, to allow chaining.
- Return type:
Warning
A warning is emitted if a category that is not set is attempted to be removed.
Example
>>> import warnings >>> reg = CollisionCategoryRegistry(auto_create=True) >>> filter_a = CollisionFilter(category="player", registry=reg) >>> filter_a.remove_category("player") CollisionFilter(category=0x0, mask=0xFFFF, group=0)
- set_group(group: int) CollisionFilter[source]
Set the collision group index for this filter.
- Parameters:
group (int) –
The collision group index.
0: No overriding group filtering—the standard category/mask rules apply.
Nonzero: Overrides the default filtering when both shapes share the same group. - Positive values force an always collide scenario. - Negative values force a never collide scenario.
- Returns:
Self, to allow chaining.
- Return type:
Example
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> filter_a = CollisionFilter(category="player", registry=reg) >>> filter_a.set_group(5) CollisionFilter(category=0x1, mask=0xFFFF, group=5)
- box2d.collision_filter.filters_collide(filter_a: CollisionFilter, filter_b: CollisionFilter) bool[source]
Determine if two collision filters would allow a collision.
- Collision is determined as follows:
Group filtering: If both filters share the same nonzero group:
A positive group forces collision.
A negative group prevents collision.
Otherwise, collision occurs if: (filter_a.category & filter_b.mask) != 0 and (filter_b.category & filter_a.mask) != 0
- Parameters:
filter_a (CollisionFilter) – The first collision filter.
filter_b (CollisionFilter) – The second collision filter.
- Returns:
True if the filters would allow a collision, False otherwise.
- Return type:
bool
Examples
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> f1 = CollisionFilter(category="player", mask="enemy", group=0, registry=reg) >>> f2 = CollisionFilter(category="enemy", mask="player", group=0, registry=reg) >>> filters_collide(f1, f2) True
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> f3 = CollisionFilter(category="player", mask="enemy", group=3, registry=reg) >>> f4 = CollisionFilter(category="enemy", mask="player", group=3, registry=reg) >>> filters_collide(f3, f4) True
>>> reg = CollisionCategoryRegistry(auto_create=True) >>> f5 = CollisionFilter(category="player", mask="enemy", group=-2, registry=reg) >>> f6 = CollisionFilter(category="enemy", mask="player", group=-2, registry=reg) >>> filters_collide(f5, f6) False