How to Create Jump Pads in Matter.js
This guide explains how to build responsive jump pads in Matter.js that launch physics bodies upward at exact, predefined velocities. By using sensor bodies and collision events instead of standard restitution, you can bypass inconsistent bounciness mechanics and exert precise control over launch heights.
Why Use Sensor Collisions Over Restitution
Using high restitution (bounciness) to simulate a jump pad introduces unpredictable behavior. The resulting launch height will depend on the incoming body's entry speed and angle. To achieve a strictly predefined upward velocity, configure the jump pad as a static sensor body, detect the moment an object touches it, and directly overwrite the object's vertical velocity.
Step 1: Define the Jump Pad Body
Create a static body and set isSensor: true. This allows
other bodies to pass through or touch the pad without triggering
standard rigid-body collision responses. Tag the body with a unique
label and define your desired launch velocity.
const jumpPad = Matter.Bodies.rectangle(400, 550, 120, 20, {
isStatic: true,
isSensor: true,
label: 'jumpPad',
launchVelocity: -18, // Negative value for upward motion in canvas coordinates
render: {
fillStyle: '#ff4757'
}
});
Matter.Composite.add(engine.world, jumpPad);Step 2: Listen for Collision Events
Attach an event listener to the Engine for
collisionStart. During this event, iterate through the
active collision pairs to determine if any dynamic body has made contact
with the jump pad.
Matter.Events.on(engine, 'collisionStart', (event) => {
const pairs = event.pairs;
for (let i = 0; i < pairs.length; i++) {
const { bodyA, bodyB } = pairs[i];
if (bodyA.label === 'jumpPad' && !bodyB.isStatic) {
launchBody(bodyB, bodyA.launchVelocity);
} else if (bodyB.label === 'jumpPad' && !bodyA.isStatic) {
launchBody(bodyA, bodyB.launchVelocity);
}
}
});Step 3: Apply the Launch Velocity
Use Matter.Body.setVelocity() to directly set the target
body's velocity. Retain the current horizontal velocity
(body.velocity.x) to preserve forward momentum while
strictly overriding the vertical velocity
(body.velocity.y).
function launchBody(body, upwardSpeed) {
Matter.Body.setVelocity(body, {
x: body.velocity.x,
y: upwardSpeed
});
}Key Considerations
- Direction Control: If the jump pad is angled,
compute launch velocity vectors using trigonometric functions
(
Math.cosandMath.sinbased on the pad'sangle) to shoot bodies perpendicularly to the pad's surface. - Continuous Jumping: Setting
isSensor: trueensures the body does not get stuck or jitter on top of the surface. If you want the body to rest on the pad without launching repeatedly, add a debounce cooldown property to the dynamic body before reapplying the launch velocity.