Collision Detection

What happens when the player touches an enemy? Or picks up a coin? Collision detection is how we know when game objects interact.

AABB Collision

AABB stands for "Axis-Aligned Bounding Box". It's the simplest and most common collision detection method. We treat every object as a rectangle and check if they overlap.

The Logic

Two rectangles are colliding if all four of these conditions are true:

  1. Left edge of A is to the left of Right edge of B
  2. Right edge of A is to the right of Left edge of B
  3. Top edge of A is above Bottom edge of B
  4. Bottom edge of A is below Top edge of B
function isColliding(rect1, rect2) {
    return rect1.x < rect2.x + rect2.width &&
           rect1.x + rect1.width > rect2.x &&
           rect1.y < rect2.y + rect2.height &&
           rect1.y + rect1.height > rect2.y;
}

// Usage
const player = { x: 100, y: 100, width: 40, height: 40 };
const enemy = { x: 120, y: 110, width: 30, height: 30 };

if (isColliding(player, enemy)) {
    console.log('💥 Collision detected!');
}

Circle Collision

For circular objects (balls, coins, characters), we check if the distance between centers is less than the sum of their radii.

function isCircleColliding(circle1, circle2) {
    const dx = circle1.x - circle2.x;
    const dy = circle1.y - circle2.y;
    const distance = Math.sqrt(dx * dx + dy * dy);
    return distance < circle1.radius + circle2.radius;
}

// Usage
const ball = { x: 200, y: 150, radius: 20 };
const coin = { x: 210, y: 160, radius: 15 };

if (isCircleColliding(ball, coin)) {
    console.log('🪙 Coin collected!');
}

Point in Rectangle

Useful for detecting mouse clicks on buttons or objects:

function isPointInRect(px, py, rect) {
    return px >= rect.x && 
           px <= rect.x + rect.width &&
           py >= rect.y && 
           py <= rect.y + rect.height;
}

// Usage with mouse click
canvas.addEventListener('click', (e) => {
    const mouseX = e.offsetX;
    const mouseY = e.offsetY;
    
    if (isPointInRect(mouseX, mouseY, button)) {
        console.log('Button clicked!');
    }
});

Complete Example: Collectible Coins

Here's a mini-game where you move a player to collect coins:

const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');

const player = { x: 50, y: 50, width: 30, height: 30 };
let coins = [
    { x: 200, y: 100, width: 20, height: 20 },
    { x: 350, y: 250, width: 20, height: 20 },
    { x: 500, y: 150, width: 20, height: 20 }
];
let score = 0;
const keys = {};

window.addEventListener('keydown', e => keys[e.key] = true);
window.addEventListener('keyup', e => keys[e.key] = false);

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;
}

function gameLoop() {
    // UPDATE
    if (keys['ArrowUp']) player.y -= 4;
    if (keys['ArrowDown']) player.y += 4;
    if (keys['ArrowLeft']) player.x -= 4;
    if (keys['ArrowRight']) player.x += 4;

    // Check coin collisions
    coins = coins.filter(coin => {
        if (isColliding(player, coin)) {
            score++;
            return false; // Remove coin
        }
        return true;
    });

    // CLEAR
    ctx.fillStyle = '#111';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // DRAW coins
    ctx.fillStyle = '#ffd700';
    coins.forEach(c => ctx.fillRect(c.x, c.y, c.width, c.height));

    // DRAW player
    ctx.fillStyle = '#4ade80';
    ctx.fillRect(player.x, player.y, player.width, player.height);

    // DRAW score
    ctx.fillStyle = '#fff';
    ctx.font = '20px Arial';
    ctx.fillText('Score: ' + score, 10, 30);

    requestAnimationFrame(gameLoop);
}

gameLoop();

Grab the Code

Copy ready-to-use collision functions from our Resources library!

View Collision Snippets

🎉 Fundamentals Complete!

You now understand the core concepts of HTML5 game development. You're ready to build your first complete game!

What's Next?

You've completed the "Getting Started" path! Here's where you can go from here: