1. Technology

Game Programming in C Tutorial Eight- Asteroids Part Two

A work in Progress!

By

Screenshot of Asteroids

If you've found this by accident, please start with Asteroids Game Programming Tutorial Part One.

After cleaning up the graphics and removing the odd irritating pixels in file a1.gif, I reduced the graphics size to 280 x 280 which seemed more proportionate for the screen size. Then I copied the file and halved it so I had 24 of 140 x 140 graphics and saved those out as a2.gif. I then repreated for 70 x 70 in a3.gif and finally 35 x 35 in a4.gif, and modified the code to use these three extra image files.

I've updated these files below.

  • View or download the asteroids.c (txt)
  • Download a zip file of the compiled exe, all graphics plus needed SDL dlls.

The DrawAsteroids function needed a very small change to accomodate the four sizes of graphics. I saved out the size from the asteroids struct into sizeIndex (0-3) and added that to the planes[PLASTEROID1 + sizeIndex] so all the size 0 graphics (biggest 280 x 280) came from planes[1], next size from planes[2] etc. I modded the 'T' key press code to generate a random size 0-3 and it gives a much more pleasing selection of asteroids zipping around.

Controls

  • T Key add random Asteroid to screen.
  • B Key - Blow up a random Asteroid.
  • Tab Key. Display Debug Information.
  • F Key. Toggle Frames Per Second Display in caption.
  • ESC Key. Press it twice to exit.

Blowing Up Asteroids

All are given velocities at 45 degrees to each other but relative to the movement of the original asteroid. If you destroy the 70 x 70 asteroid (size 2) you get 8 x size 3. Destroy a size 3 of course and it is just removed.

The easiest way to determine velocities is to use a 3 x 3 grid for the 8 directions 0-7 where 0 is north.

7 0 1
6 x 2
5 4 3

for each of the x and y velocities. So an asteroid moving north (dir=0) has x =0, y=-1. Moving South-west (dir=5) is x=-1, y=1 etc. This gives the two arrays.

const int xdir[8]= {0,1,1,1,0,-1,-1,-1};
const int ydir[8]= {-1,-1,0,1,1,1,0,-1};

When the asteroid splits it sets the active flag to 0 for the destroyed one and adds the eight asteroids. The eight have random velocities multipliers between one and four so an asteroid moving north west might have a velocity of -1,-1 up to -4,-4. However because the original asteroid had its own velocity, that is added to the new velocities of each one, so they carry some of the original asteroid's momentum.

Also the size of the destroyed asteroid is used as a 'radius' so the asteroids are created at that radius away from the x,y of the destroyed asteroid. It helps to prevent them colliding and blowing up.

Collisions Ahoy!

Asteroids can blow up when they collide. So for this simple example a bounding box collision is used. Our asteroids aren't rectangular though and it's entirely possible they may come close but not touch. We'll deal with that in the next tutorial. The bounding boxes are compared for overlapping and if they do, it's a collision.

The function HitAsteroid(int index) compares the bounding box for this Asteroid against all others to see if the overlap. If the two rectangles are defined by x1,y1 to x2,y2 and x3,y3 to x4,y4 then if any of the four corners of the 2nd shape fall between x1,y1 and x2,y2 then it's a hit. The easiest comparison is imagine the two bounding boxes 1 and 2. With 1 in the center there are four conditions where they don't touch.

if (x3 > x2 || y2 < y3 || x4 < x1 || y4 < y1)
continue;

To help show this, this version of Asteroids (it's not finished yet) has a file debug.gif which contains the bounding squares for all four sizes. It's just as quick blitting these as drawing lines and much simpler- just two lines of code. If you hit the tab key, it toggles debug mode and in debug mode, the bounding squares are drawn around the asteroids as they move. When they overlap both asteroids are destroyed. Presently they just vanish but it would be nice to have an animated sprite displayed for a few seconds. I'll see if I can devise one for the next tutorial.

Frame Speed

The first version ran at unlimited frame per second (around 400!), but I've added a time wasting loop which just sits and does nothing until approx 17 ms have passed. This drops the fps to about 59fps which is still fast enough for smoooth animation. It's not a great way to spend time though but it does mean that rotation speeds, asteroid movement are not affected as more asteroids are added. In the next tutorial I'll use the SDL timers to improve on this.

 while ( SDL_GetTicks()- tickcount < 17) ; // delay it to ~60 fps

To make SDL more responsive, I also added this line of code at the start:

   SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS) ;

Which tells Windows to run the game at a higher priority and makes the SDL_GetTicks() a bit more accurate.

That completes this tutorial. In the next one I'll add the player ship and bullets and improve on the collision detection.

  1. About.com
  2. Technology
  3. C / C++ / C#
  4. C Programming
  5. C Tutorials
  6. Game Programming in C Tutorial Eight - Asteroids Part Two

©2014 About.com. All rights reserved.