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