For 90% of 2D beginner games, “did box A touch box B?” is all you need. That’s AABB (axis-aligned bounding box):
local function overlaps(a, b)
return a.x < b.x + b.w
and b.x < a.x + a.w
and a.y < b.y + b.h
and b.y < a.y + a.h
endExample: pick up a coin
local player = { x = 100, y = 100, w = 32, h = 32 }
local coin = { x = 300, y = 200, w = 16, h = 16, taken = false }
function love.update(dt)
if not coin.taken and overlaps(player, coin) then
coin.taken = true
score = score + 1
end
endExample: solid wall (push out)
-- after moving, resolve: push player out along smallest axis
if overlaps(player, wall) then
-- came from left
player.x = wall.x - player.w
endFor full platformer resolution (all 4 sides), resolve X first, then Y — two separate checks.
When it breaks
| Symptom | Fix |
|---|---|
| Tunneling at high speed | Move in smaller steps or clamp position on hit; cap dt with dt = math.min(dt, 1/30) |
| Collision fires every frame | Resolve position after detection so they no longer overlap. |
| Nothing collides | print() both boxes’ x/y/w/h — usually a width/height is 0 or nil |