Low-Friction Air Hockey Puck in Matter.js

This guide explains how to simulate an air hockey puck gliding seamlessly over an invisible low-friction air cushion in Matter.js. By fine-tuning physical properties such as surface friction, static friction, air resistance, and restitution, you can accurately emulate the near-frictionless hover generated by real air table jets without needing complex force fields or custom particle systems.

Core Physics Properties in Matter.js

To create the illusion of an air cushion, you must eliminate standard surface-to-surface resistance while carefully controlling atmospheric drag. Matter.js provides four essential body properties to achieve this:

Implementation Example

The following code creates an engine, the boundary walls representing the table rink, and a circular puck tuned for frictionless movement:

const { Engine, Render, Runner, Bodies, Composite } = Matter;

const engine = Engine.create();
engine.gravity.y = 0; // Top-down 2D view: disable vertical gravity

const render = Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: 800,
        height: 600,
        wireframes: false
    }
});

// Create table walls with high elasticity and zero friction
const wallOptions = { isStatic: true, friction: 0, restitution: 1.0 };
const walls = [
    Bodies.rectangle(400, 0, 800, 20, wallOptions),
    Bodies.rectangle(400, 600, 800, 20, wallOptions),
    Bodies.rectangle(0, 300, 20, 600, wallOptions),
    Bodies.rectangle(800, 300, 20, 600, wallOptions)
];

// Create the air hockey puck
const puck = Bodies.circle(400, 300, 25, {
    density: 0.001,
    friction: 0,
    frictionStatic: 0,
    frictionAir: 0.001, // Subtle drag to replicate real-world air damping
    restitution: 0.99,  // Retain momentum on ricochet
    render: {
        fillStyle: '#ff2d55'
    }
});

Composite.add(engine.world, [...walls, puck]);

Render.run(render);
Runner.run(Runner.create(), engine);

Addressing High-Speed Tunneling

Because the puck moves at high velocities with negligible friction, it risks passing through walls—a common physics engine issue known as tunneling. Mitigate this by applying two configurations:

  1. Increase Engine Iterations: Increase engine.positionIterations and engine.velocityIterations to at least 8 or 10 to improve collision resolution accuracy per frame.
  2. Increase Wall Thickness: Build boundary walls with greater depth (e.g., 50 to 100 pixels wide) positioned outside the visible canvas area rather than thin barriers.