To learn LOVE2D I am creating a simple project. Player moves the square with arrows keys until it hits the goal square, at which point the game is won.

function isCollision(x1,y1,w1,h1,x2,y2,w2,h2)
    return (x1<x2+w2)and(x2<x1+w1)and(y1<y2+h2)and(y2<y1+h1)

function love.update(dt)
    if love.keyboard.isDown("escape") then love.event.quit() end
    if isCollision(player.x,player.y,player.w,player.h,goal.x,goal.y,goal.w,goal.h) then
        if love.keyboard.isDown("space") then love.load() end
        delta = player.speed*dt
        if love.keyboard.isDown("right") and player.x<=800-player.w then player.x=player.x+delta end
        if love.keyboard.isDown("left") and player.x>=0 then player.x=player.x-delta end
        if love.keyboard.isDown("down") and player.y<=600-player.h then player.y=player.y+delta end
        if love.keyboard.isDown("up") and player.y>=0 then player.y=player.y-delta end      

But sometimes the square overshoots the goal and it becomes lodged in the goal.

The unfortunate collision

How do I make it so that engine detects when the player simply touches the goal and stops there, without moving further in the frame?

Disclaimer: Using a collision detection library like bump.lua would be too easy. I want to learn the relevant practices so that I can apply it to retro consoles and computers in the future.


At the moment you are checking for a collision between where the player is now and the goal square. Instead, you can define a rectangle which goes from where the player was last frame and where he is now. If there is a collision between this rectangle and the goal square this means one of three things:

1) The player collided with the square last frame (impossible, would have been noted already)

2) The player collided with the square this frame (what you're checking for now)

3) The player collided with the square "in between" the frames (the extra thing you want to check)

Where 2) and 3) are exactly what you want to check!

Note that to construct this new rectangle this you have to keep track of the square's old position. Or, equivalently, of how it moved last frame.

| improve this answer | |
  • \$\begingroup\$ I wasn't clear enough; 3) is the case I was asking about. \$\endgroup\$ – shinkarom May 24 '19 at 16:59
  • \$\begingroup\$ The point is to check not just where the player currently is for a collision, but the whole area between where he was and where he currently is.You can always make the rectangle I'm describing smaller to avoid case 1) and/or case 2). \$\endgroup\$ – ScienceSnake May 24 '19 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.