Collision detection

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.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Collision detection

Post by micha »

I understand the problem.

First, I claim, that the game will work fine, even with this flaw. In practice the player will not notice the difference.

Second, if you still want to have it mathematically correct, you can calculate the y-coordinates, of the "contact":

Code: Select all

alpha = (paddle.x - ball.oldx) / (ball.x-ball.oldx)
contact.y = ball.oldy + (ball.y-ball.oldy)*alpha
This code basically draws a straight line from the old position to the new position and calculations the intersection with the vertical line of the paddle.

Now replace ball.y by contact.y in the collision check and your done.
(Disclaimer: I wrote the above formula without testing it. I am quiet sure, it is correct, but if it works incorrectly, please tell me and I will check)
User avatar
jag_e_nummer_ett
Citizen
Posts: 52
Joined: Thu May 16, 2013 6:31 pm
Location: Stockholm, Sweden

Re: Collision detection

Post by jag_e_nummer_ett »

I guess the most simple way to make it move is just to make the movement a loop.
This wont be a problem as long as I don't got multiple stuff moving, and I am excluding the paddles from this system.

Code: Select all

function checkCondition()
    if ball.x < paddle.x
    and oldx > paddle.x
    and ball.y > paddle.y
    and ball.y < paddle.y + paddle.h then
        ball.xvel = ball.xvel * -1
    end
end

ball.x = 5
ball.y = 5
ball.xvel = -3
ball.yvel = 3

local steps = ball.xvel
if steps < 0 then steps * -1 end

for count = 1,steps do
    oldx = ball.x
    checkCondition()
    ball.x = ball.x + ball.xvel
    ball.y = ball.y + ball.yvel
end
Would this work? I'll try it :ultraglee:

EDIT: Oh yea this would only work if the x velocity is the same as the y velocity... :roll:
User avatar
jag_e_nummer_ett
Citizen
Posts: 52
Joined: Thu May 16, 2013 6:31 pm
Location: Stockholm, Sweden

Re: Collision detection

Post by jag_e_nummer_ett »

micha wrote:I understand the problem.

First, I claim, that the game will work fine, even with this flaw. In practice the player will not notice the difference.

Second, if you still want to have it mathematically correct, you can calculate the y-coordinates, of the "contact":

Code: Select all

alpha = (paddle.x - ball.oldx) / (ball.x-ball.oldx)
contact.y = ball.oldy + (ball.y-ball.oldy)*alpha
This code basically draws a straight line from the old position to the new position and calculations the intersection with the vertical line of the paddle.

Now replace ball.y by contact.y in the collision check and your done.
(Disclaimer: I wrote the above formula without testing it. I am quiet sure, it is correct, but if it works incorrectly, please tell me and I will check)
:O I missed the second page!
I'll try this right now!!
User avatar
jag_e_nummer_ett
Citizen
Posts: 52
Joined: Thu May 16, 2013 6:31 pm
Location: Stockholm, Sweden

Re: Collision detection

Post by jag_e_nummer_ett »

micha wrote:I understand the problem.

First, I claim, that the game will work fine, even with this flaw. In practice the player will not notice the difference.

Second, if you still want to have it mathematically correct, you can calculate the y-coordinates, of the "contact":

Code: Select all

alpha = (paddle.x - ball.oldx) / (ball.x-ball.oldx)
contact.y = ball.oldy + (ball.y-ball.oldy)*alpha
This code basically draws a straight line from the old position to the new position and calculations the intersection with the vertical line of the paddle.

Now replace ball.y by contact.y in the collision check and your done.
(Disclaimer: I wrote the above formula without testing it. I am quiet sure, it is correct, but if it works incorrectly, please tell me and I will check)

Yea so while testing it I notice a clear difference!
It is working perfectly... for the left side.

I am having a really hard time figuring out how the formula works, so could you help me out?
I need one that works when the ball is travelling to the right.

It would be great if you just made another formula for the right side, but it would be awesome if I learned this and could use this in my future code!
User avatar
jag_e_nummer_ett
Citizen
Posts: 52
Joined: Thu May 16, 2013 6:31 pm
Location: Stockholm, Sweden

Re: Collision detection

Post by jag_e_nummer_ett »

I am noticing even more errors, from time to time it does not seem to work when the ball is travelling downwards either.
It is really weird, and I am confused :cry:
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Collision detection

Post by micha »

Maybe, this is because your ball has a height and width (instead of being a single point)? For a collision with the right wall you have to check for ball.x+ball.width not for ball.x. Same goes for the bottom collision. Check ball.y+ball.height instead of ball.y.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Collision detection

Post by micha »

And now for the explanation of the formula. I made a figure.
paddlecollision.png
paddlecollision.png (13.65 KiB) Viewed 2503 times
You see the ball in red and its bounding box (gray square around the balls). The coordinates of the ball are the upper left coordinates of the bounding box. The ball moves from right to left and somewhere crosses the line of the paddle.
To determine the coordinates of the potential collision, we have to find the coordinates of paddle.x and collision.y. Now comes some geometry. You see the horizontal arrows in blue and green. If you calculate the ration green divided by blue, then you get a number between 0 and 1. This is alpha. For geometrical reasons (its called Intercept theorem) the ratio of the vertical green and blue arrows is the same.
So to find the value of collision.y we first calculate the vertical blue arrow (ball.y-ball.oldy) and multiply it by alpha to get the length of the green vertical arrow. We have to add this to the ball.oldy. So the final formula is

Code: Select all

collision.y = ball.oldy + (ball.y-ball.oldy)*alpha
To find alpha in the first place, we divide the horizontal green arrow by the horizontal blue one:

Code: Select all

alpha = (paddle.x - ball.oldx) / (ball.x-ball.oldx)
If you now check for collision on the right side, you have to take the balls width into account. For calculating alpha, instead of using paddle.x you need paddle.x-ball.width, because collision already occurs, when the balls right side collides with the paddle.
User avatar
jag_e_nummer_ett
Citizen
Posts: 52
Joined: Thu May 16, 2013 6:31 pm
Location: Stockholm, Sweden

Re: Collision detection

Post by jag_e_nummer_ett »

Mind = blown :ultrashocked:

Your solution was greatly more efficient and noble!
Doe I already made a solution myself, and it works, so I'm satisfied.

My solution is as follows

Code: Select all

	local steps = ball.xv
	if steps < 0 then steps = steps * -1 end

	for count = 1,steps do
		ball.oldx = ball.x
		ball.oldy = ball.y

		ball.x = ball.x + ball.xv/steps * dt
		ball.y = ball.y + ball.yv/steps * dt

		checkCondition()
	end
This works perfectly fine, doe it does create a bit of lag when the velocity is above 2500 ~ish...
That wont be a problem anyways, no one can be quick enough to come up to such speed.
I have it set to increase by 10% each time it hits a paddle, but I've also added a break so the velocity cannot get above 10000 or below -10000.

I am overjoyed of your answers! And graceful that you took your time!!

I do not need any more help at the moment with my pong game, so for now; case closed :)
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 5 guests