How to Clone an Existing Body in Matter.js
Cloning a body in Matter.js is essential when duplicating dynamic
game elements, generating particle effects, or spawning recurring
obstacles. Because the engine does not provide a native
Body.clone() method, developers must instantiate a new body
by copying the structural, physical, and rendering properties of the
original. This guide demonstrates how to properly duplicate an existing
body without causing identity conflicts or physics calculation
errors.
Why Native Cloning Methods Fail
Directly copying a body object using Object.assign() or
standard deep-clone utilities can break the physics simulation.
Matter.js bodies contain internal state trackers, such as unique
id values, computed geometric bounds, axes, and collision
caches. If two bodies share identical internal IDs or reference
identical vertex arrays, collision detection and constraint solving will
fail. The safest approach is constructing a new body with
Matter.Body.create() while reusing the original body's
vertices and physical options.
Step-by-Step Cloning Function
To clone a body reliably, create a utility function that extracts the physical properties and clones the vertices to break memory references.
function cloneBody(originalBody, newX, newY) {
// 1. Clone vertices to prevent reference sharing
const vertices = Matter.Vertices.clone(originalBody.vertices);
// 2. Clone basic physical properties and collision settings
const options = {
angle: originalBody.angle,
friction: originalBody.friction,
frictionAir: originalBody.frictionAir,
frictionStatic: originalBody.frictionStatic,
restitution: originalBody.restitution,
density: originalBody.density,
isStatic: originalBody.isStatic,
isSensor: originalBody.isSensor,
collisionFilter: {
category: originalBody.collisionFilter.category,
mask: originalBody.collisionFilter.mask,
group: originalBody.collisionFilter.group
},
render: {
visible: originalBody.render.visible,
opacity: originalBody.render.opacity,
strokeStyle: originalBody.render.strokeStyle,
fillStyle: originalBody.render.fillStyle,
lineWidth: originalBody.render.lineWidth,
sprite: originalBody.render.sprite ? { ...originalBody.render.sprite } : null
}
};
// 3. Create a fresh body instance
const newBody = Matter.Body.create(options);
// 4. Assign cloned vertices to restore the original shape
Matter.Body.setVertices(newBody, vertices);
// 5. Position the cloned body (using original coordinates if none are provided)
const targetX = newX !== undefined ? newX : originalBody.position.x;
const targetY = newY !== undefined ? newY : originalBody.position.y;
Matter.Body.setPosition(newBody, { x: targetX, y: targetY });
return newBody;
}Adding the Cloned Body to the World
After generating the cloned body, add it to your engine's world composite. You can place it directly at an offset position to prevent it from immediately overlapping and colliding with the source body.
// Existing source body
const originalBox = Matter.Bodies.rectangle(200, 200, 80, 80, {
restitution: 0.8,
render: { fillStyle: '#e74c3c' }
});
Matter.Composite.add(engine.world, originalBox);
// Create a clone positioned 100 pixels to the right
const clonedBox = cloneBody(originalBox, 300, 200);
// Add the clone to the simulation
Matter.Composite.add(engine.world, clonedBox);Handling Compound Bodies
If the target body is a compound body consisting of multiple
sub-parts, you must iterate over the parts array:
- Skip the first part (
originalBody.parts[0]), which represents the parent container. - Clone each individual child part using its relative position and vertices.
- Pass the newly cloned parts to
Matter.Body.setParts(newBody, clonedParts).