Matter.js Events on a Specific Body

Matter.js does not provide a built-in mechanism to attach event listeners directly to individual physics bodies. Instead, all collision and lifecycle events are handled globally through the Engine using the Matter.Events module. To listen for events on a specific body, you must listen to the engine's global events and filter for the target body, or attach custom event handlers to the body object that trigger during global updates.

Filtering Global Collision Events

The standard way to detect collisions involving a specific body is by listening to collisionStart, collisionActive, or collisionEnd on the Engine and inspecting each collision pair.

const { Engine, Events } = Matter;

const engine = Engine.create();
const myBody = Bodies.circle(100, 100, 20);

Events.on(engine, 'collisionStart', (event) => {
    const pairs = event.pairs;

    for (let i = 0; i < pairs.length; i++) {
        const pair = pairs[i];

        if (pair.bodyA === myBody || pair.bodyB === myBody) {
            const otherBody = pair.bodyA === myBody ? pair.bodyB : pair.bodyA;
            console.log('Collision detected on myBody with:', otherBody);
        }
    }
});

Implementing a Custom Per-Body Event System

If your application has many individual bodies requiring their own collision logic, checking bodies manually inside a single listener can become cluttered. You can simplify this by attaching custom callbacks directly to the body and iterating through them globally.

// Attach a custom callback directly to the body
myBody.onCollide = (otherBody) => {
    console.log('Collided with:', otherBody);
};

// Set up a single global dispatcher
Events.on(engine, 'collisionStart', (event) => {
    event.pairs.forEach((pair) => {
        if (pair.bodyA.onCollide) {
            pair.bodyA.onCollide(pair.bodyB);
        }
        if (pair.bodyB.onCollide) {
            pair.bodyB.onCollide(pair.bodyA);
        }
    });
});

Monitoring Movement and Position Changes

For body updates outside collisions (such as position or rotation changes), Matter.js does not emit per-body change events. You can monitor individual body updates by listening to the engine's beforeUpdate or afterUpdate events and reading the target body's properties directly:

Events.on(engine, 'afterUpdate', () => {
    // Read or react to specific body changes each tick
    const currentPosition = myBody.position;
    const currentVelocity = myBody.velocity;
});