How to Detect Body Wake Up in Matter.js

This article explains how to detect when a rigid body wakes up from a sleeping state in the Matter.js 2D physics engine. You will learn how to enable the sleeping module, attach event listeners directly to bodies using the built-in sleepEnd event, and handle global wake-up detection across multiple bodies within your physics world.

Enabling the Sleeping Module

By default, body sleeping is disabled in Matter.js. To allow bodies to sleep when stationary and subsequently wake up upon interaction, you must enable enableSleeping on your engine instance before or during its creation:

const engine = Matter.Engine.create({
    enableSleeping: true
});

When this property is true, stationary bodies transition to isSleeping = true after a period of inactivity, saving processing cycles. Any collision, force application, or manual position shift will wake the body up, setting isSleeping back to false.

Listening to the sleepEnd Event

Matter.js fires a sleepEnd event directly on the individual body instance whenever it transitions from a sleeping state to an active state. You can listen to this event using Matter.Events.on():

const { Bodies, Events, Composite } = Matter;

// Create a body
const box = Bodies.rectangle(400, 200, 80, 80);
Composite.add(engine.world, box);

// Detect when the body wakes up
Events.on(box, 'sleepEnd', function(event) {
    const body = event.source;
    console.log(`Body with ID ${body.id} has woken up!`);
});

In the handler, event.source references the specific body that was awakened.

Detecting Wake-Ups Across All Bodies

If you need to monitor wake-ups globally rather than on a single body, you can attach the sleepEnd listener automatically whenever a body is added to the world, or dynamically scan active bodies in the engine update loop.

Method 1: Attaching Listeners to Newly Added Bodies

Use the world composite's afterAdd event to bind the sleepEnd event to every body added to the simulation:

Events.on(engine.world, 'afterAdd', function(event) {
    event.object.forEach(item => {
        if (item.type === 'body') {
            Events.on(item, 'sleepEnd', function(e) {
                console.log('A body woke up:', e.source);
            });
        }
    });
});

Method 2: Polling with Engine Updates

If you prefer state polling rather than individual event bindings, you can track the previous isSleeping state of all bodies in the beforeUpdate and afterUpdate cycles:

const sleepingStates = new Map();

Events.on(engine, 'beforeUpdate', function() {
    const bodies = Matter.Composite.allBodies(engine.world);
    for (let i = 0; i < bodies.length; i++) {
        const body = bodies[i];
        const wasSleeping = sleepingStates.get(body.id) ?? false;

        // If the body was sleeping, but is no longer sleeping
        if (wasSleeping && !body.isSleeping) {
            console.log(`Body ${body.id} woke up`);
        }

        // Update the cached state
        sleepingStates.set(body.id, body.isSleeping);
    }
});

Manually Waking a Body

To programmatically wake up a body and trigger the corresponding state change, use the Matter.Sleeping.set method:

Matter.Sleeping.set(box, false);

Passing false updates body.isSleeping to false and dispatches the sleepEnd event immediately.