Building the Roids Program Example


As with every new improvement to the game engine, new concepts only fully make sense when you see them in action. The remainder of the hour shows you how to put the new background classes to use in a program example called Roids. The Roids program example simulates an asteroid field by displaying several animated asteroid sprites over an animated starry background. Not surprisingly, the StarryBackground class is used as the basis for the background in the Roids program.

Writing the Program Code

The Roids program begins with the Roids.h header file, which declares global variables that are important to the program. Take a look at Listing 18.7 to see these variables .

Listing 18.7 The Roids.h Header File Imports Several Header Files and Declares Global Variables Required for the Background and Asteroid Sprites
 1: #pragma once  2:  3: //-----------------------------------------------------------------  4: // Include Files  5: //-----------------------------------------------------------------  6: #include <windows.h>  7: #include "Resource.h"  8: #include "GameEngine.h"  9: #include "Bitmap.h" 10: #include "Sprite.h" 11: #include "Background.h" 12: 13: //----------------------------------------------------------------- 14: // Global Variables 15: //----------------------------------------------------------------- 16: HINSTANCE         _hInstance; 17: GameEngine*       _pGame; 18: HDC               _hOffscreenDC; 19: HBITMAP           _hOffscreenBitmap; 20: Bitmap*           _pAsteroidBitmap; 21: StarryBackground* _pBackground; 

The first variable unique to the Roids program is _pAsteroidBitmap (line 20), which is a bitmap for an asteroid image. This image is actually a series of frame images for an asteroid that appears to be tumbling when it is animated. A total of 14 frames are in the asteroid image, as you find out in a moment when you create the asteroid sprites. The other important global variable in the Roids program is the _pBackground variable, which stores a pointer to a StarryBackground object (line 21). This object serves as the background for the program, as you soon find out.

The GameStart() function is where the Roids program really gets rolling because it is responsible for creating bitmaps and sprites, not to mention the starry background. Listing 18.8 shows the code for this function.

