Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Collision - A C# Game, Part 2: Tracking Game Elements and Adding Interaction

0.00/5 (No votes)
16 Apr 2002 1  
Continuing my attempt at a simple game in C#

Sample Image - Collision2.jpg

Goals

Having established that my original design was too ambitious, the idea now is to simplify the drawing process while at the same time adding some elements of gameplay - planets that are not in a repeating pattern, that grow in number as the game progresses, and a ship we can control.

Drawing the Background

I've kept the code that makes the star field different each time, but now the star field no longer scrolls. This makes life a lot easier, because now the drawing all occurs in the OnPaint method. Because we set the DoubleBuffering to be on in our startup code, we have got flicker free drawing at no cost (in terms of effort) which makes all of this much simpler.

The timer code now repositions the ship and the asteroids, and adds/removes them, but the planets and ship are drawn in the OnPaint method, direct to the screen. This is similar to how rubber banding would be achieved in GDI+ - we keep the bit that does not change and any stuff that will is drawn direct to the screen and thus is not stored, nor does it affect our background bitmap.

Adding Planets and Scoring

To add planets in a semi random manner, I use the Random class, which has a Next method which accepts a value which is the maximum returned by the random number generator. I score 10 points for every planet passed, and I increase the likelihood of a planet being added according to the score. The initial value of the counter is set to a negative to force a minimum gap between planets. The code looks like this:

++m_nAddPlanet;

Random r = new Random();

if (m_nAddPlanet > r.Next(Math.Max(300 - m_nScore, 2)))
{
    m_nAddPlanet = - 10;

    bool b = true;
    Rectangle rcDest = new Rectangle();
    while (b)
    {
        b = false;
        rcDest = new Rectangle(640, r.Next(280), 87, 87);

        for (int i = 0; i < m_arAsteroids.Count; ++i)
        {
            Asteroid arTemp = (Asteroid)m_arAsteroids[i];

            if (rcDest.IntersectsWith(arTemp.rcAsteroid))
                b = true;
        }
    }

    Asteroid arAdd;
    arAdd.rcAsteroid = rcDest;
    arAdd.nBitmap = r.Next(8);

    m_arAsteroids.Add(arAdd);
}

Tracking the Planets

The planets (which are still called Asteroids in the code because of the initial design) are defined in a struct like this:

public struct Asteroid
{
    public Rectangle rcAsteroid;
    public int       nBitmap;
}

Because it's a struct, it is passed by value. It stores the Rectangle it will be drawn into, and the index of the bitmap to draw it. I initially intended to step this to rotate an asteroid, but having gone with the planets, I have no rotating views of them. You can see in the adding code that the planets are positioned just off the screen at a random Y value. They are moved as they are drawn in the paint method, as follows:

for (int i = 0; i < m_arAsteroids.Count; ++i)
{
   Asteroid arTemp = (Asteroid)m_arAsteroids[i];

   arTemp.rcAsteroid.X -= 5;

   m_arAsteroids[i] = arTemp;

   if (arTemp.rcAsteroid.X < -87)
   {
      m_arAsteroids.RemoveAt(i);
      --i;
      m_nScore += 10;
   }

   e.Graphics.DrawImage(m_bmPlanets, arTemp.rcAsteroid, 
                          87 * arTemp.nBitmap, 0, 87, 87, 
                          GraphicsUnit.Pixel, iattrib);
}

Remember that incrementing the score adds to the speed in which planets are added, making the game increase in difficulty.

The Ship

The ship is pretty basic stuff - we create two variables to store the values in which to move the ship in the x and y direction, and set them to 1 or -1 when an arrow is pressed, and back to 0 when it is released. The code could easily be changed so that multiple presses accelerate/decelerate the ship. The ship's rect is stored, and changed by these values, then used to draw it.

What's Next ?

The code still does not use any time sync code, because it still is just OK at full speed on my 700 MHz machine. The idea is next to check for collision, which we will make work in a pixel perfect manner, while hopefully retaining a playable speed, and to use C++ and DirectX next time we decide to write an action game. The game definitely slows down as more planets are added, and it is a little better (although it looks awful) if we turn off colour keying. Some speed increase may be possible if we were to use the MakeTransparent function and revert to a (larger) bitmap resource instead of jpg.

History

  • 17th April, 2002: Initial version

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here