Move a Matter.js Composite as a Single Unit
In Matter.js, a Composite is a collection of bodies,
constraints, and nested composites rather than a physical object with
its own coordinates. Because of this architecture, moving an entire
composite requires shifting all of its individual child bodies together.
This guide explains how to translate a composite using built-in methods,
reposition it to an absolute coordinate, apply synchronized velocities
for physics-based movement, and determine when a compound body is a
better alternative.
1. Relative
Movement with Composite.translate
The most direct way to move a composite as a single unit is using the
built-in Matter.Composite.translate method. This method
takes a translation vector and adds those x and
y offsets to every body within the composite
recursively.
// Shift the composite 10 units to the right and 5 units up
Matter.Composite.translate(myComposite, { x: 10, y: -5 });This updates the positions of all constituent bodies while preserving their relative spacing and constraint setups.
2. Moving to an Absolute Position
Because a Composite lacks an intrinsic
position property, you must designate an anchor point (such
as a primary body or the average center) to move the composite to an
exact coordinate. Calculate the difference between the desired target
position and the anchor's current position, then pass that difference
into Composite.translate.
function setCompositePosition(composite, targetX, targetY) {
// Use the first body in the composite as the reference anchor
const bodies = Matter.Composite.allBodies(composite);
if (bodies.length === 0) return;
const anchor = bodies[0];
const deltaX = targetX - anchor.position.x;
const deltaY = targetY - anchor.position.y;
Matter.Composite.translate(composite, { x: deltaX, y: deltaY });
}
// Move the composite so its reference body sits at (400, 300)
setCompositePosition(myComposite, 400, 300);3. Synchronizing Velocity for Dynamic Movement
If the bodies in your composite are dynamic and need to move collectively while reacting to collisions, changing positions directly will disrupt the physics simulation. Instead, update the linear velocity of every body inside the composite uniformly:
function setCompositeVelocity(composite, velocity) {
const bodies = Matter.Composite.allBodies(composite);
bodies.forEach(body => {
Matter.Body.setVelocity(body, velocity);
});
}
// Launch all bodies in the composite with uniform momentum
setCompositeVelocity(myComposite, { x: 5, y: -10 });4. Alternative: Compound Bodies
If your composite consists of multiple shapes that must remain
rigidly fixed to one another without constraints, consider using a
compound Body instead of a Composite. Compound
bodies have a single origin, center of mass, and position vector.
const bodyA = Matter.Bodies.rectangle(100, 100, 50, 50);
const bodyB = Matter.Bodies.circle(130, 100, 20);
// Create a compound body from multiple parts
const compound = Matter.Body.create({
parts: [bodyA, bodyB]
});
Matter.Composite.add(engine.world, compound);
// Move the entire compound body directly
Matter.Body.setPosition(compound, { x: 500, y: 300 });
Matter.Body.setVelocity(compound, { x: 2, y: 0 });Use Composite.translate when your assembly requires
internal flexibility, constraints, or distinct dynamic behaviors between
parts. Use compound bodies when the assembly is entirely rigid.