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.