Test store. Prices are the planned list prices stored as test data, license terms are drafts, and payments go to a Stripe test-mode account. No real money moves.

HTML5 Game Physics: Engines, 2D Collision Basics and a Tutorial

An HTML5 game physics engine moves bodies under gravity, detects collisions and resolves them every frame. For 2D games in 2026 the main choices are Phaser's Arcade Physics, Matter.js, Planck.js, Phaser Box2D and Rapier; for 3D, Rapier, Havok in Babylon.js and ammo.js in PlayCanvas. Simple games need only a few lines of collision code, and puzzles with fixed solutions often need a deterministic simulation of their own.

An HTML5 game physics engine is a JavaScript or WebAssembly library that moves bodies under gravity, detects when they touch and pushes them apart in a believable way, many times a second. You need one for stacking, ragdolls, ropes, chains and launch-and-topple games. You usually don't for platformers, shooters and grid puzzles, where a few lines of collision code are simpler and more predictable. We've shipped a slingshot puzzle, a ragdoll distance game, a stacking game and several other physics games on Phaser 4, and this page covers both routes: collision code you write yourself, and the engines worth using in October 2026.

This guide belongs to our series on HTML5 canvas games, which covers the canvas and the game loop this code runs in.

Do you need a physics engine?

Pick the lightest tool that gives the feel you want:

Your gameWhat you need
Platformer, runner, top-down shooterRectangle and circle collisions plus gravity you write, or Phaser's Arcade Physics
Grid puzzle, match-3, card gameNo physics at all: rules on a grid
Pinball, breakout, mini golfCircle-versus-shape collisions with bounce; an engine helps with complex tables
Stacking, ragdolls, ropes, toppling towersA rigid-body engine with joints and stable stacking
3D game with collisionsA 3D engine such as Rapier, or raycasts for simple cases

Phaser's documentation describes its Arcade Physics as "a lightweight physics system that can only handle two different types of physics shapes: rectangles and circles" (Phaser physics concepts). That limit is a feature for a platformer: boxes that never rotate are what make jumping feel precise.

Make an easy HTML5 canvas game with 2D collision

Before choosing an engine, write the basics once. Three functions cover most 2D games: an overlap test for axis-aligned boxes, one for circles, and a resolver that pushes a moving box out of a wall.

collide.js
// Axis-aligned boxes: { x, y, w, h } with x, y at the top-left corner.
function overlaps(a, b) {
  return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
}

// Circles: { x, y, r } with x, y at the centre. Compare squared distances: no square root needed.
function circlesTouch(a, b) {
  const dx = b.x - a.x, dy = b.y - a.y, r = a.r + b.r;
  return dx * dx + dy * dy < r * r;
}

// Push the player out of a wall along the axis of smallest overlap.
function resolve(p, wall) {
  const left = p.x + p.w - wall.x, right = wall.x + wall.w - p.x;
  const up = p.y + p.h - wall.y, down = wall.y + wall.h - p.y;
  const min = Math.min(left, right, up, down);
  if (min === up) { p.y -= up; p.vy = 0; p.onGround = true; }
  else if (min === down) { p.y += down; p.vy = 0; }
  else if (min === left) { p.x -= left; p.vx = 0; }
  else { p.x += right; p.vx = 0; }
}

Run the physics at a fixed step, not once per frame. Phones refresh at 60, 90 or 120 Hz, and a jump that depends on the frame rate is a different jump on every device:

loop.js
const STEP = 1 / 120; // seconds per physics step
const GRAVITY = 1800;  // pixels per second squared
let acc = 0, last = performance.now();

function update(dt) {
  player.vy += GRAVITY * dt;
  player.x += player.vx * dt;
  player.y += player.vy * dt;
  player.onGround = false;
  for (const wall of walls) if (overlaps(player, wall)) resolve(player, wall);
}

function frame(now) {
  acc += Math.min(0.25, (now - last) / 1000); // cap long pauses (tab switches)
  last = now;
  while (acc >= STEP) { update(STEP); acc -= STEP; }
  draw();
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);

That's enough for a platformer or a breakout clone. Our free platformer and breakout code pages build complete games on the same ideas, and MDN's 2D collision detection article adds the separating axis theorem for rotated shapes.

The classic bug at this stage is tunnelling: a fast object moves further than a wall's thickness in one step and passes straight through. Fix it with smaller steps for fast objects, thicker walls, or a swept test (cast a ray along the movement and stop at the first hit). Engines with continuous collision detection do the swept test for you.

HTML5 game physics engines compared

These are the libraries worth considering in October 2026. All are free and open source.

