# Collision problems with Space Invaders

• 03-23-2006
dxfoo
I have aliens flying about the screen. If they hit the player, the player looses a life. For now, I set the player's Y to 900 which takes him off screen. So, as the code explains, for every monster that is currently alive, does the monster's x/y coordinates equal the player's x/y location. If so, set the player offscreen for now. I noticed the positions have to be "exact" for the PC to loose a life. How can I detect if "any" monster falls into the player's range? I always had trouble with this. Any help would be great.

Code:

```        // Player colliding into the monsters         for (register int i = 0; i < MAX_MONSTERS; i++) {                 if (monster[i].getAlive()) {                         if ((monster[i].getX() == PC.getX()) &&                                 (monster[i].getY() == PC.getY()))                                 PC.setY(900);  // Take player offscreen for now.                 }         }```
• 03-24-2006
VirtualAce
Use the distance formula and work in terms of the square of the distance. Essentially this is a spherical bounding volume.

Code:

``` float Vector2::GetDistanceSq(const Vector2 &pt) {   float diffx=pt.m_fX-m_fX;   float diffy=pt.m_fY-m_fY;   return (diffx*diffx+diffy*diffy); }```
• 03-24-2006
dxfoo
Okay, and what would I do with the returned value? I did my own guess and the monsters do hit me except for ones going through the center of my ship. Why would that be?

Code:

```        // Player colliding into the monsters         for (register int i = 0; i < MAX_MONSTERS; i++) {                 if (monster[i].getAlive()) {                         float val = GetDistanceSq(monster[i]);                         if (val < 64)                                 PC.setY(900);                 }         } } float GetDistanceSq(Monster &m) {         float diffx = PC.getX() - m.getX();         float diffy = PC.getY() - m.getY();         return (diffx*diffx + diffy*diffy); }```
EDIT: I changed 64 to 128 and I'm getting much better and accurate results. Thanks for the help once again.
• 03-25-2006
VirtualAce
If you are working in terms of the square of the distance then the value returned is just that. It is the square of the actual distance. So if the actual distance is 10 world units, the function will return 100 world units. We are trying to avoid the costly square root which costs many CPU cycles and in this case unecessarily so.

The distance must be checked on all sides of the unit. Your code would look like this:

Code:

``` //Distance test (Spherical) float dist=GetDistSq(Player.Pos,Object.Pos); if (dist<Player.iBoundingSphereSize) {   //Player has been hit }```
The problem with this code is that spheres do not make perfect bounding volumes. And when a sphere is off, it's way off. The sphere test should be done as a trivial rejection test. If this test fails, then you move to the more expensive bounding box test.

You may also want to check for time intervals for collisions instead of using position. If the time interval is empty, there is no collision else there is.