Archived

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

knealeaj

Help with collision

Recommended Posts

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

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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-move

bool 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]

Share this post


Link to post
Share on other sites