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.

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);