Graphics Collision Detection

Rectangle collisions are detected by comparing edges on the x and y axes (AABB), while round objects are better checked by comparing the distance between their centers to the sum of their radii.

Why Objects Need to Know When They Touch

A game loop can move objects around a canvas all day, but without collision detection nothing can ever hit a wall, catch a coin, or take damage. Collision detection is simply the math that answers one question every frame: do these two shapes currently overlap?

Axis-Aligned Bounding Boxes (AABB)

The cheapest and most common technique treats every object as a rectangle that never rotates — an axis-aligned bounding box. Two such rectangles overlap if, and only if, they overlap on the x-axis and on the y-axis at the same time. If there's a gap between them on either axis alone, they cannot be touching, no matter what the other axis looks like.

Example

<!DOCTYPE html>
<html>
<head>
</head>
<body>

<canvas id="game" width="480" height="320"></canvas>

<script>
function isColliding(a, b) {
  return (
    a.x < b.x + b.width &&
    a.x + a.width > b.x &&
    a.y < b.y + b.height &&
    a.y + a.height > b.y
  );
}
</script>

</body>
</html>
  • a.x < b.x + b.width — a's left edge is left of b's right edge.
  • a.x + a.width > b.x — a's right edge is right of b's left edge.
  • a.y < b.y + b.height — a's top edge is above b's bottom edge.
  • a.y + a.height > b.y — a's bottom edge is below b's top edge.
  • All four conditions must be true at once — if any single one fails, the boxes are separated on that axis and cannot be colliding.
Box ABox BColliding?
x:0, y:0, w:50, h:50x:40, y:40, w:50, h:50Yes — overlaps on both axes
x:0, y:0, w:50, h:50x:60, y:0, w:50, h:50No — gap on the x-axis
x:0, y:0, w:50, h:50x:0, y:60, w:50, h:50No — gap on the y-axis
Note: This is sometimes explained through the 'separating axis' idea: to prove two boxes are NOT touching, you only need to find one axis with a gap between them. The AABB check above simply verifies that no such gap exists on either axis.

When Boxes Aren't a Good Fit: Circle Collision

Bounding boxes are fast but sloppy for round objects — a ball's actual edge is nowhere near the corners of its box, so box-based checks can register a 'hit' before the balls visually touch. For circular objects like balls or particles, it's both cheaper and more accurate to compare the distance between their centers to the sum of their radii: if that distance is smaller than the combined radii, the circles overlap.

Example

<!DOCTYPE html>
<html>
<head>
</head>
<body>

<canvas id="game" width="480" height="320"></canvas>

<script>
function circlesColliding(a, b) {
  const dx = a.x - b.x;
  const dy = a.y - b.y;
  const distanceSquared = dx * dx + dy * dy;
  const radiusSum = a.radius + b.radius;

  return distanceSquared < radiusSum * radiusSum;
}
</script>

</body>
</html>
Note: Comparing squared distance to the squared radius sum (instead of calling Math.sqrt) avoids an expensive square root every frame for every pair of objects — a small trick that adds up when you're checking dozens of objects against each other. For large numbers of objects, most games also add a cheap 'broad phase' step, like dividing the canvas into a grid, to rule out far-apart pairs before running these precise checks.

Exercise: Graphics Canvas Game Basics

What is a "game loop" in a canvas-based browser game?