Click here to Skip to main content
15,867,835 members
Articles / Programming Languages / C#

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

Rate me:
Please Sign up or sign in to vote.
3.22/5 (3 votes)
16 Apr 20023 min read 64.1K   816   34   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:

C#
++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:

C#
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:

C#
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.


Written By
Software Developer (Senior)
Australia Australia
Programming computers ( self taught ) since about 1984 when I bought my first Apple ][. Was working on a GUI library to interface Win32 to Python, and writing graphics filters in my spare time, and then building n-tiered apps using asp, atl and asp.net in my job at Dytech. After 4 years there, I've started working from home, at first for Code Project and now for a vet telemedicine company. I owned part of a company that sells client education software in the vet market, but we sold that and I worked for the owners for five years before leaving to get away from the travel, and spend more time with my family. I now work for a company here in Hobart, doing all sorts of Microsoft based stuff in C++ and C#, with a lot of T-SQL in the mix.

Comments and Discussions

 
GeneralMy vote of 5 Pin
ne0hisda0ne10-Jul-13 11:09
ne0hisda0ne10-Jul-13 11:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.