Create Speed Booster Strips in Matter.js
This article explains how to build interactive speed booster strips in Matter.js that accelerate dynamic bodies upon contact. By configuring static sensor bodies and listening to collision events, you can detect intersecting objects and programmatically apply directional force or set their velocity to propel them forward.
1. Define the Booster Strip as a Sensor
To allow dynamic bodies to pass over a booster strip without
deflecting or bouncing off it, define the booster body with the
isSensor: true property. You can also label it so it can be
easily identified inside collision event listeners.
const booster = Matter.Bodies.rectangle(400, 500, 200, 40, {
isStatic: true,
isSensor: true,
label: 'boosterStrip',
angle: 0, // In radians; determine the direction of the boost
render: {
fillStyle: '#00ffcc'
}
});
Matter.Composite.add(engine.world, booster);2. Listen to Collision Events
Use Matter.js's collisionActive event rather than
collisionStart if you want the strip to continuously
accelerate the body as long as it remains on the strip. If you want an
instantaneous single-frame impulse, use collisionStart.
Matter.Events.on(engine, 'beforeUpdate', () => {
// Optional: Frame-rate independent physics updates can go here
});
Matter.Events.on(engine, 'collisionActive', (event) => {
event.pairs.forEach((pair) => {
const { bodyA, bodyB } = pair;
if (bodyA.label === 'boosterStrip') {
applyBoost(bodyA, bodyB);
} else if (bodyB.label === 'boosterStrip') {
applyBoost(bodyB, bodyA);
}
});
});3. Apply Directional Force or Velocity
Once a target body is confirmed to be on the booster, accelerate it
in the direction the strip is facing. You can achieve this with either
Matter.Body.applyForce (for natural acceleration) or
Matter.Body.setVelocity (for fixed speed).
Using force application:
function applyBoost(boosterBody, targetBody) {
if (targetBody.isStatic) return;
const boostMagnitude = 0.05 * targetBody.mass;
const angle = boosterBody.angle;
// Calculate forward vector based on the booster's angle
const force = {
x: Math.cos(angle) * boostMagnitude,
y: Math.sin(angle) * boostMagnitude
};
Matter.Body.applyForce(targetBody, targetBody.position, force);
}Using direct velocity modification:
function applyInstantBoost(boosterBody, targetBody) {
if (targetBody.isStatic) return;
const speed = 15;
const angle = boosterBody.angle;
Matter.Body.setVelocity(targetBody, {
x: Math.cos(angle) * speed,
y: Math.sin(angle) * speed
});
}4. Cap Maximum Speed (Recommended)
Continuous forces applied inside collisionActive can
cause bodies to accelerate excessively if they remain on long strips.
Implement a velocity clamp on the target body to maintain controlled
movement:
const maxSpeed = 20;
const currentSpeed = Matter.Vector.magnitude(targetBody.velocity);
if (currentSpeed > maxSpeed) {
const normalized = Matter.Vector.normalise(targetBody.velocity);
Matter.Body.setVelocity(targetBody, {
x: normalized.x * maxSpeed,
y: normalized.y * maxSpeed
});
}