Update All Body Properties in a Matter.js Composite
This guide explains how to batch-update the physical properties of
every physics body contained within a Matter.js Composite.
By utilizing the built-in Composite.allBodies method, you
can recursively find all top-level and nested bodies and apply new
values for attributes such as friction, restitution, density, and static
states.
Retrieving All Bodies in a Composite
A Composite in Matter.js can contain individual bodies
as well as nested composites. Accessing composite.bodies
directly only returns the top-level bodies, ignoring any sub-composites.
To retrieve every body regardless of nesting depth, use
Matter.Composite.allBodies():
const allBodies = Matter.Composite.allBodies(myComposite);Iterating and Modifying Properties
Once you have the array of bodies, iterate through them using a loop
or forEach and apply your changes.
When updating simple scalar values like friction or
restitution (bounciness), you can update them directly on
each body instance:
const allBodies = Matter.Composite.allBodies(myComposite);
allBodies.forEach(body => {
body.friction = 0.05;
body.frictionAir = 0.01;
body.restitution = 0.8; // Bounciness
});Modifying Properties Using Matter.Body Helper Methods
For properties that require internal calculations—such as mass,
inertia, density, or static state—use the corresponding
Matter.Body.set* methods instead of direct assignment. This
ensures Matter.js automatically recalculates the physics
constraints.
Setting Static State
To toggle whether all bodies in a composite are frozen in place:
allBodies.forEach(body => {
Matter.Body.setStatic(body, true);
});Updating Density and Mass
Modifying density requires recalculating mass and moment of inertia:
allBodies.forEach(body => {
Matter.Body.setDensity(body, 0.005);
});Updating Velocities
To impart forces, reset velocity, or stop all movement:
allBodies.forEach(body => {
Matter.Body.setVelocity(body, { x: 0, y: 0 });
Matter.Body.setAngularVelocity(body, 0);
});Modifying Collision Filters
If you need to change how all bodies in the composite interact with
other bodies in the simulation, update the collisionFilter
property:
allBodies.forEach(body => {
body.collisionFilter.category = 0x0002;
body.collisionFilter.mask = 0x0001;
body.collisionFilter.group = -1;
});Reusable Utility Function
You can combine these approaches into a generic utility function that accepts a composite and a configuration object:
function updateCompositeProperties(composite, properties) {
const bodies = Matter.Composite.allBodies(composite);
bodies.forEach(body => {
if (properties.isStatic !== undefined) {
Matter.Body.setStatic(body, properties.isStatic);
}
if (properties.density !== undefined) {
Matter.Body.setDensity(body, properties.density);
}
if (properties.friction !== undefined) {
body.friction = properties.friction;
}
if (properties.restitution !== undefined) {
body.restitution = properties.restitution;
}
});
}
// Example usage:
updateCompositeProperties(myComposite, {
friction: 0.1,
restitution: 0.9,
isStatic: false
});