What Is a Composite in Matter.js?
In Matter.js, a Composite is a structural container used to group physics entities—including rigid bodies, constraints, and other nested composites—into a single manageable unit. Rather than handling individual shapes and joints independently, Composites allow developers to organize complex physical assemblies, such as vehicles, ropes, or ragdolls, under a unified hierarchy. This article explains the core concepts of Composites, how they work within the physics engine, and the essential methods for creating and managing them.
The Role of a Composite
At its core, Matter.js organizes simulations using a tree-like
hierarchy of composites. In fact, the root environment where all
simulation elements exist—engine.world—is itself a
Composite.
Composites serve three primary purposes:
- Organization: Grouping logically connected items together so they can be added, removed, or repositioned simultaneously.
- Nesting: Supporting multi-level hierarchies where a composite contains other sub-composites, simplifying the construction of intricate machines or characters.
- Batch Operations: Enabling bulk queries and manipulations, such as retrieving all bodies or applying transformations to an entire group at once.
What Can a Composite Contain?
A Composite can hold three types of objects:
- Bodies: The physical objects that collide, move, and react to forces (e.g., rectangles, circles, custom polygons).
- Constraints: Joints, springs, or pins that link two bodies together or pin a body to a fixed point in space.
- Composites: Other composite instances, allowing for recursive, modular designs.
Basic Usage and Key Methods
Matter.js provides the Matter.Composite module to create
and manipulate these containers.
1. Creating and Adding Elements
To create a composite, use Composite.create(). You can
then populate it with bodies and constraints using
Composite.add().
// Create a new composite container
const car = Matter.Composite.create();
// Define parts
const chassis = Matter.Bodies.rectangle(200, 100, 100, 20);
const wheelA = Matter.Bodies.circle(180, 120, 15);
const wheelB = Matter.Bodies.circle(220, 120, 15);
const axelA = Matter.Constraint.create({ bodyA: chassis, bodyB: wheelA, pointB: { x: 0, y: 0 } });
const axelB = Matter.Constraint.create({ bodyA: chassis, bodyB: wheelB, pointB: { x: 0, y: 0 } });
// Add parts to the car composite
Matter.Composite.add(car, [chassis, wheelA, wheelB, axelA, axelB]);
// Add the car composite to the main simulation world
Matter.Composite.add(engine.world, car);2. Removing Elements
To remove an object or an entire sub-assembly from the world, pass
the target container and the items to remove into
Composite.remove():
Matter.Composite.remove(engine.world, car);3. Querying Elements
Because composites can be nested, Matter.js includes recursive helper functions to search the hierarchy:
Composite.allBodies(composite): Returns a flat array of all bodies within the composite and any nested composites.Composite.allConstraints(composite): Returns a flat array of all constraints within the hierarchy.Composite.allComposites(composite): Returns an array of all nested child composites.
4. Batch Transformations
Composites allow you to translate (move) or rotate entire assemblies without manually calculating the offsets for every individual part:
Composite.rotate(composite, angle, point): Rotates all bodies and constraints around a specific origin point.Composite.translate(composite, vector): Moves all contained elements by a specified vector.
Summary
The Composite is the foundational organizational unit in Matter.js. By abstracting groups of bodies and constraints into modular, reusable packages, it enables the creation of complex physical mechanisms while keeping your simulation architecture clean and scalable.