How to Separate a Compound Body in Matter.js
This article explains how to disassemble a compound body into
independent rigid bodies in the Matter.js 2D physics engine. In
Matter.js, compound bodies are formed by assigning multiple child bodies
to a parent body's parts array. Separating them involves
removing the compound entity from the physics world, resetting each
child body's parent reference and transformation properties, and adding
the individual parts back to the world composite.
Understanding Matter.js Compound Body Structure
When a compound body is instantiated, Matter.js creates a hierarchy
stored within the body.parts array.
- The element at index
0(body.parts[0]) is the parent compound body itself. - Elements from index
1onward (body.parts.slice(1)) are the constituent child bodies. - Each child body has its
parentproperty linked directly to the parent compound body.
To return these parts to standalone bodies, you must decouple this relationship and recalculate their physical properties.
Step-by-Step Separation Process
1. Extract the Child Parts
Retrieve the individual bodies while excluding the root parent:
const childBodies = compoundBody.parts.slice(1);2. Remove the Compound Body from the World
Remove the original compound body from your Matter.js engine world composite to stop processing its combined physics:
Matter.Composite.remove(engine.world, compoundBody);3. Reset Body Hierarchies and Transformations
Before adding the parts back as standalone bodies, unlink the parent
reference and synchronize their current world coordinates. When part of
a compound body, a part's absolute coordinates are tracked by Matter.js,
but unlinking requires setting part.parent = part:
childBodies.forEach((part) => {
// Unlink the parent reference
part.parent = part;
// Re-establish independent physics properties
Matter.Body.setAngle(part, part.angle);
Matter.Body.setPosition(part, { x: part.position.x, y: part.position.y });
Matter.Body.setVelocity(part, { x: compoundBody.velocity.x, y: compoundBody.velocity.y });
Matter.Body.setAngularVelocity(part, compoundBody.angularVelocity);
// Clear compound-specific parts list on the individual body
part.parts = [part];
});4. Add the Individual Bodies to the World
Finally, add the modified child bodies back into the physics simulation:
Matter.Composite.add(engine.world, childBodies);Complete Reusable Function
Below is a complete helper function that safely separates any compound body into its original components:
function separateCompoundBody(engine, compoundBody) {
if (!compoundBody.parts || compoundBody.parts.length <= 1) {
return [compoundBody];
}
// 1. Extract the constituent parts (skip index 0)
const individualBodies = compoundBody.parts.slice(1);
// 2. Remove the main compound body from the world
Matter.Composite.remove(engine.world, compoundBody);
// 3. Reset each body to be its own root entity
individualBodies.forEach((body) => {
body.parent = body;
body.parts = [body];
// Preserve world transformations and linear/angular momentum
Matter.Body.setPosition(body, { x: body.position.x, y: body.position.y });
Matter.Body.setAngle(body, body.angle);
Matter.Body.setVelocity(body, {
x: compoundBody.velocity.x,
y: compoundBody.velocity.y
});
Matter.Body.setAngularVelocity(body, compoundBody.angularVelocity);
});
// 4. Re-insert independent bodies into the world
Matter.Composite.add(engine.world, individualBodies);
return individualBodies;
}