Building the Brainiac 2 Program Example


You now have enough wave playing skills to see how waves are played in the context of a real game. In fact, instead of embarking on an entirely new game project, it makes sense to revisit a game you've already created and examine how to spiff it up with wave sounds. I'm referring to the Brainiac game from Hour 8, which is a simple tile matching memory game if you recall.

The Brainiac game isn't necessarily suffering from a lack of sound support, but it could definitely be made more interesting with some carefully injected waves. Think about how the game plays and how playing a wave sound here and there might improve its playability. After playing the game a few times and thinking about what would make it more fun, I came up with the following list of game events that could benefit from having sound effects associated with them:

  • Selecting a tile

  • Matching a pair of tiles

  • Mismatching a pair of tiles

  • Winning the game by matching all the tiles

If you play the game again and pay attention to each of these game events, you can start to see how a brief sound could add some interest to the game and make it a little more fun. The next few sections explore how to create a new version of the Brainiac game called Brainiac 2 that plays wave sounds in response to each of these game events.

Writing the Program Code

If you recall, the bulk of the code for the game logic in the Brainiac game resides in the MouseButtonDown() function. This function is called whenever the player clicks the mouse on the game screen, and is therefore where all of the tile matching takes place. Not surprisingly, this function is where you'll find all the game events for the Brainiac game, such as tile selections, matches, and mismatches . Listing 14.1 shows the new MouseButtonDown() function, which includes several calls to the PlaySound() function to play sounds responding to game events.

