Archived

This topic is now archived and is closed to further replies.

This topic is 5620 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hey all, I''m writing an SDL-based clone of Pong with extremely simple pixel-based graphics. I have it running except for collision detection between the paddles and ball - and unfortunately this is the one area I have never been able to successfully implement. The game is set-up with 2 paddles, with the height and width and the x,y center of the paddle available. The ball has an x,y center and a radius. The way I''ve attempted to approach the problem is by using a long if statement comparing the x,y position of the ball to the left and right edges of the paddle - if it is within the left and right edges of the paddle and it''s y position is close enough, reverse the y-velocity. In theory I thought it would work, if a bit oddly, but it actually just causes the ball to bounce back no matter what! Here is that portion of code:
	if((ball->getXPos() >= (player1->getXPos() - (0.5 * player1->getWidth())) || ball->getXPos() <= (player1->getXPos() + (0.5 * player1->getXPos())))
&& ball->getYPos() >= (player1->getYPos() - (0.5 * player1->getHeight())))
{
ball->setYVel(-1 * ball->getYVel());
} 
if someone could point out the flaw in my logic, or [preferably] a better, more realistic method, that''d be nice too! Thanks.

Share on other sites
quote:
Original post by DyDx
if it is within the left and right edges of the paddle and it''s y position is close enough, reverse the y-velocity.
*snip
	if((ball->getXPos() >= (player1->getXPos() - (0.5 * player1->getWidth())) || ball->getXPos() <= (player1->getXPos() + (0.5 * player1->getXPos())))*snip

When you write it out in English, you say the ball is between the edges of the paddle (or the ball is less than the right side AND more than the left side)...

...but your code says OR, so your code only cares if the ball is EITHER to the right of the left side OR to the left of the right side.

Try changing || to && and see if that works

Share on other sites
here is how i handled it in my first ever game

    if(theBall->xVel < 0) // ball is moving left{	if( (theBall->xPosition < leftPlayer.xPosition+leftPlayer.width) &&			theBall->xPosition > leftPlayer.xPosition)	{		if((theBall->yPosition+theBall->height > leftPlayer.yPosition) &&				theBall->yPosition < leftPlayer.yPosition+leftPlayer.height)		{				theBall->xVel = -theBall->xVel;				leftPlayer.iAmHit(); // used for power ups		}	}}else	// ball is moving right{	if((theBall->xPosition+theBall->width > rightPlayer.xPosition) &&		theBall->xPosition+theBall->width < rightPlayer.xPosition+rightPlayer.width)	{		if((theBall->yPosition+theBall->height > rightPlayer.yPosition) && 			theBall->yPosition < rightPlayer.yPosition+rightPlayer.height)		{			theBall->xVel = -theBall->xVel;			rightPlayer.iAmHit(); // used for power ups		}	}}

[edited by - deal on March 2, 2003 1:57:11 PM]

Share on other sites
Thanks ducki, I didn't notice that :D

Anyways, it works for the most part now, but I still have anomalies - specifically, when it hits the corner of the paddle. When this happens, either the ball just goes through the paddle OR the ball sort of slides through the paddle... hard to describe.

Here is the current code:

void checkCollisions(Ball *ball, Paddle *player1, Paddle *player2){	// check for collisions with player1	if((ball->getXPos() >= (player1->getXPos() - (0.5 * player1->getWidth())) && ball->getXPos() <= (player1->getXPos() + (0.5 * player1->getXPos())))	&& (ball->getYPos() + ball->getRadius()) >= (player1->getYPos() - (0.5 * player1->getHeight())))	{		ball->setYVel(-1 * ball->getYVel());  }  // check for collisions with player2  if((ball->getXPos() >= (player2->getXPos() - (0.5 * player2->getWidth())) && ball->getXPos() <= (player2->getXPos() + (0.5 * player2->getXPos())))	&& (ball->getYPos() - ball->getRadius()) <= (player2->getYPos() + (0.5 * player2->getHeight())))	{		ball->setYVel(-1 * ball->getYVel());  }}

Anyone else with tips?

Thanks.

[edited by - DyDx on March 2, 2003 2:03:30 PM]

Share on other sites
I''d be willing to bet that the ball is slipping past because the XPos of the ball doesn''t take its radius into account.

Duplicate the bit about adding the ball.radius to its XPos just like you did for the YPos and that should detect the collision.

Share on other sites
incorporate direction of ball into the collision detection similar to my code posted above.

what is happening is that the balls x velocity is constantly being reversed kinda like below

\
/
\
/
\

Share on other sites
quote:
Original post by ducki
I''d be willing to bet that the ball is slipping past because the XPos of the ball doesn''t take its radius into account.

Duplicate the bit about adding the ball.radius to its XPos just like you did for the YPos and that should detect the collision.

Hmm well I tried that:

void checkCollisions(Ball *ball, Paddle *player1, Paddle *player2){	// check for collisions with player1	if(((ball->getXPos() + ball->getRadius()) >= (player1->getXPos() - (0.5 * player1->getWidth())) && (ball->getXPos() - ball->getRadius()) <= (player1->getXPos() + (0.5 * player1->getXPos())))	&& (ball->getYPos() + ball->getRadius()) >= (player1->getYPos() - (0.5 * player1->getHeight())))	{		ball->setYVel(-1 * ball->getYVel());  }  // check for collisions with player2  if(((ball->getXPos() + ball->getRadius()) >= (player2->getXPos() - (0.5 * player2->getWidth())) && (ball->getXPos() - ball->getRadius()) <= (player2->getXPos() + (0.5 * player2->getXPos())))	&& (ball->getYPos() - ball->getRadius()) <= (player2->getYPos() + (0.5 * player2->getHeight())))	{		ball->setYVel(-1 * ball->getYVel());  }}

To no avail... it still goes through the paddle at corners and there is still weird sliding about on the bottom of the screen. (and sometimes the top)

I can send the executable and SDL.dll if anyone would care to see what I''m speaking about... the rar file is less than 700kb. (I can include all the source code too if you''d like)

Share on other sites
quote:
Original post by deal
incorporate direction of ball into the collision detection similar to my code posted above.

what is happening is that the balls x velocity is constantly being reversed kinda like below

\
/
\
/
\

Hmm I thought your method was about the same as mine, I guess I''ll have to examine it more closely. thanks.

Share on other sites
try something like below

  void checkCollisions(Ball *ball, Paddle *player1, Paddle *player2){		// check for collisions with player1	if( /*code here to check ball is moving left*/)	{		if((ball->getXPos() >= (player1->getXPos() - (0.5 * player1->getWidth())) 			&& ball->getXPos() <= (player1->getXPos() + (0.5 * player1->getXPos())))				&& (ball->getYPos() + ball->getRadius()) >= (player1->getYPos() - (0.5 * player1->getHeight())))		{					ball->setYVel(-1 * ball->getYVel());  		}	}		// check for collisions with player2	else	{		if((ball->getXPos() >= (player2->getXPos() - (0.5 * player2->getWidth())) 			&& ball->getXPos() <= (player2->getXPos() + (0.5 * player2->getXPos())))				&& (ball->getYPos() - ball->getRadius()) <= (player2->getYPos() + (0.5 * player2->getHeight())))			{					ball->setYVel(-1 * ball->getYVel());  		}	}}

Share on other sites
quote:
Original post by deal
try something like below

    void checkCollisions(Ball *ball, Paddle *player1, Paddle *player2){		// check for collisions with player1	if( /*code here to check ball is moving left*/)	{		if((ball->getXPos() >= (player1->getXPos() - (0.5 * player1->getWidth())) 			&& ball->getXPos() <= (player1->getXPos() + (0.5 * player1->getXPos())))				&& (ball->getYPos() + ball->getRadius()) >= (player1->getYPos() - (0.5 * player1->getHeight())))		{					ball->setYVel(-1 * ball->getYVel());  		}	}		// check for collisions with player2	else	{		if((ball->getXPos() >= (player2->getXPos() - (0.5 * player2->getWidth())) 			&& ball->getXPos() <= (player2->getXPos() + (0.5 * player2->getXPos())))				&& (ball->getYPos() - ball->getRadius()) <= (player2->getYPos() + (0.5 * player2->getHeight())))			{					ball->setYVel(-1 * ball->getYVel());  		}	}}

After dealing with the mass of paranthesis, it works pretty damn well.

Thanks!

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
16
5. 5

• 14
• 29
• 11
• 11
• 9
• Forum Statistics

• Total Topics
631774
• Total Posts
3002274
×