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:
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 CodeIf 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 Events1: 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 ResourcesBecause 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 Sounds1: //----------------------------------------------------------------- 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 Resources1: //----------------------------------------------------------------- 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.
Testing the Finished ProductYou 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.
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! |