Click here to Skip to main content
15,886,873 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
Hi everybody, I'm having a problem with collision in my asteroids-type game. I succesfully managed to collide my asteroid with my spaceship, making my game re-start as if they had died.

However, since making the asteroids going out one side of the screen and back in the other, my spaceship now collides with the asteroid but the asteroids just spin round without my spaceship reseting.

Heres the code I did for my asteroid movement.

C#
Sprite[] asteroid = new Sprite[10];
Vector2[] AsteroidPosition = new Vector2[10];
for (int i = 0; i < 10; i++)
{
  if (Utils.CircToCircCollision(spaceship.GetPosition(), spaceship.GetRadius(),
    asteroid[i].GetPosition(), asteroid[i].GetRadius()))
  {
    LoadContent();
    Random r = new Random();
    Vector2 randPos = new Vector2(r.Next(800), r.Next(600));
    float randRot = MathHelper.ToRadians(r.Next(360));
   }
 }
 if (position.X < 0 - spaceship.GetWidth())
 {
   position.X = 800 + spaceship.GetWidth();
 }
 if (position.X > 800 + spaceship.GetWidth())
 {
   position.X = 0 - spaceship.GetWidth();
 }
 if (position.Y < 0 - spaceship.GetHeight())
 {
   position.Y = 600 + spaceship.GetHeight();
 }
 if (position.Y > 600 + spaceship.GetHeight())
 {
   position.Y = 0 - spaceship.GetHeight();
 }
 spaceship.SetPosition(position);
 for (int i = 0; i < 10; i++)
 {
   if (AsteroidPosition[i].X < 0 - asteroid[i].GetWidth())
   {
     AsteroidPosition[i].X = 800 + asteroid[i].GetWidth();
   }
   if (AsteroidPosition[i].X > 800 + asteroid[i].GetWidth())
   {
     AsteroidPosition[i].X = 0 - asteroid[i].GetWidth();
   }
   if (AsteroidPosition[i].Y < 0 - asteroid[i].GetHeight())
   {
     AsteroidPosition[i].Y = 600 + asteroid[i].GetHeight();
   }
   if (AsteroidPosition[i].Y > 600 + asteroid[i].GetHeight())
   {
     AsteroidPosition[i].Y = 0 - asteroid[i].GetHeight();
   }
   asteroid[i].SetPosition(AsteroidPosition[i]);
 }
Posted
Updated 9-Jan-11 12:24pm
v3
Comments
Sergey Alexandrovich Kryukov 9-Jan-11 18:29pm    
Yusuf, thank you for formatting the code.
Elliot, you don't show the code where a ship is "reset" or "collide" with the asteriod.
Elliot Harrison 9-Jan-11 18:41pm    
Sorry, how do I format the code so I can do it now?
Henry Minute 9-Jan-11 19:25pm    
Either select your code and then click the 'code block' widget, just above the edit box, or type in a <pre lang="cs"> tag on the line above your code and a </pre> tag on the line after.
Sergey Alexandrovich Kryukov 9-Jan-11 20:29pm    
Elliot, your problem was "less than" and "greater than" HTML character entities. The server script escaped them. You either need to use symbols and allow the script to escape them or use entities "Allow HTML" option (a radio button).

1 solution

You don't really show the source of the problem, but there are suspect things.

CircToCircCollision uses GetPosition; at the same time, boundary roll-over use AsteroidPosition[i]. How do I know they are the same and AsteroidPosition is updated? There is no indication of AsteroidPosition update. This is inconsistency that should be fixed. You need only one single source of object coordinate data. Then, you should always use a local variable for calculation.

Inside your loop:

C#
var coordinate = asteroid[index].GetPosition();
coordinate.X = //???
asteroid[index].SetPosition(coordinate);


You should not really construct instances of Random over and over inside loop, you should use the same instance.

You need to refactor your code in this way and see it it helps.
Also, your code is greatly spoiled by lack of code re-use and supportability.

We will start talking seriously only if you remove every single innediate constant like 10, 600, 800 (and -- in this context -- even 0). What's going to happen if you need different scene size? You need to everything is a single definition class, or better yet, to a single editable options class.

Coordinate roll-over itself should be made a separate function agnostic to what object is using it:

C#
static Coordinate RollOver(
            Coordinate coodinate,
            Coordinate min, Coordinate max,
            Coordinate size) {
    Coordinate newCoordinate = coodinate;
    //allowed as it works with a copy of parameters:
    min = min - size;
    max = max + size;
    if (coodinate < min)
        coodinate = max;
    else if (coodinate > max)
        coodinate = min;
    return newCoordinate;
} //RollOver


or even in this form:

C#
static void RollOver(
        ref Coordinate coodinate,
        Coordinate min, Coordinate max,
        Coordinate size) {
    min = min - size;
    max = max + size;
    if (coodinate < min)
        coodinate = max;
    else if (coodinate > max)
        coodinate = min;
} //RollOver


I would prefer the second form with ref, because additionally it will prevent using Asteroid property and force you into using a local (hopefully you will use local) variable. Using a property with some side effect could be a source of your particular problem; this form of the method would block the misuse of side effect.

All objects like Asteroid or Spaceship should be well encapsulated without exposing any fields (even via "internal"). GetPosition and SetPosition should be reworked into a single read/write properties. The side effect of property write can be modified inside class to achieve desired effect (such as invalidation of a part of the scene or whatever technique you use). The code using these objects should be made agnostic to these detail.

I'm telling you, even though you do not really show your problem in code: it is solely in data inconsistency (if I can trust your description). If you remove your mess in favor of single-point access to data, you will see that many similar problems will be avoided automatically.

Sorry if your problem is not still resolved. You should understand that your code sample does not show enough to dig out the problem completely and you should not down-vote the answer based on lack of your progress.
 
Share this answer
 
v4
Comments
Elliot Harrison 10-Jan-11 6:32am    
Ok, I wouldn't of down voted the answer anyway, I know the problem is with my question. Thank you.
Sergey Alexandrovich Kryukov 10-Jan-11 19:09pm    
Thanks, Elliot. You can think on what I suggest, come closer to the problem if you still have one and ask another question(s).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900