Newb question, how do I detect collision?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Newb question, how do I detect collision?

Post by Vimm »

So I just started with LOVE and lua, and I'm trying to make a simple little pong remake kinda thing, I got the paddles moving and the ball "sort of" moving, but I don't know how to check for collision between the ball and the paddle, i tried checking if the balls x coordinates overlapped the paddles y, but that didn't work cuz that would have to be a pixel perfect collision. \

I've never really understood collision detection so if someone can help me out thatd be awesome!
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: Newb question, how do I detect collision?

Post by MadByte »

If your ball is a a classic pong rectangle you could start by figuring out a simple function to detect collisions between axis aligned bounding boxes (AABB's). You could find a working function almost everywhere in the web and in the löve wiki, but I think it might be more fun to actually figure it out yourself. Therefor you just check if a position e.g the x axis of an object overlaps with the x position of another object.

Here is an example for one side:
Image

This only checks a collision between the right side of the a box and the left side of the b box. You can use almost the same comparison to check the other side on the x axis and the same for the y axis. Then you can detect proper collisions.

If you just want the function without figuring out how it works, here is a link.
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Re: Newb question, how do I detect collision?

Post by Vimm »

MadByte wrote:If your ball is a a classic pong rectangle you could start by figuring out a simple function to detect collisions between axis aligned bounding boxes (AABB's). You could find a working function almost everywhere in the web and in the löve wiki, but I think it might be more fun to actually figure it out yourself. Therefor you just check if a position e.g the x axis of an object overlaps with the x position of another object.

Here is an example for one side:
Image

This only checks a collision between the right side of the a box and the left side of the b box. You can use almost the same comparison to check the other side on the x axis and the same for the y axis. Then you can detect proper collisions.

If you just want the function without figuring out how it works, here is a link.
Thanks for responding! using the diagram you showed me I managed to kind of make it work, I can make the ball bounce between the paddles, but it bounces back and forth regardless of if it hit the paddle or not, because it's till reaching the same x value and not the y. I don't know how to add the y to it and the function you sent a link to confuses me haha XD
User avatar
Sheepolution
Party member
Posts: 264
Joined: Mon Mar 04, 2013 9:31 am
Location: The Netherlands
Contact:

Re: Newb question, how do I detect collision?

Post by Sheepolution »

Image

Here are 3 pairs of 2 rectangles, with the first 2 are colliding.

Here's a list of conditions that need to be true to confirm collision between the 2 rectangles.
Compare them with the image above and see if they're true.

The top of A < the bottom of B - yes, yes, yes
The top of B < the bottom of A - yes, yes, no
The left of A < the right of B - yes, yes, yes
The left of B < the right of A - yes, yes, yes

The 3rd pairs fails on the 2nd condition, meaning there is no collision.

If we put this in code you get:

Code: Select all

function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
  return x1 < x2+w2 and
         x2 < x1+w1 and
         y1 < y2+h2 and
         y2 < y1+h1
end
Because:
x1 = the left of A
x1+w1 = the right of A
y1 = the top of A
y1+h1 = the bottom of A

Replace the 1 with 2 and you get B

Now you can use the function like this:

Code: Select all

checkCollision(pad.x, pad.y, pad.width, pad.height, ball.x, ball.y, ball.width, ball.height)
I hope that cleared things up.
User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Re: Newb question, how do I detect collision?

Post by Vimm »

Sheepolution wrote:Image

Here are 3 pairs of 2 rectangles, with the first 2 are colliding.

Here's a list of conditions that need to be true to confirm collision between the 2 rectangles.
Compare them with the image above and see if they're true.

The top of A < the bottom of B - yes, yes, yes
The top of B < the bottom of A - yes, yes, no
The left of A < the right of B - yes, yes, yes
The left of B < the right of A - yes, yes, yes

The 3rd pairs fails on the 2nd condition, meaning there is no collision.

If we put this in code you get:

Code: Select all

function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
  return x1 < x2+w2 and
         x2 < x1+w1 and
         y1 < y2+h2 and
         y2 < y1+h1
end
Because:
x1 = the left of A
x1+w1 = the right of A
y1 = the top of A
y1+h1 = the bottom of A

Replace the 1 with 2 and you get B

Now you can use the function like this:

Code: Select all

checkCollision(pad.x, pad.y, pad.width, pad.height, ball.x, ball.y, ball.width, ball.height)
I hope that cleared things up.
That did clear things up a bit, I still don't 100% understand but I'm sure the more I use it and the more I program in general, the more I'll understand it, thanks!
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Newb question, how do I detect collision?

Post by airstruck »

Here's another approach you can use. If you store each box as a center point and a "half-width" and "half-height," the collision check is a bit simpler. Suppose your ball is 8x8 and your paddle is 8x32, so the half-width of each object is 4, the half-height of the ball is 4 and the half-height of the paddle is 16.
pong.png
pong.png (8.04 KiB) Viewed 9423 times
Now, calculate the distance between the center points on each axis. If the distance along X is less than the sum of the half-widths, and the distance along Y is less than the sum of the half-heights, then the objects are colliding.

In other words, the distance from the paddle's center to its sides is 4, and the distance from ball's center to its sides is 4, so if the distance between the center points along X is less than 8, the objects must overlap on the X axis. Apply the same rules for Y; if the boxes also overlap on the Y axis, they're colliding.

Code: Select all

local function checkCollision (a, b)
    local dx = math.abs(a.x - b.x) -- x distance
    local dy = math.abs(a.y - b.y) -- y distance
    local mx = a.halfwidth + b.halfwidth -- minimum x distance
    local my = a.halfheight + b.halfheight -- minimum y distance

    return dx < mx and dy < my
end
Storing the boxes as center points and half-widths/half-heights should also make finding the collision normal a bit more straightforward if you need to do that in future projects (shouldn't need it for pong, but you'd want it for something like breakout/arkanoid).
User avatar
pgimeno
Party member
Posts: 3609
Joined: Sun Oct 18, 2015 2:58 pm

Re: Newb question, how do I detect collision?

Post by pgimeno »

I've found this approach to be the most instructive:

Say A and B are the rectangles.

A and B don't collide if either of these conditions hold:

- The left border of B is to the right of the right border of A.
- The top border of B is below the bottom border of A.
- The right border of B is to the left of the left border of A.
- The bottom border of B is above the top border of A.

If neither of these conditions holds, the rectangles are colliding. These conditions are the exact opposite of the individual ones that Sheepolution posted:

- The left border of B is to the right of the right border of A: that's written as B.x > A.x + A.w
- The top border of B is below the bottom border of A: that's written as B.y > A.y + A.h
- The right border of B is to the left of the left border of A: that's written as B.x + B.w < A.x
- The bottom border of B is above the top border of A: that's written as B.y + B.h < A.y

So, the rectangles do NOT collide if:

Code: Select all

(B.x > A.x + A.w) or (B.y > A.y + A.h) or (B.x + B.w < A.x) or (B.y + B.h < A.y)
therefore they DO collide if:

Code: Select all

not ((B.x > A.x + A.w) or (B.y > A.y + A.h) or (B.x + B.w < A.x) or (B.y + B.h < A.y))
(I've simply inserted a 'not').

By De Morgan's laws, not (P1 or P2 or P3 or P4) equals (not P1) and (not P2) and (not P3) and (not P4).

Negating a < only needs changing it to >=, so the above check for whether they DO collide can be simplified to:

Code: Select all

(B.x <= A.x + A.w) and (B.y <= A.y + A.h) and (B.x + B.w >= A.x) and (B.y + B.h >= A.y)
which is basically what Sheepolution posted.

Depending on your boundary conditions, the >= might need to be > and vice versa, and the <= might need to be < and vice versa.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 1 guest