Build a Bridge with Constraints in Matter.js
This guide demonstrates how to construct an interactive, realistic suspension bridge using the Matter.js 2D physics engine. By linking a series of rigid rectangular bodies with elastic constraints and pinning the ends to static anchors, you can simulate realistic tension, sag, and weight-bearing behavior. Below, you will find the conceptual breakdown, step-by-step implementation, and complete code required to generate a functional bridge.
Core Concepts
A dynamic bridge in Matter.js consists of three primary components:
- Planks (Bodies): A sequence of dynamic rectangular bodies acting as the bridge deck.
- Joints (Constraints): Connections linking adjacent planks together, maintaining distance while allowing rotational flexibility.
- Pillars/Anchors: Static bodies or fixed coordinates at both ends that secure the bridge in world space.
Step-by-Step Implementation
1. Initialize the Engine and World
Set up the standard Matter.js modules: Engine,
Render, Runner, Bodies,
Composite, Composites, and
Constraint.
const { Engine, Render, Runner, Bodies, Composite, Composites, Constraint } = Matter;
const engine = Engine.create();
const world = engine.world;
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
Render.run(render);
Runner.run(Runner.create(), engine);2. Create the Bridge Segments Using a Stack
The easiest way to generate bridge planks is via
Composites.stack. This creates an array of aligned
rectangles across the horizontal axis.
const bridgeLength = 12; // Number of planks
const plankWidth = 45;
const plankHeight = 15;
const startX = 130;
const startY = 300;
const bridge = Composites.stack(startX, startY, bridgeLength, 1, 5, 0, (x, y) => {
return Bodies.rectangle(x, y, plankWidth, plankHeight, {
collisionFilter: { group: -1 }, // Prevents planks from colliding with each other
chamfer: 2,
density: 0.005
});
});3. Chain the Planks Together
Use Composites.chain to automatically generate
constraints between consecutive planks in the stack.
Composites.chain(bridge, 0.4, 0, -0.4, 0, {
stiffness: 0.9,
length: 2,
render: {
visible: true,
lineWidth: 2,
strokeStyle: '#666'
}
});The offset parameters (0.4 and -0.4) attach
the constraint near the edges of adjacent planks rather than their
centers, resulting in realistic pivoting.
4. Anchor the Ends
To prevent the bridge from falling under gravity, attach the first and last bodies to fixed world points using independent constraints.
// Anchor the left side
const leftAnchor = Constraint.create({
pointA: { x: startX - 20, y: startY },
bodyB: bridge.bodies[0],
pointB: { x: -plankWidth / 2, y: 0 },
stiffness: 1,
length: 0
});
// Anchor the right side
const rightAnchor = Constraint.create({
pointA: { x: startX + (plankWidth + 5) * bridgeLength, y: startY },
bodyB: bridge.bodies[bridge.bodies.length - 1],
pointB: { x: plankWidth / 2, y: 0 },
stiffness: 1,
length: 0
});
Composite.add(world, [bridge, leftAnchor, rightAnchor]);Tuning Physics Behavior
- Stiffness: Adjust
stiffnesson the constraints (from0.0to1.0). A lower value creates an elastic rope bridge effect, while a value near1.0produces a firm wooden suspension bridge. - Density: Modifying the
densityof the planks dictates how heavily the bridge sags under its own weight. - Length: Setting the constraint
lengthgreater than zero introduces slack, which creates deeper initial sag without requiring external mass.