Help with collision

Started by
4 comments, last by knealeaj 19 years, 10 months ago
Hi guys. I am making a break out clone . I have a function to test for collision between the players ball and the blocks. I was wondering how to distinguish if the ball has hit the sides of the block or the top or bottom. My code can be found at http://members.lycos.co.uk/knealeaj/files Thanks
Advertisement
I made a VERY quick check in your code and I can only ASSUME your doing it in 3D ...

Anyway, are you able to check which direction the normal is pointing on the triangles? That might just solve your problem.

- Patrik Willbo

The Lord says He can get me out of this mess, but He''s pretty sure you''re fucked.
- Stephen (Braveheart)
Since the motion/collision is presumably occuring in 2 dimensions, maybe your collision-test function could return a vector pointing away from the face with which the ball collided, and of course null or zero if there is no collision.
yeah the motion is in 2d.could you give an example of what you mean smitty1276.

Thanks
here is an uber way to do it if your testing square/rectangle collisoin, btw its way easy to to get the square coordinates for an ellipse. WARNING* This doesn't use vector collision, so its very algebra friendly, being vector is a trig concept and all.
This tests for all 3 cases of collision, regardless the sides of the rectangle. By 3 cases I mean if the rectangle that is colliding with object is bigger or inside the boundries of the object, if the rectangle has one that is off one of the objects side, or if the rectangle has a side that is off the other side of the object. A note about my code. Each entity in my game has it's own collision function. And since your speaking of break, Imma give you my pong_collision.cpp source. Here ya go :] Enjoy->
#include "entities.h"// for all auto-movebool CBall::Move(){		x0 += velocity_x;	y0 += velocity_y;	return true;}bool CBall::Collision(CGameWorld *GameWorld){	// check the walls	if ((x0 + velocity_x) < GameWorld->GetScreenX()/2 || (x0 + radius + velocity_x) > (GameWorld->GetScreenX()))	{			velocity_x = -velocity_x;		// make a little noise		MessageBeep(MB_OK);	}	// still checking walls	if ((y0 + velocity_y) < 0 || (y0 + radius + velocity_y) > GameWorld->GetScreenY()/2)	{		velocity_y = -velocity_y;		// make a little noise        MessageBeep(MB_OK);	}	return true;} bool CBall::Collision(CGameWorld *GameWorld, CPaddle *Paddle){		// test for right  and lef side collision, this tests all three cases :]		if (y0 <= (Paddle->GetY()+Paddle->GetLength()) && (y0 + radius) >= Paddle->GetY())		{				if ((x0 + velocity_x) <= (Paddle->GetX()+Paddle->GetWidth()) 					&& (x0+radius+velocity_x) >= Paddle->GetX())				{					velocity_x = -velocity_x;										// see if ball went thru wall. If it did, add its relected direction pixel					// by pixel until out of wall. It may even push the paddle up					while (1)					{						if ((x0 + velocity_x) < GameWorld->GetScreenX()/2 							 || (x0 + radius + velocity_x) > (GameWorld->GetScreenX()))						{							if (velocity_x < 0) // ball is traveling left and will go through left wall							{									x0++;									while(x0+radius >= Paddle->GetX()) // push the paddle out of the ball								{										Paddle->AddX(1);								}							}							else							{									x0--; // ball is traveling right and will go through right wall								while(x0 <= Paddle->GetX()+Paddle->GetWidth()) // push the paddle out of the ball								{										Paddle->AddX(-1);								}															}						}						else							break;					}					MessageBeep(MB_OK);				}								}		// test for top and bottom collisoin, THIS TESTS ALL THREE CASES!!! :]		if (x0 <= (Paddle->GetX()+Paddle->GetWidth()) && (x0+radius) >= Paddle->GetX())		{			if ((y0 + radius + velocity_y) >= Paddle->GetY()			   && (y0 + velocity_y) <= (Paddle->GetY()+Paddle->GetLength()))			{				velocity_y = -velocity_y;								// see if ball went thru wall. If it did, add its relected direction, pixel				// by pixel until out of wall. It may even push the paddle up				while (1)				{					if ((y0 + velocity_y) < 0 						 || (y0 + radius + velocity_y) > GameWorld->GetScreenY()/2)					{						if (velocity_y < 0) // ball going up						{								y0++;							// if paddle is in ball, push paddle out! :]							while (y0+radius >= Paddle->GetY())							{								Paddle->AddY(1);							}						}						else						{								y0--; // ball going down 							// if paddle is in ball, push paddle out! :]							while (y0 <= Paddle->GetY()+Paddle->GetLength())							{								Paddle->AddY(-1);							}						}					}					else						break;				}											MessageBeep(MB_OK);				//MessageBox(NULL, "TEST", "", MB_OK);			}				}		return true;}void CPaddle::Collision(CGameWorld* GameWorld, CBall* Ball, CGDI_X *gdix){	if (y0 < 0)	{		y0 += velocity_y;	}		if ((y0+length) > GameWorld->GetScreenY())	{		y0 -= velocity_y;	}	if (x0 < 0)	{		x0 += velocity_x;	}	if (x0+width > GameWorld->GetScreenX())	{		x0 -= velocity_x;	}	// checks for right or left side collision with ball	if (y0 <= Ball->GetY()+Ball->GetRadius() && y0+length >= Ball->GetY())		if (x0 <= Ball->GetX()+Ball->GetRadius() && x0+width >= Ball->GetX())		{			// Paddle is moving to left			if (direction == 180 || left == true)			{				x0 += velocity_x;				// find out if i need to reflect the ball				if (Ball->GetVelX() > 0)					Ball->SetVelX(Ball->GetVelX()*-1);			}			// Paddle moving to right			if (direction == 360 || right == true)			{				x0 -= velocity_x;				// find out if I need to refelct the balls trajectory				if (Ball->GetVelX() < 0)					Ball->SetVelX(Ball->GetVelX()*-1);			}		}  	// check for collision with the ball	// start with the top of the rectangle	// test for top and bottom collision		if (x0 <= (Ball->GetX()+Ball->GetRadius()) && (x0+width) >= (Ball->GetX()))		if (y0 <= Ball->GetY()+Ball->GetRadius() && (y0+length) >= (Ball->GetY()))		{				// figure out the direction the ball is traveling and which side did it hit			// its direction vector I guess ^?			if (direction == 90 || up == true) // paddle moving up			{				y0 += velocity_y;				if (Ball->GetVelY() > 0) // if ball is "falling"				{					Ball->SetVelY(Ball->GetVelY()*-1);					//Ball->AddEnergyY(8);					MessageBeep(MB_OK);				}				else				{					//Ball->AddEnergyY(5);					MessageBeep(MB_OK);				}			}			if (direction == 270 || down == true) // paddling moving down			{				y0 += -velocity_y;					//gdix->DrawLine(x0, y0, x0+width, y0, RGB(0, 0, 255));				if (Ball->GetVelY() < 0) // if ball is "rising"				{					Ball->SetVelY(Ball->GetVelY()*-1);					//Ball->AddEnergyY(8);					MessageBeep(MB_OK);								}				else				{					//Ball->AddEnergyY(5);					MessageBeep(MB_OK);				}			}		}	up = left = down = right = false;}


[edited by - xorjesus on May 27, 2004 2:39:02 AM]
I study day and night, memorizing the game.
For breakout, remember that the ball can jump right over a corner of a brick in one frame, appearing to miss a block entirely when the path actually crossed a little bit of corner. I fell for that one

Mark
Sound Effects For Game Developers
http://www.indiesfx.co.uk

This topic is closed to new replies.

Advertisement