Engine2D/3DBuilt withLicenseStrengthsWatch out for
Phaser Arcade Physics2DJavaScript, inside PhaserMITVery fast, simple, ideal for platformersRectangles and circles only, no rotation physics
Matter.js2DJavaScriptMITPolygons, constraints, composites; bundled with PhaserPhaser's own comparison rates its stacking stability weak, with no continuous collision detection
Planck.js2DJavaScript/TypeScript rewrite of Box2DMITBox2D's proven design and jointsBox2D-style units (metres, not pixels)
Phaser Box2D2DJavaScript conversion of Box2D v3MITStable stacking, continuous collision, motors, limits and springs on jointsA separate library, not a built-in Phaser physics system
Rapier2D and 3DRust compiled to WebAssemblyApache 2.0Fast, documented cross-platform determinismLoads asynchronously; the WASM adds download size
Havok in Babylon.js3DWebAssemblyMIT (the @babylonjs/havok package)Integrated as Babylon's Physics V2Made for Babylon.js
ammo.js in PlayCanvas3DBullet compiled to WebAssemblyzlib (Bullet)Mature, full-featuredPlayCanvas notes it adds several hundred kilobytes

The Matter.js row is worth reading twice. Matter is pleasant to use and is enough for many games, but the Phaser Box2D page compares it directly: stacking stability "Weak", no continuous collision detection, distance joints only. If your game is about tall stacks or fast projectiles, start with a Box2D-class engine or Rapier.

Game engines with physics built in

If you'd rather not wire a physics library to a renderer yourself, choose an engine that already did it. Phaser ships Arcade Physics and Matter.js, set with one line of game config. Babylon.js integrates Havok, PlayCanvas integrates ammo.js through its rigid body component, and Godot and Unity web exports carry their own physics. For 3D browser games in general, see our guide to 3D HTML5 games.

How to create a physics-based HTML5 game with Matter.js

This tutorial builds a tower of crates and a ball you launch by dragging back and releasing. It's the core of every launch-and-topple game. Install Matter.js with npm install matter-js and import it with import Matter from "matter-js".

1. Create the world

The engine holds the bodies, the renderer draws them (Matter's built-in renderer is meant for debugging, but it's fine for a first test), and the runner steps the engine every frame.

physics-game.js
const { Engine, Render, Runner, Bodies, Body, Composite, Events } = Matter;

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

const ground = Bodies.rectangle(400, 440, 800, 20, { isStatic: true });
const crates = [];
for (let row = 0; row < 6; row++) {
  for (let col = 0; col < 2; col++) crates.push(Bodies.rectangle(560 + col * 42, 410 - row * 42, 40, 40));
}
const ball = Bodies.circle(120, 300, 18, { density: 0.004, restitution: 0.3 });
Composite.add(engine.world, [ground, ...crates, ball]);

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

2. Launch with a drag

Drag back from anywhere and release: the vector from release to press becomes the launch velocity. Pointer events make the same code work with a mouse and on a touch screen.

physics-game.js
const HOME = { x: 120, y: 300 };
let start = null;
render.canvas.addEventListener("pointerdown", (e) => { start = { x: e.offsetX, y: e.offsetY }; });
render.canvas.addEventListener("pointerup", (e) => {
  if (!start) return;
  const pull = { x: start.x - e.offsetX, y: start.y - e.offsetY };
  Body.setPosition(ball, HOME);
  Body.setAngularVelocity(ball, 0);
  Body.setVelocity(ball, { x: pull.x * 0.12, y: pull.y * 0.12 });
  start = null;
});

3. React to collisions

Games are rules on top of physics. Matter reports every new contact, so you can play a sound, score a hit or break a crate when the impact is hard enough:

physics-game.js
Events.on(engine, "collisionStart", (event) => {
  for (const { bodyA, bodyB } of event.pairs) {
    if (bodyA !== ball && bodyB !== ball) continue;
    const other = bodyA === ball ? bodyB : bodyA;
    if (crates.includes(other) && ball.speed > 8) Composite.remove(engine.world, other);
  }
});

From here, a real game draws its own sprites at each body's position and angle instead of using the debug renderer, adds a trajectory preview, a camera that follows the ball and levels loaded from data. In Phaser the same game is shorter, because physics: { default: "matter" } in the game config gives every scene a this.matter factory that creates bodies and sprites together.

Can a game like Angry Birds be developed in HTML5?

Yes, and it already was. Rovio's browser version of Angry Birds launched for Chrome at Google I/O in 2011. According to an InfoQ interview with Joel Webber, a co-creator of Google Web Toolkit, it was written in Java, compiled to JavaScript, and used a Box2D port for its physics. Browsers and JavaScript engines are far faster today, and every library in the table above can run a launch-and-topple game on a phone.

