How to Create Sensor Bodies in Matter.js
In Matter.js, a sensor body is a physics body that detects collisions
and triggers events without producing physical forces, friction, or
bounces against other objects. This article explains how to configure a
body as a sensor using the isSensor flag, listen for
overlap events using the engine's event system, and apply this pattern
for gameplay triggers such as checkpoints, pickups, and zone
detection.
Setting the isSensor
Property
To convert any standard rigid body into a sensor, set its
isSensor property to true. This property can
be defined directly during the body's initialization or toggled
dynamically on an existing body.
On Initialization
Pass isSensor: true within the options object when
creating a body:
const { Bodies } = Matter;
// Create a rectangular sensor zone
const triggerZone = Bodies.rectangle(400, 300, 200, 100, {
isSensor: true,
isStatic: true, // Typically static if used as an area trigger
render: {
fillStyle: 'rgba(0, 255, 0, 0.3)',
strokeStyle: 'green',
lineWidth: 1
}
});Dynamically Updating an Existing Body
To turn an existing solid body into a sensor or vice versa at
runtime, use the Body.set method:
const { Body } = Matter;
// Enable sensor mode
Body.set(myBody, 'isSensor', true);
// Disable sensor mode (reverts to solid physical interactions)
Body.set(myBody, 'isSensor', false);Detecting Sensor Collisions
Because sensor bodies do not physically interact with other bodies,
you must handle interactions through the Matter.Events
module by listening to collision lifecycle events:
collisionStart, collisionActive, and
collisionEnd.
Listening for Collisions
The collisionStart event fires the first frame two
bodies overlap:
const { Events } = Matter;
Events.on(engine, 'collisionStart', (event) => {
const pairs = event.pairs;
for (let i = 0; i < pairs.length; i++) {
const { bodyA, bodyB } = pairs[i];
// Check if one of the bodies is our trigger zone
if (bodyA === triggerZone || bodyB === triggerZone) {
const otherBody = bodyA === triggerZone ? bodyB : bodyA;
console.log('An object entered the sensor zone:', otherBody);
// Trigger game logic, such as awarding points or opening a door
}
}
});Detecting Exit Events
To detect when an object leaves the sensor's boundary, listen to the
collisionEnd event using the exact same pair-checking
logic:
Events.on(engine, 'collisionEnd', (event) => {
const pairs = event.pairs;
for (let i = 0; i < pairs.length; i++) {
const { bodyA, bodyB } = pairs[i];
if (bodyA === triggerZone || bodyB === triggerZone) {
const otherBody = bodyA === triggerZone ? bodyB : bodyA;
console.log('An object exited the sensor zone:', otherBody);
}
}
});Controlling Which Bodies Trigger the Sensor
Sensors obey the same collisionFilter rules as standard
rigid bodies. If a sensor should only detect specific bodies (such as
the player character and not background projectiles), configure the
category and mask bitmasks on the sensor's
collisionFilter:
const PLAYER_CATEGORY = 0x0001;
const ENEMY_CATEGORY = 0x0002;
const playerDetector = Bodies.circle(400, 200, 50, {
isSensor: true,
isStatic: true,
collisionFilter: {
category: 0x0004,
mask: PLAYER_CATEGORY // Only reports collisions with bodies belonging to PLAYER_CATEGORY
}
});