Skip to main content
gamedev.net
🔒 Locked

Collision Detection

Started by kiznore 6 replies 550+ views
Original Post
kiznore
kiznore
Hi ya i need help with my asteroids game. I''ve been trying for a while now but with now luck. Im trying to test my bullets against my asteroids. I have an array of 5 bullets and an array of asteroids. The bullsts have a x and y position and my asteroids also have an x and y pos. My asteroid are very round so that i could use it radius as a way of testing collsion. What i tried to do was to get the length of the line between the asteroid and the bullet and if the length of the line was smaller or equal to the radius, then there was collsion. Is this correct. Does anyone out there have any other ideas how to get collsion. PLease help Thanks below is the code for collsion ive been trying to implement. int cIdleThreatApp::CollisionDetection() { int i, j; int radius = 41; float length_of_line; float astx, asty, bulletx,bullety; float astx_center = astx + radius; float asty_center = asty + radius; float testx, testy; for (i = 0; i < MAX_ASTEROIDS; i++) { astx = Asteroid.Asteroid.XPos; asty = Asteroid.Asteroid[i].YPos; for (j = 0; j < MAX_BULLETS; j++) { bulletx = Ship.Bullets[j].xcenter; bullety = Ship.Bullets[j].ycenter; testx = bulletx - astx_center; testy = bullety - asty_center; length_of_line = sqrt((testx * testx) (testy * testy)); if(length_of_line < radius) { return 1; Asteroid.Asteroid[i].alive = false; Ship.Bullets[j].alive = false; } } } }
SpaceDude
SpaceDude
put this after "astx =" and "asty =" lines:

astx_center = astx + radius;
asty_center = asty + radius;

[edited by - SpaceDude on May 2, 2004 11:01:17 AM]
Thunder_Hawk
Thunder_Hawk
quote:
Original post by kiznore
length_of_line = sqrt((testx * testx) (testy * testy));



This might not be the only thing wrong with your code, but that line should read (I''m guessing you just made a typo):

length_of_line = sqrt((testx * testx) + (testy * testy));



______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
CodeMonkeyX
CodeMonkeyX
I think your idea for collision detection is good but I have a few comments on the code. I'm pretty sure these are valid comments but I'm not a professional so I'm not making any promises.

int cIdleThreatApp::CollisionDetection()
{

int i, j;
int radius = 41;
float length_of_line;
float astx, asty, bulletx,bullety;
float astx_center = astx + radius; //astx is being used before it has been initialized
float asty_center = asty + radius; //asty is being used before it has been initialized
float testx, testy;

for (i = 0; i < MAX_ASTEROIDS; i++)
{


astx = Asteroid.Asteroid.XPos;
asty = Asteroid.Asteroid.YPos;

//Here is where you should assign values to astx_center and asty_center
//However draw a picture of the asteriod to make sure your geometry is correct
//I'm guessing that you are measuring from the top left hand corner

//WARNING: The following section of comments I made on my initial post
//I am almost certain they are based on false assumptions and should be ignored!

//If this is so than adding radius(41) will give an actual radius of sqrt((41 * 41)+(41 * 41))=57.98
//After some geometry I found that sqrt((29 * 29)+(29 * 29))= 41
//I think that you should use 29 instead of 41 based on my assumptions about your situation

//END WARNING
//That section was written under assumption that the top left hand corner fell on the perimeter of the cirlce
//The function: astx_center = astx + radius; is most likely correct


//This is purely a style thing but I like to see nested loops indented
//but I think you did that just for the message board
for (j = 0; j < MAX_BULLETS; j++)
{

bulletx = Ship.Bullets[j].xcenter;
bullety = Ship.Bullets[j].ycenter;

//at first I thought you need to use an absolute value on the two functions below
//however on closer inspection I see that both are being squared later
//therefore it dosen't matter what sign they have
testx = bulletx - astx_center;
testy = bullety - asty_center;

length_of_line = sqrt((testx * testx) (testy * testy)); //add a plus sign



if(length_of_line < radius)
{

return 1;

//Some might say that the collision detection function should be reserved onLY for collision detection
//It's really a matter of opinion though
Asteroid.Asteroid[i].alive = false;
Ship.Bullets[j].alive = false;

}
}
}

}

Good luck!

edit: fixed a false assumption I made


[edited by - CodeMonkeyX on May 2, 2004 3:09:10 PM]
kiznore
kiznore
you see, astx and asty are the x and y coordinates of my asteroid sprite. the reason that i added on 41 to both was because i wanted to have the center of the sprite(because it is drawn from top left corner to bottom right corner, u all prob know that anyway. I have it kind of going but not accurate. anyother suggestion. I was also wonder ow i should go about checking my ship against the asteroids. The bullets only take up a couple of pixels, but the ship is very different, any help
CodeMonkeyX
CodeMonkeyX
What do you mean by not accurate? The type of accuracy problem may help to determine the solution.
kiznore
kiznore
What i mean is that sometimes when i shoot the asteroid, it only disappears when the bullet is very near the center of the asteroid(my code going wrong somewhere). Another thing is that the asteroid is a circle, but the whole sprite is a square, just that the backgorund is transparent. the prob is that at each corner then theres a bit extra if you know what i mean, its hard to explain. the radius is going to be bigger than the radius of the circle. how would i get to the center of the circle and use the radius that is that actual radius of the circle. cant think here, been in front of comp all day. Any tips on the ship aswell.
thanks
CodeMonkeyX
CodeMonkeyX
If an asteroid is centered in the sprite then you can use functions like this:

atx_center = atx + (sWidth / 2);
aty_center = aty + (sHeight / 2);

Where sWidth is the width of the sprite and sHeight is the height of the sprite.

If the asteroid meets all four sides of the sprite then (sWidth / 2) = (sHeight / 2) = radius. So in this case your function using radius would apply.

One thing I missed when I originally looked at your code is that the test "if(length_of_line < radius)" should actually use a <= sign. This is because if the borders of the objects are touching but not intersecting there is still a collision. This may help with the accuracy problems.

These accuracy problems may also be caused by how often the collision test is being preformed vs. how fast the relative speed of the bullet and asteriod is.

For example lets say the bullet is moving at speed 20 towards the asteriod which is moving at speed 12 towards the bullet. The relative speed between the two objects is 32. This means that the bullet may be just outside of the asteriod during one collision test but then jump 32 into the asteriod before another test is preformed.

In collesion tests accuracy in timing can be just as important as accuracy in space. However, before you make any changes to timing try smaller changes like changing the < to a <=. Also, perhaps padding the radius a little might help.


Depending on the shape of the ship you may be able to assign it a radius as well. Your collision test might then look like this:

if(length_of_line <= radius + ship_radius)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.