How to Subscribe to collisionStart in Matter.js
This article provides a concise guide on how to subscribe to the
collisionStart event in the Matter.js 2D physics engine.
You will learn how to attach an event listener to the engine instance,
retrieve collision pairs, and identify the specific bodies involved when
a collision begins.
Setting Up the Event Listener
Matter.js provides an Events module specifically for
listening to simulation state changes. To detect the exact moment two
bodies begin colliding, subscribe to the collisionStart
event on your engine instance using
Matter.Events.on.
// Import modules if using ES6, or reference from the global Matter object
const { Engine, Render, Runner, Bodies, Composite, Events } = Matter;
// Create the engine
const engine = Engine.create();
// Subscribe to the collisionStart event
Events.on(engine, 'collisionStart', (event) => {
const pairs = event.pairs;
for (let i = 0; i < pairs.length; i++) {
const bodyA = pairs[i].bodyA;
const bodyB = pairs[i].bodyB;
console.log('Collision detected between:', bodyA.label, 'and', bodyB.label);
}
});Understanding the Collision Event Data
When the collisionStart event fires, it passes an event
object containing a pairs array.
event.pairs: A list of all collision pairs that initiated contact during the current physics tick.pair.bodyAandpair.bodyB: The two collidingMatter.Bodyobjects. The order ofbodyAandbodyBis determined internally and is not guaranteed, so your logic should account for either body appearing in either position.
Identifying Specific Collisions
To target specific objects, assign labels, categories, or custom properties when creating the bodies, then check those properties within the event callback.
const player = Bodies.circle(100, 100, 20, { label: 'player' });
const coin = Bodies.circle(200, 100, 10, { label: 'coin', isSensor: true });
Composite.add(engine.world, [player, coin]);
Events.on(engine, 'collisionStart', (event) => {
event.pairs.forEach((pair) => {
const { bodyA, bodyB } = pair;
const isPlayerAndCoin =
(bodyA.label === 'player' && bodyB.label === 'coin') ||
(bodyA.label === 'coin' && bodyB.label === 'player');
if (isPlayerAndCoin) {
console.log('Player collected the coin!');
}
});
});Unsubscribing from the Event
If you need to remove the event listener later, use
Matter.Events.off:
function handleCollision(event) {
// Collision logic
}
// Subscribe
Events.on(engine, 'collisionStart', handleCollision);
// Unsubscribe
Events.off(engine, 'collisionStart', handleCollision);