Listing 14.1 The MouseButtonDown() Function Plays Wave Sounds in Response to Several Important Game Events
 1: void MouseButtonDown(int x, int y, BOOL bLeft)  2: {  3:   // Determine which tile was clicked  4:   int iTileX = x / _pTiles[0]->GetWidth();  5:   int iTileY = y / _pTiles[0]->GetHeight();  6:  7:   // Make sure the tile hasn't already been matched  8:   if (!_bTileStates[iTileX][iTileY])  9:   { 10:     // See if this is the first tile selected 11:     if (_ptTile1.x == -1) 12:     { 13:       // Play a sound for the tile selection 14:       PlaySound((LPCSTR)IDW_SELECT, _hInstance, SND_ASYNC  SND_RESOURCE); 15: 16:       // Set the first tile selection 17:       _ptTile1.x = iTileX; 18:       _ptTile1.y = iTileY; 19:     } 20:     else if ((iTileX != _ptTile1.x)  (iTileY != _ptTile1.y)) 21:     { 22:       if (_ptTile2.x == -1) 23:       { 24:         // Play a sound for the tile selection 25:         PlaySound((LPCSTR)IDW_SELECT, _hInstance, SND_ASYNC  26:           SND_RESOURCE); 27: 28:         // Increase the number of tries 29:         _iTries++; 30: 31:         // Set the second tile selection 32:         _ptTile2.x = iTileX; 33:         _ptTile2.y = iTileY; 34: 35:         // See if it's a match 36:         if (_iTiles[_ptTile1.x][_ptTile1.y] == 37:           _iTiles[_ptTile2.x][_ptTile2.y]) 38:         { 39:           // Play a sound for the tile match 40:           PlaySound((LPCSTR)IDW_MATCH, _hInstance, SND_ASYNC  41:             SND_RESOURCE); 42: 43:           // Set the tile state to indicate the match 44:           _bTileStates[_ptTile1.x][_ptTile1.y] = TRUE; 45:           _bTileStates[_ptTile2.x][_ptTile2.y] = TRUE; 46: 47:           // Clear the tile selections 48:           _ptTile1.x = _ptTile1.y = _ptTile2.x = _ptTile2.y = -1; 49: 50:           // Update the match count and check for winner 51:           if (++_iMatches == 8) 52:           { 53:             // Play a victory sound 54:             PlaySound((LPCSTR)IDW_WIN, _hInstance, SND_ASYNC  55:               SND_RESOURCE); 56:             TCHAR szText[64]; 57:             wsprintf(szText, "You won in %d tries.", _iTries); 58:             MessageBox(_pGame->GetWindow(), szText, TEXT("Brainiac"), 59:               MB_OK); 60:           } 61:         } 62:         else 63:           // Play a sound for the tile mismatch 64:           PlaySound((LPCSTR)IDW_MISMATCH, _hInstance, SND_ASYNC  65:             SND_RESOURCE); 66:       } 67:       else 68:       { 69:         // Clear the tile selections 70:         _ptTile1.x = _ptTile1.y = _ptTile2.x = _ptTile2.y = -1; 71:       } 72:     } 73: 74:     // Force a repaint to update the tile 75:     InvalidateRect(_pGame->GetWindow(), NULL, FALSE); 76:   } 77: } 

The first two calls to the PlaySound() function occur in response to tile selections (lines 14, 25, and 26). If you recall, two tiles must be selected in each turn of the game, so the IDW_SELECT sound is played in response to each of the two tile selections. The IDW_MATCH sound is played whenever a pair of tiles is successfully matched (lines 40 “41). Similarly, the IDW_MISMATCH sound is played whenever two mismatched tiles are selected (lines 64 “65). Finally, the IDW_WIN wave is played whenever all the tiles have been matched (lines 54 “55).

Assembling the Resources

Because waves are resources similar to bitmaps and icons, you must declare resource IDs for them, as well as include them in the resource script for your games . In the case of the Brainiac 2 game, the wave resource IDs are declared in the Resource.h header file, which is shown in Listing 14.2.

Listing 14.2 The Resource.h Header File Defines New Resource IDs for the Wave Sounds
 1: //-----------------------------------------------------------------  2: // Icons                    Range : 1000 - 1999  3: //-----------------------------------------------------------------  4: #define IDI_BRAINIAC        1000  5: #define IDI_BRAINIAC_SM     1001  6:  7: //-----------------------------------------------------------------  8: // Bitmaps                  Range : 2000 - 2999  9: //----------------------------------------------------------------- 10: #define IDB_TILEBLANK       2000 11: #define IDB_TILE1           2001 12: #define IDB_TILE2           2002 13: #define IDB_TILE3           2003 14: #define IDB_TILE4           2004 15: #define IDB_TILE5           2005 16: #define IDB_TILE6           2006 17: #define IDB_TILE7           2007 18: #define IDB_TILE8           2008 19: 20: //----------------------------------------------------------------- 21: // Wave Sounds              Range : 3000 - 3999 22: //----------------------------------------------------------------- 23: #define IDW_SELECT          3000 24: #define IDW_MATCH           3001 25: #define IDW_MISMATCH        3002 26: #define IDW_WIN             3003 

The four wave resource IDs are declared in the Resource.h header file (lines 23 “26), which means that you can now place them in the Brainiac.rc resource script. This script is shown in Listing 14.3.

Listing 14.3 The Brainiac.rc Resource Script Includes Four New Wave Resources
 1: //-----------------------------------------------------------------  2: // Include Files  3: //-----------------------------------------------------------------  4: #include "Resource.h"  5:  6: //-----------------------------------------------------------------  7: // Icons  8: //-----------------------------------------------------------------  9: IDI_BRAINIAC       ICON         "Brainiac.ico" 10: IDI_BRAINIAC_SM    ICON         "Brainiac_sm.ico" 11: 12: //----------------------------------------------------------------- 13: // Bitmaps 14: //----------------------------------------------------------------- 15: IDB_TILEBLANK      BITMAP       "TileBlank.bmp" 16: IDB_TILE1          BITMAP       "Tile1.bmp" 17: IDB_TILE2          BITMAP       "Tile2.bmp" 18: IDB_TILE3          BITMAP       "Tile3.bmp" 19: IDB_TILE4          BITMAP       "Tile4.bmp" 20: IDB_TILE5          BITMAP       "Tile5.bmp" 21: IDB_TILE6          BITMAP       "Tile6.bmp" 22: IDB_TILE7          BITMAP       "Tile7.bmp" 23: IDB_TILE8          BITMAP       "Tile8.bmp" 24: 25: //----------------------------------------------------------------- 26: // Wave Sounds 27: //----------------------------------------------------------------- 28: IDW_SELECT         WAVE         "Select.wav" 29: IDW_MATCH          WAVE         "Match.wav" 30: IDW_MISMATCH       WAVE         "Mismatch.wav" 31: IDW_WIN            WAVE         "Win.wav" 

The resource script for the Brainiac 2 game is very similar to the original Brainiac resource script, except that it now includes wave resources (lines 28 “31). Notice that the resource type WAVE is used when listing each of the wave resources in the script. This script successfully maps the wave sounds to resource identifiers that can then be used with the PlaySound() function, as you saw in the previous section.

graphics/book.gif

If you happen to get a "multiple initialization" compiler error while compiling the Brainiac 2 program, you can easily fix it by removing the int variable declaration in the second for loop of the GameStart() function. This error stems from the fact that some compilers don't fully support the standard C++ approach of declaring loop initializer variables local to the loop. So, the int variable i is mistakenly interpreted as being declared twice.


Testing the Finished Product

You already have a pretty good idea how to play the Brainiac game, so testing out the new wave sounds is very straightforward. Just take the game for a spin and pay attention to how sounds are played in response to different game events such as selecting and matching tiles. Figure 14.1 shows the game in action.

Figure 14.1. The Brainiac 2 game is made more interesting than its predecessor by playing wave sounds in response to game events.

graphics/14fig01.gif

Believe it or not, a sound is being played in this figure. Because I couldn't convince the publisher to include an audio tape with the book, you'll just have to imagine the sound as you look at the figure. Or just fire up the game yourself and experience the sounds on your own!



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