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.