How to Detect Added Bodies Using Matter.js Events
Matter.js features an internal event pipeline that enables you to track changes to the physics simulation in real time. This article explains how to detect when a rigid body is added to a Matter.js world by subscribing to composite lifecycle events, inspecting the event payload to verify body instances, and handling dynamically added objects cleanly.
Using the afterAdd
Event
In Matter.js, the root physics simulation world
(engine.world) is an instance of
Matter.Composite. When an entity is introduced using
Composite.add() or World.add(), Matter.js
dispatches events directly to that composite.
To detect when an element is added, use the
Matter.Events.on method to listen for the
afterAdd event on the target world or composite.
const { Engine, Events, Bodies, Composite } = Matter;
const engine = Engine.create();
const world = engine.world;
// Listen for additions to the world
Events.on(world, 'afterAdd', (event) => {
console.log('An object was added:', event.object);
});The afterAdd event fires immediately after the object is
inserted into the composite's internal lists. If you need to intercept
or modify state prior to the addition being finalized, you can use the
beforeAdd event instead.
Filtering for Rigid Bodies
The afterAdd event fires for any object type added to
the composite, including constraints, nested composites, and arrays of
items. To specifically target bodies, check the type
property of the injected object:
Events.on(world, 'afterAdd', (event) => {
const addedObject = event.object;
// Handle single body additions
if (addedObject.type === 'body') {
handleNewBody(addedObject);
}
// Handle bulk additions where an array of bodies was passed
else if (Array.isArray(addedObject)) {
addedObject.forEach((item) => {
if (item.type === 'body') {
handleNewBody(item);
}
});
}
});
function handleNewBody(body) {
console.log(`Detected body: ${body.label} (ID: ${body.id})`);
}Practical Applications
Listening to body additions allows you to decouple your physics logic from other systems in your application:
- Renderer Synchronization: Bind rendering sprites or meshes (such as PixiJS or Three.js objects) to the newly created physics body.
- Property Initialization: Apply custom properties, collision categories, or default velocities right as an object enters the world.
- Entity Tracking: Maintain a separate active entity registry or UI counter without coupling object creation directly to UI code.