How to Use Collision Categories in Matter.js
Collision categories in Matter.js allow you to control which physics
bodies interact and which pass through each other. By assigning bitwise
category flags and masks to bodies via their
collisionFilter properties, you can create complex
collision rules—such as allowing player projectiles to pass through the
player while still damaging enemies. This guide explains how to define
and implement collision categories using 32-bit integers in your
Matter.js projects.
Understanding the Collision Filter
Matter.js determines collisions using the
collisionFilter object on a body. This object contains
three primary properties:
category: A bitmask that defines what the body is.mask: A bitmask that defines which categories the body can collide with.group: An optional integer. If two bodies share the same non-zero group, a positive value forces them to always collide, and a negative value prevents them from ever colliding, overriding categories.
For two bodies (Body A and Body B) without
an overriding group to collide, both of the following bitwise conditions
must be true:
(bodyA.collisionFilter.category & bodyB.collisionFilter.mask) !== 0(bodyB.collisionFilter.category & bodyA.collisionFilter.mask) !== 0
Step 1: Define Your Categories
Because Matter.js uses bitwise operations, each category must be a power of two (representing a single bit in a 32-bit integer). Define your categories using hexadecimal values for clarity:
const defaultCategory = 0x0001; // 0001
const playerCategory = 0x0002; // 0010
const enemyCategory = 0x0004; // 0100
const bulletCategory = 0x0008; // 1000Matter.js supports up to 32 distinct categories (up to
0x80000000).
Step 2: Assign Categories and Masks to Bodies
When creating a body, set its category to the designated
flag and set its mask to the bitwise OR (|) of
all categories it should collide with.
Example: Player Body
The player should collide with the environment
(defaultCategory) and enemies (enemyCategory),
but ignore player bullets.
const player = Matter.Bodies.rectangle(100, 100, 50, 50, {
collisionFilter: {
category: playerCategory,
mask: defaultCategory | enemyCategory
}
});Example: Player Bullet
The bullet should only collide with enemies and the environment, ignoring the player who fired it.
const bullet = Matter.Bodies.circle(120, 100, 5, {
collisionFilter: {
category: bulletCategory,
mask: defaultCategory | enemyCategory
}
});Example: Enemy Body
The enemy should collide with the player, the environment, and the player's bullets.
const enemy = Matter.Bodies.rectangle(300, 100, 50, 50, {
collisionFilter: {
category: enemyCategory,
mask: defaultCategory | playerCategory | bulletCategory
}
});Common Collision Masks
- Collide with everything: Set
mask: 0xFFFFFFFF. - Collide with nothing: Set
mask: 0x00000000. - Collide with all except one: Use bitwise NOT
(
~), such asmask: ~playerCategory.