Time for action - positioning the asteroids

  1. Add methods to generate random locations and velocities to the AsteroidManager class:
    private Vector2 randomLocation()
    {
    Vector2 location = Vector2.Zero;
    bool locationOK = true;
    int tryCount = 0;
    do
    {
    locationOK = true;
    switch (rand.Next(0, 3))
    {
    case 0:
    location.X = -initialFrame.Width;
    location.Y = rand.Next(0, screenHeight);
    break;
    case 1:
    location.X = screenWidth;
    location.Y = rand.Next(0, screenHeight);
    break;
    case 2:
    location.X = rand.Next(0, screenWidth);
    location.Y = -initialFrame.Height;
    break;
    }
    foreach (Sprite asteroid in Asteroids)
    {
    if (asteroid.IsBoxColliding(
    new Rectangle(
    (int)location.X,
    (int)location.Y,
    initialFrame.Width,
    initialFrame.Height)))
    {
    locationOK = false;
    }
    }
    tryCount++;
    if ((tryCount > 5) && locationOK==false)
    {
    location = new Vector2(-500, -500);
    locationOK = true;
    }
    } while (locationOK == false);
    return location;
    }
    private Vector2 randomVelocity()
    {
    Vector2 velocity = new Vector2(
    rand.Next(0, 101) - 50,
    rand.Next(0, 101) - 50);
    velocity.Normalize();
    velocity *= rand.Next(minSpeed, maxSpeed);
    return velocity;
    }
    

What just happened?

When a random location is generated, we want to make sure it is not already colliding with an existing asteroid. In order to perform this check, a do...while loop surrounds the switch statement which randomly determines which side of the screen to use for the location. Here, we have chosen the left side of the screen (case 0), the right side of the screen (case 1) or the top of the screen (case 2). We have chosen not to have asteroids appear directly from the bottom of the screen, in order to give the player a little warning that they are coming, since the player ship will be near that side of the screen.

Each existing asteroid is checked to see if it would collide (using the Sprite class' IsBoxColliding() method) with a rectangle equal to the width and height of the asteroid frame placed at location. If it does collide with any asteroid, the locationOK Boolean is set to false, causing the loop to repeat. If the check has failed more than 5 times (determined by comparing against tryCount), the location is set to a distant off-screen location and the check is automatically passed in order to prevent the game getting stuck when trying to place too many asteroids in the limited off-screen area available. This is simply a safety measure. If we were to generate more than about 30 asteroids at the same time, it may become impossible for the code to place them all so that none of them are too close together. This would result in the game trying forever and locking up.

In order to generate a velocity, the randomVelocity() method creates a vector with both the X and Y components set randomly to a number between -50 and 50. That vector is then normalized, resulting in a vector that is exactly 1 unit long, but pointing in a random direction. The vector is multiplied by a random scaling factor, resulting in the final velocity which determines how far the asteroid moves in a single second of game time.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.223.123