What separates a good slingshot game from a physics demo is mostly design:

  • Materials: wood, stone, ice and glass need different density, friction and bounce, and the player must be able to read them at a glance.
  • Damage: blocks break when the impact is hard enough, not on any touch, so you compare collision speed or impulse against a threshold.
  • Settling: a level isn't over until the bodies stop moving, so turn on sleeping and wait for every body to rest.
  • Fairness: the same shot should give the same result, or players feel cheated.

Our Slingshot Rescue takes the last point further. Its shot physics runs on integers: positions and velocities in fixed point (1 pixel = 256 units), one 240 Hz substep at a time, with angles from lookup tables. Ten materials, from soil and stone to jelly, ice and cloud, each have their own bounce and grip. A solver searches the same discrete grid of pull angles and power steps the player uses, so every stored solution can be reproduced by hand, and each level's par is the fewest shots that clear it.

Why our physics games run their rules in their own simulation

Here is the most useful thing we learned building these games: if the outcome of a level must be the same everywhere, don't let a general-purpose engine decide it.

JavaScript's Math.sin, Math.cos and Math.atan2 are "implementation-approximated" in the ECMAScript specification, so Chrome, Firefox and Safari can return slightly different values. A physics engine that uses them can drift apart between browsers after a few hundred steps. Rapier's determinism notes give the same warning about transcendental functions. For a sandbox that doesn't matter. For a puzzle with a proven solution, a daily challenge that everyone plays with the same seed, or a ghost replay, it does.

So in our physics games, the rules run in plain TypeScript simulations that use only operations JavaScript defines exactly:

  • Stack & Balance has a compact rigid-body solver in the style of Box2D v2.4 (polygon contacts, warm starting, sleeping, a revolute joint for seesaws) that uses only addition, subtraction, multiplication, division and Math.sqrt. Rotations are stored as a cosine and sine pair instead of an angle. The same inputs give bit-identical results in Chromium, Firefox, WebKit and Node.
  • Bounce Architect, Slingshot Rescue and Cannon Courier compute every outcome in integer arithmetic.
  • Ragdoll Rooftops builds its ragdoll from 11 Verlet particles joined by rigid bones with joint limits, and uses its own polynomial sine and cosine instead of the browser's.

Matter.js still appears in these games, but only for things that don't affect the result: plates falling away in Screwscape Workshop, debris tumbling off rooftops, confetti. Cannon Courier uses Phaser's Arcade Physics the same way, for debris. In Cannon Courier, the solver, the trajectory preview and the renderer all step the same simulation code, which is what lets every level be checked automatically before it ships.

Ragdoll Rooftops

  • Phaser
  • Build-verified source

Launch and swing a floppy ragdoll across rooftops, grabbing anchors, bouncing on trampolines and flipping for style to travel as far as possible.

You don't need this for every game. Use an engine for feel and juice; own the simulation, or pick one that documents determinism, when outcomes must be reproducible. More of our physics games are in the puzzle category and, for skill games like Ragdoll Rooftops and Hook Hero Neon, the action category.

Physics performance tips for phones

  • Use simple shapes. Circles and boxes are cheapest. Approximate a detailed sprite with a few convex parts instead of tracing every pixel.
  • Let bodies sleep. Bodies at rest stop costing time. Matter has an enableSleeping option, and Box2D-style engines and Rapier support sleeping too.
  • Remove what the player can't see. Debris that left the screen should leave the world too.
  • Keep the step fixed. Variable steps make stacks jitter and jumps inconsistent.
  • Load WASM engines early, but not first. Start loading Rapier while the menu shows, so the first level doesn't wait.

Our guide to HTML5 game performance covers profiling, and the guides on isometric games and sprites and animation cover the drawing side of the same games.

Frequently asked questions

Which physics engine does Phaser 4 use?

Phaser 4 includes two: Arcade Physics for fast rectangle and circle collisions, and a bundled version of Matter.js for full rigid bodies with polygons and constraints. You pick one in the game config. Phaser Box2D is a separate MIT-licensed library that you can add for Box2D v3 physics.

Is Matter.js good enough for a commercial game?

Yes, for many games: it handles polygons, constraints and collision events well, and it's built into Phaser. Its weak spots are tall stacks and very fast objects, because it has no continuous collision detection. For those, use Planck.js, Phaser Box2D or Rapier.

How do I stop fast objects passing through walls?

Take smaller physics steps for fast objects, make walls thicker than the distance an object moves in one step, or use a swept test that casts a ray along the movement. Engines with continuous collision detection, such as Phaser Box2D and Rapier, can handle it for you.

Can I use one physics engine for both 2D and 3D games?

Rapier comes closest: it has separate 2D and 3D packages with the same design and a similar API. Most other engines are either 2D (Matter.js, Planck.js, Box2D) or 3D (Havok, ammo.js).

We make and sell HTML5 game source code; links to our games are marked as ours.