How to Build a Tentacle Arm with Matter.js
This article explains how to construct a multi-segment, flexible tentacle arm using the Matter.js 2D physics engine and drive it toward target coordinates. You will learn how to configure chained rigid bodies using pin constraints, disable self-collisions, anchor the base, and apply continuous steering forces to make the tentacle naturally reach and curl toward a target.
1. Setting Up the Matter.js Environment
To create a tentacle, initialize the standard Matter.js modules:
Engine, Render, Runner,
Bodies, Composite, Constraint,
and Vector.
const { Engine, Render, Runner, Bodies, Composite, Constraint, Vector, Body } = 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. Creating Chained Segments
A flexible tentacle consists of a series of small rectangular bodies connected end-to-end via revolute constraints. To prevent the segments from colliding with each other and breaking the chain, assign them a shared negative collision group.
const segmentCount = 12;
const segmentWidth = 30;
const segmentHeight = 10;
const startX = 400;
const startY = 500;
const collisionGroup = Body.nextGroup(true); // Generates a unique negative group
const segments = [];
let prevBody = null;
for (let i = 0; i < segmentCount; i++) {
const x = startX;
const y = startY - i * segmentWidth;
// Scale segment size down slightly toward the tip for a tapered look
const scale = 1 - (i / segmentCount) * 0.5;
const body = Bodies.rectangle(x, y, segmentWidth * scale, segmentHeight * scale, {
collisionFilter: { group: collisionGroup },
frictionAir: 0.05, // Adds drag to simulate underwater or muscle resistance
density: 0.001
});
segments.push(body);
Composite.add(world, body);
if (prevBody) {
// Connect current segment to the previous segment
const joint = Constraint.create({
bodyA: prevBody,
pointA: { x: 0, y: -segmentWidth / 2 },
bodyB: body,
pointB: { x: 0, y: segmentWidth / 2 },
stiffness: 0.9,
damping: 0.1,
render: { visible: false }
});
Composite.add(world, joint);
}
prevBody = body;
}3. Anchoring the Base
To keep the tentacle anchored in place, pin the root segment to a fixed point in the physics world:
const anchor = Constraint.create({
pointA: { x: startX, y: startY },
bodyB: segments[0],
pointB: { x: 0, y: segmentWidth / 2 },
stiffness: 1
});
Composite.add(world, anchor);4. Directing the Tentacle Toward a Target
To make the tentacle actively reach toward a target (such as mouse coordinates or a moving game object), apply targeted physics forces before each engine update.
Rather than pulling only the tip—which makes the arm behave like a limp rope—apply a progressive force across the upper segments toward the target.
const target = { x: 400, y: 200 };
// Track mouse as target
window.addEventListener('mousemove', (event) => {
target.x = event.clientX;
target.y = event.clientY;
});
Matter.Events.on(engine, 'beforeUpdate', () => {
const tip = segments[segments.length - 1];
// Apply proportional reaching forces across the top half of the tentacle
for (let i = Math.floor(segmentCount / 2); i < segmentCount; i++) {
const seg = segments[i];
// Calculate direction vector to target
const direction = Vector.sub(target, seg.position);
const distance = Vector.magnitude(direction);
if (distance > 0) {
const normalized = Vector.normalise(direction);
// Weight force higher near the tip
const weight = (i / segmentCount) * 0.0005;
const force = Vector.mult(normalized, weight);
Body.applyForce(seg, seg.position, force);
}
}
});5. Tuning Flexibility and Movement
- Constraint Stiffness: Lowering
stiffness(e.g.,0.3to0.6) in the joints increases bendiness, while values closer to1.0make the arm act more rigid. - Air Friction: Increasing
frictionAir(e.g.,0.08) dampens extreme oscillation, resulting in smooth, controlled reaching motions. - Target Resistance: Limiting the maximum force applied prevents the tentacle from stretching its constraints beyond stable limits during sudden target movements.