How to Detect When a Body Falls Asleep in Matter.js

In Matter.js, body sleeping is a performance optimization feature that halts physics calculations for rigid bodies that have come to a complete rest. Detecting when a body enters this dormant state can be achieved by enabling the engine's sleep module and listening to the sleepStart lifecycle event or by polling the body's isSleeping property. This article explains how to properly configure your Matter.js engine to allow sleep and how to hook into the sleep events to trigger game logic or visual changes.

1. Enable Sleeping on the Engine

By default, sleeping is disabled in Matter.js. Before you can detect a body falling asleep, you must explicitly enable sleeping when creating your engine or by modifying the engine instance:

// When creating the engine
const engine = Matter.Engine.create({
  enableSleeping: true
});

// Or updating an existing engine
engine.enableSleeping = true;

2. Detect Sleep via the sleepStart Event

The cleanest and most efficient way to detect when a body falls asleep is using the Matter.js event system. The Engine emits a sleepStart event whenever an individual body transitions from an active state to a sleeping state.

Matter.Events.on(engine, 'sleepStart', function(event) {
  const sleepingBody = event.source; // Or event.body depending on the Matter.js version

  console.log(`Body with ID ${sleepingBody.id} has fallen asleep.`);
  
  // Example: Change appearance or trigger logic
  sleepingBody.render.fillStyle = '#888888';
});

Note: Depending on the specific build of Matter.js you are using, the affected body is typically passed inside the event payload as event.source or event.body.

3. Check the isSleeping Boolean Property

If you need to check whether a body is asleep within your own tick or beforeUpdate loop rather than relying on an event, you can directly read the isSleeping property of any Matter.Body:

if (myBody.isSleeping) {
  // The body is currently asleep
  console.log('The body is currently resting.');
}

4. Detecting When a Body Wakes Up

To reverse any visual changes or resume tracking when a body starts moving again, pair your sleepStart listener with the sleepEnd event:

Matter.Events.on(engine, 'sleepEnd', function(event) {
  const awakeBody = event.source;

  console.log(`Body with ID ${awakeBody.id} has woken up.`);
  awakeBody.render.fillStyle = '#ff0000';
});

5. Adjusting Sleep Sensitivity

If a body falls asleep too quickly or takes too long to settle, you can adjust the sleepThreshold property on individual bodies. This defines how many consecutive frames of motion below the speed threshold are required before the body transitions to sleep:

const body = Matter.Bodies.rectangle(400, 200, 80, 80, {
  sleepThreshold: 60 // Number of idle frames before sleeping (default is 60)
});