How to Use Collision Masks in Matter.js

This guide explains how to control object interactions in Matter.js using collision categories and masks. By leveraging bitwise flags, you can precisely define which physics bodies collide with one another and which pass through each other harmlessly. You will learn the mechanics behind the collisionFilter object, how to define unique categories, and how to write clear code to enforce these rules in your simulation.


Understanding the Collision Filter

Matter.js uses a collisionFilter object attached to each body to determine whether two bodies can physically interact. This object contains two primary properties relevant to masking:

For two bodies, bodyA and bodyB, to collide, both of the following conditions must be met:

(bodyA.collisionFilter.mask & bodyB.collisionFilter.category) !== 0
(bodyB.collisionFilter.mask & bodyA.collisionFilter.category) !== 0

If either evaluation results in 0, no collision will occur.


Defining Categories with Bitwise Flags

Categories in Matter.js must be powers of two (up to 32 unique categories, representing 32-bit integers). You can define these using hexadecimal notation or bit-shift operators:

const defaultCategory = 0x0001; // 1 << 0
const playerCategory  = 0x0002; // 1 << 1
const enemyCategory   = 0x0004; // 1 << 2
const groundCategory  = 0x0008; // 1 << 3
const bulletCategory  = 0x0010; // 1 << 4

Combining Categories for the Mask

To allow a body to collide with multiple categories, combine those categories using the bitwise OR operator (|).

Example Scenario


Implementation Example

const { Bodies } = Matter;

// 1. Define Categories
const CATEGORY_GROUND = 0x0001;
const CATEGORY_PLAYER = 0x0002;
const CATEGORY_ENEMY  = 0x0004;
const CATEGORY_BULLET = 0x0008;

// 2. Create the Ground
const ground = Bodies.rectangle(400, 600, 800, 50, {
  isStatic: true,
  collisionFilter: {
    category: CATEGORY_GROUND,
    mask: CATEGORY_PLAYER | CATEGORY_ENEMY | CATEGORY_BULLET
  }
});

// 3. Create the Player
const player = Bodies.circle(200, 200, 30, {
  collisionFilter: {
    category: CATEGORY_PLAYER,
    // Collides with ground and enemy, ignores bullets
    mask: CATEGORY_GROUND | CATEGORY_ENEMY
  }
});

// 4. Create the Bullet
const bullet = Bodies.circle(250, 200, 5, {
  collisionFilter: {
    category: CATEGORY_BULLET,
    // Collides with ground and enemy, ignores player
    mask: CATEGORY_GROUND | CATEGORY_ENEMY
  }
});

// 5. Create an Enemy
const enemy = Bodies.rectangle(500, 200, 40, 40, {
  collisionFilter: {
    category: CATEGORY_ENEMY,
    // Collides with ground, player, and bullets
    mask: CATEGORY_GROUND | CATEGORY_PLAYER | CATEGORY_BULLET
  }
});

Important Considerations