Listing 18.8 The GameStart() Function Creates and Loads the Asteroid Bitmap, the Starry Background, and the Asteroid Sprites
 1: void GameStart(HWND hWindow)  2: {  3:   // Seed the random number generator  4:   srand(GetTickCount());  5:  6:   // Create the offscreen device context and bitmap  7:   _hOffscreenDC = CreateCompatibleDC(GetDC(hWindow));  8:   _hOffscreenBitmap = CreateCompatibleBitmap(GetDC(hWindow),  9:     _pGame->GetWidth(), _pGame->GetHeight()); 10:   SelectObject(_hOffscreenDC, _hOffscreenBitmap); 11: 12:   // Create and load the asteroid bitmap 13:   HDC hDC = GetDC(hWindow); 14:   _pAsteroidBitmap = new Bitmap(hDC, IDB_ASTEROID, _hInstance); 15: 16:   // Create the starry background 17:   _pBackground = new StarryBackground(500, 400); 18: 19:   // Create the asteroid sprites 20:   RECT    rcBounds = { 0, 0, 500, 400 }; 21:   Sprite* pSprite; 22:   pSprite = new Sprite(_pAsteroidBitmap, rcBounds, BA_WRAP); 23:   pSprite->SetNumFrames(14); 24:   pSprite->SetFrameDelay(1); 25:   pSprite->SetPosition(250, 200); 26:   pSprite->SetVelocity(-3, 1); 27:   _pGame->AddSprite(pSprite); 28:   pSprite = new Sprite(_pAsteroidBitmap, rcBounds, BA_WRAP); 29:   pSprite->SetNumFrames(14); 30:   pSprite->SetFrameDelay(2); 31:   pSprite->SetPosition(250, 200); 32:   pSprite->SetVelocity(3, -2); 33:   _pGame->AddSprite(pSprite); 34:   pSprite = new Sprite(_pAsteroidBitmap, rcBounds, BA_WRAP); 35:   pSprite->SetNumFrames(14); 36:   pSprite->SetFrameDelay(3); 37:   pSprite->SetPosition(250, 200); 38:   pSprite->SetVelocity(-2, -4); 39:   _pGame->AddSprite(pSprite); 40: } 

The first few sections of code in the GameStart() function should be familiar to you from other program examples, so I'll spare you a recap. Instead, let's jump straight to the line of code that creates the StarryBackground object (line 17). As you can see, the starry background is set to a size of 500 by 400, which is the same size of the game screen. Because no other arguments are provided to the new object, the default values of 100 for the number of stars and 50 for the twinkle delay are assumed.

The remainder of the GameStart() function focuses on the creation of the asteroid sprites. Notice that the number of frames for each of these sprites is set to 14 (lines 23, 39, and 35), which indicates that 14 frame images are stored in the image for the asteroid. Also, the frame delay of each sprite is set differently so that the asteroids appear to tumble at different speeds (lines 24, 30, and 36). Beyond those settings, nothing is tricky or otherwise noteworthy regarding the asteroid sprites.

The GamePaint() function is responsible for drawing the graphics in the Roids program, as shown in Listing 18.9.

Listing 18.9 The GamePaint() Function Draws the Starry Background and the Asteroid Sprites
 1: void GamePaint(HDC hDC)  2: {  3:   // Draw the background  4:   _pBackground->Draw(hDC);  5:  6:   // Draw the sprites  7:   _pGame->DrawSprites(hDC);  8: } 

The important line of code worth paying attention to here is the line that calls the Draw() method on the StarryBackground object (line 4). As long as the background is drawn before the sprites, everything works great.

The final function on the Roids agenda is GameCycle() , which takes care of updating the animated graphics in the program. Because the background is animated, it too must be updated in GameCycle() function, as shown in Listing 18.10.

Listing 18.10 The GameCycle() Function Updates the Starry Background and Asteroid Sprites, and then Repaints the Game Screen
 1: void GameCycle()  2: {  3:   // Update the background  4:   _pBackground->Update();  5:  6:   // Update the sprites  7:   _pGame->UpdateSprites();  8:  9:   // Obtain a device context for repainting the game 10:   HWND  hWindow = _pGame->GetWindow(); 11:   HDC   hDC = GetDC(hWindow); 12: 13:   // Paint the game to the offscreen device context 14:   GamePaint(_hOffscreenDC); 15: 16:   // Blit the offscreen bitmap to the game screen 17:   BitBlt(hDC, 0, 0, _pGame->GetWidth(), _pGame->GetHeight(), 18:     _hOffscreenDC, 0, 0, SRCCOPY); 19: 20:   // Cleanup 21:   ReleaseDC(hWindow, hDC); 22: } 

The background is the first thing updated in the GameCycle() function (line 4), and this simply involves a call to the Update() method on the StarryBackground class. This call is sufficient enough to cause the entire background to come alive with twinkling stars. If you don't believe me, try commenting out this line of code and see what happens to the background ”no animation, and therefore not much excitement!

Testing the Finished Product

Granted, the Roids program example isn't quite up to par with the classic Asteroids game. In fact, Roids isn't a game at all. The reason for this is because I wanted to focus on the specific task of using an animated background without the distraction of trying to assemble a complete game. If you're dying to build another complete game, your wishes will be answered in the next hour. But for now, take a look at Figure 18.2 to see the Roids program in action.

Figure 18.2. The asteroid sprites in the Roids program tumble over an animated starry background thanks to the new background classes in the game engine.

graphics/18fig02.gif

In addition to noticing how effective the twinkling stars are at presenting an interesting space background, hopefully you're now appreciating the power of animated sprites. This has to do with the fact that the animated asteroids in the Roids program are considerably smoother and more detailed than the animated guys in the Battle Office 2 game where you first learned about animated sprites. It's starting to become clear that you can get some surprisingly powerful visual effects out of the game engine when you combine an animated background with high quality sprite graphics.



Sams Teach Yourself Game Programming in 24 Hours
Sams Teach Yourself Game Programming in 24 Hours
ISBN: 067232461X
EAN: 2147483647
Year: 2002
Pages: 271

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net