HTML5 Canvas: Advanced Physics and Collision (Hitbox)
HTML5 Canvas: Advanced Physics and Hitbox Collision
Drawing a player and applying gravity is fantastic, but a game isn't a game until objects interact. When a player's foot hits a ball, the ball needs to fly! When the ball hits the ground, it shouldn't just stick—it needs to bounce and roll to a stop.
This module will teach you Hitbox Collision Detection and Advanced Projectile Physics (Bounciness and Friction) in a simple, understandable way.
1. The Hitbox: AABB Collision Detection
In 2D games, we usually don't calculate collisions pixel-by-pixel—it's too slow. Instead, we draw an invisible rectangular box around our sprite called a Hitbox (or Bounding Box).
The industry standard algorithm for checking if two rectangles overlap is called AABB (Axis-Aligned Bounding Box). The math is surprisingly simple! We check four absolute limits:
// Function returns TRUE if Box1 and Box2 overlap
function checkAABBCollision(box1, box2) {
// We check if it's IMPOSSIBLE for them to collide first.
// Example: Is Box1's right edge further left than Box2's left edge?
return (
box1.x < box2.x + box2.width && // Box1 Left is past Box2 Right
box1.x + box1.width > box2.x && // Box1 Right is past Box2 Left
box1.y < box2.y + box2.height && // Box1 Top is past Box2 Bottom
box1.y + box1.height > box2.y // Box1 Bottom is past Box2 Top
);
}
If ALL those conditions are true, the two objects are currently crashing into each other!
2. Advanced Game Physics: The Ball
If you are making a sports or platformer game, your ball needs to feel realistic. A true physics ball requires two new concepts:
- Bounce / Restitution: When it hits the floor, it reverses direction
(-dy), but it loses some energy so it doesn't bounce forever. - Friction / Drag: When rolling left or right, the grass slows it down until it completely stops.
class Ball {
constructor(x, y) {
this.x = x;
this.y = y;
this.width = 50; // Standardizing hitbox
this.height = 50;
// Physics properties
this.dx = 0; // Horizontal speed
this.dy = 0; // Vertical falling speed
this.gravity = 0.5;
// THE SECRET INGREDIENTS
this.bounce = -0.7; // Loses 30% of energy every bounce
this.friction = 0.98; // Multiplies dx to slow it down 2% every frame
}
update(groundLevel) {
// 1. Apply Gravity
this.dy += this.gravity;
// 2. Apply Friction to slow rolling
this.dx *= this.friction;
// Stop completely if the speed is incredibly slow (micro-movements)
if (Math.abs(this.dx) < 0.1) this.dx = 0;
// 3. Move the Ball
this.x += this.dx;
this.y += this.dy;
// 4. Floor Collision & Bouncing Logic
if (this.y + this.height >= groundLevel) {
this.y = groundLevel - this.height; // Prevent sinking
// Only bounce if falling fast enough (prevents infinite micro-jitters)
if (this.dy > 1) {
this.dy *= this.bounce; // Reverse direction and lose energy!
} else {
this.dy = 0; // Settle on the ground completely
}
}
}
}
3. Creating the Impact (Transferring Momentum)
How do we put everything together? Inside your Game Loop, you use your AABB math to check if the Player touches the Ball.
If they touch, AND the player is currently in the "Kick" animation state, we instantly inject explosive velocity (dx and dy) into the ball!
// Inside your requestAnimationFrame Loop...
// 1. Update entities
player.update();
ball.update(canvas.height - 90);
// 2. Check Hitbox Collision
if (checkAABBCollision(player, ball)) {
// Did the player hit the kick button just now?
if (player.state === "Kick") {
// BOOM! Transfer huge momentum to the ball
// Shoot it upwards and forwards!
ball.dy = -15;
// Shoot left or right depending on player's side
if (player.position === "left") {
ball.dx = 20; // Blast to the right
} else {
ball.dx = -20; // Blast to the left
}
} else {
// If just walking into it normally, nudge the ball slightly
ball.dx = player.dx * 1.2;
}
}
With these three steps, your characters no longer pass through objects like ghosts! You have successfully implemented a professional Physics Engine logic within HTML5 Canvas.