How to Identify Colliding Bodies in Matter.js
This article explains how to determine which two physics bodies are
involved in a collision using Matter.js. When a collision occurs,
Matter.js fires collision events containing a list of contact pairs. By
inspecting the bodyA and bodyB properties on
each pair, along with labels or custom identifiers assigned to those
bodies, you can reliably identify which objects interacted and execute
game logic accordingly.
Listening to Collision Events
Matter.js provides three main collision events on the
Engine instance: collisionStart,
collisionActive, and collisionEnd. To inspect
collisions, attach an event listener to the engine:
Matter.Events.on(engine, 'collisionStart', function(event) {
const pairs = event.pairs;
for (let i = 0; i < pairs.length; i++) {
const bodyA = pairs[i].bodyA;
const bodyB = pairs[i].bodyB;
// Identification logic goes here
}
});The event.pairs array contains every distinct collision
occurring in the current physics step. Each element in this array has
two key properties: pair.bodyA and
pair.bodyB.
Identifying Bodies Using Labels
The standard approach to distinguish bodies is assigning a string to
the label property when creating the body:
const player = Matter.Bodies.rectangle(100, 100, 50, 50, { label: 'player' });
const ground = Matter.Bodies.rectangle(400, 600, 800, 50, { isStatic: true, label: 'ground' });Because Matter.js does not guarantee the order of bodyA
and bodyB, you must check both directions:
Matter.Events.on(engine, 'collisionStart', function(event) {
event.pairs.forEach(pair => {
const { bodyA, bodyB } = pair;
if (
(bodyA.label === 'player' && bodyB.label === 'ground') ||
(bodyA.label === 'ground' && bodyB.label === 'player')
) {
console.log('Player touched the ground');
}
});
});Identifying Bodies Using Custom Properties or References
If your application requires more specific data than a string label, you can attach custom properties or direct references to the body object upon creation:
const bullet = Matter.Bodies.circle(200, 200, 5, {
label: 'bullet',
plugin: { damage: 25, ownerId: 'player1' }
});Alternatively, compare object references directly if you hold a reference in scope:
if (bodyA === player || bodyB === player) {
const otherBody = bodyA === player ? bodyB : bodyA;
console.log('Player collided with:', otherBody.label);
}A Clean Helper Pattern
To avoid repetitive conditional statements, use a helper function that sorts or matches the pair:
function checkCollision(pair, labelA, labelB) {
return (
(pair.bodyA.label === labelA && pair.bodyB.label === labelB) ||
(pair.bodyA.label === labelB && pair.bodyB.label === labelA)
);
}
// Usage inside the event listener:
if (checkCollision(pair, 'player', 'enemy')) {
// Handle player-enemy interaction
}Using consistent labels and accounting for variable body ordering ensures reliable collision resolution across all your Matter.js simulations.