How to create Sound Effects for video games

how to make game sound effects and how to add sound in android games how to add sound in gamesalad how to add sound in game maker studio how to add sound to games
Dr.MohitBansal Profile Pic
Dr.MohitBansal,Canada,Teacher
Published Date:25-10-2017
Your Website URL(Optional)
Comment
Adding Sound Effects and Music Sound effects and music are very important in modern games. I am sure you can remember some recent popular game where the "Better with headphones" sign appears on the splash screen. Many games just would not be that good without the atmosphere created with sound eects ff and music. In this chapter, we will learn how to add them to our game. We will add sound eects ff when we shoot the arrow, hit the bird, and in other places where you would expect to hear sounds in the real world. In addition to this, we are going to make our game even cooler by adding some background music. In this chapter, we will cover the following topics: ‹ Playing sound eects ff ‹ Playing music and background sounds ‹ Switching between music tracks ‹ Making use of stereo headphones ‹ Finding sound eects f ff or our game ‹ Adding sound eects and pr ff eloading themAdding Sound Eects and Music ff Creating AudioManager and playing sound effects You can play sound eects and music on iOS without using an ff y game engine in many different ways, but as I have mentioned before, one of the goals of the game engine such as Cocos2D is to make our lives easier. This is why Cocos2D uses a great library called ObjectAL that provides a nice interface to the underlying OpenAL framework. A good thing about using ObjectAL is that it provides different levels of control. For example, there is a class called OALSimpleAudio, which provides a very simple interface to play audio and requires absolutely no knowledge of how things work internally. This class is suitable for most games and provides all the required features to play background and foreground audio files. On the other hand, you can always go deeper and use some lower-level class that will be more complex, but will also give you more control. We will start with the basic OALSimpleAudio functionality and will build on top of it along the way. Time for action – adding the AudioManager class We are going to create a simple singleton class and put all the code related to the audio playback into it. Although we could play any sound eect with jus ff t a single line of code by using OALSimpleAudio, we are going to create a special class called AudioManager. This will allow us to keep the audio playback code separate from the rest of our code. This is a good idea as it allows you to tweak the playback in one place and even switch to some other audio framework without going through all the code and searching and replacing the code. It also decentralizes the access to the audio playback, which means the main screen, game screen, and cut scenes can all control audio. We will start from almost an empty class, and we will fill it with code as we complete the tasks of adding sound eects and music t ff o our game by performing the following steps: 1. Open the Cocohunt Xcode project at the point where we left it in the previous chapter. 224 Chapter 8 If you have completed the previous chapter, you can continue working with your project. Alternatively, you can take the included final project from the previous chapter and use it as a starter project. You can find the final project for the previous chapter at the Chapter_07/Chapter_07_Final folder in the book's supporting files, which can be downloaded from www.packtpub.com/support and follow the instructions. 2. Right-click on the Common group and create a new Objective-C class . Call it AudioManager and make it a subclass of NSObject. 3. Open the AudioManager.h file and add the following method declarations: -(void)playSoundEffect:(NSString )soundFile; +(instancetype)sharedAudioManager; 4. Then, open the AudioManager.m file and import the OALSimpleAudio.h header file at the top as follows: import "OALSimpleAudio.h" 5. Add the following implementation of the methods we declared earlier: -(void)playSoundEffect:(NSString )soundFile OALSimpleAudio sharedInstance playEffect:soundFile; +(AudioManager )sharedAudioManager static dispatch_once_t pred; static AudioManager _sharedInstance; dispatch_once(&pred, _sharedInstance = self alloc init; ); return _sharedInstance; Don't worry about the sharedAudioManager method implementation. It is a standard and recommended way to create a singleton. We will discuss this in a moment. 6. That is it Build the game and check whether there are any errors. There is no reason to run the game right now as you will see no visual changes. However, you should always build the game and check that there are no errors before continuing. 225 Adding Sound Eects and Music ff What just happened? We have not done much yet, but we have laid out a good foundation for our future code. We have created a singleton class that we will be able to use at any point in the game and we have created a method that plays sound eects using the giv ff en sound file name. As I've mentioned in one of the previous chapters, singletons are quite useful if you want to have a globally accessible decentralized instance. In our case, we want to be able to control audio playback from any scene in our game; this is why we need this global object. The sharedAudioManager method simply creates the only singleton instance when you first access this method. This is why we used the dispatch_once_t predicate. You can find out more about using Grand Central Dispatch (GCD) from Apple's documentation at https://developer.apple.com/ library/mac/documentation/performance/reference/ gcd_libdispatch_ref/Reference/reference.html (short link: http://bit.ly/1hISyQ0). Don't worry about this singleton-related code. The only thing you need to understand that a singleton will be globally accessible and as there will be only one instance, we can use instance variables to store the data shared between all scenes of the game. Although you will do completely fine if you simply remember how to create a singleton and when to use it, learning at least a bit more about singletons as well as about other design paerns c tt an be quite useful. Now, back to the audio playback-related code. The following is the declaration of the method that is used to play sound eects in the ff OALSimpleAudio.h file: - (idALSoundSource) playEffect:(NSString) filePath It takes the audio file path and returns the strange idALSoundSource value as a return value. You can think of this return value as a currently played sound identifier or a reference to the sound that you have just played. This value can be used to identify the sound, for example, if you want to stop the looped playback. You might notice that there are not many options in the playEffect: method shown earlier. This is because this simple method just calls the more general playEffect: method that has more parameters as shown in the following code: - (idALSoundSource) playEffect:(NSString) filePath volume:(float) volume pitch:(float) pitch pan:(float) pan loop:(bool) loop; 226 Chapter 8 In the preceding code, you see you can set the sound eect t ff o loop and change other options. The following is some brief information about each parameter: ‹ filePath: This is the path to the audio file to play. ‹ volume: This is the level of the volume to play at, where 0 means no sound and 1.0 is the original volume. ‹ pitch: This is the pitch to play at, where 1.0 is the original sound. Passing a higher pitch value makes the sound play at a higher note. Passing a lower pitch will make the eect sound lo ff wer. ‹ pan: This is the pan that aects s ff tereo playback. Passing -1.0 will play the sound at the far left (almost no sound in the right headphone), while passing +1.0 will play the sound at the far right. ‹ loop: If set to YES, this sound eect will be looped. ff Of course, it is hard to understand all these parameters without examples. We will see how to use them later in this chapter, but first we need to find some sound eects and add them ff to our game. Time for action – finding and playing our first sound effect Now that we have the basic code to play sound eects r ff eady, I am sure you are eager to try it. We are going to find some sound eects, add them t ff o the game, and even play one. There are many places on the Web where you can find some free sound eects ff for your game. You can find a bigger list of websites with free sound eects and ff music at the end of the book in Chapter 12, Standing Out– Integrating Game Center and In-App Purchases. This final chapter can be downloaded for free from the Packt website at www.packtpub.com/support, as it does not fit in the print book. You can choose any sound eects y ff ou like. The only thing you need to take into account is the supported audio formats. You can find detailed information about iOS supported formats at https:// developer.apple.com/library/ios/documentation/ AudioVideo/Conceptual/MultimediaPG/UsingAudio/ UsingAudio.html (short link: http://bit.ly/RLfmsx). 227 Adding Sound Eects and Music ff Most of the files on the Web are in the .wav or .mp3 formats and should work just fine. Perform the following steps: 1. Let's download some sound eects fr ff om the Web. Open the http://freesound. org/ website and search for the sound eects tha ff t we should play in the following situations: ‰ When the hunter shots the arrow from the bow ‰ When the arrow hits the bird ‰ When you win the game ‰ When you lose the game This is not important for this sample case, but if you are making a real project, note the license of the each audio file you download. For example, you cannot use an audio file licensed under the noncommercial license in the game you are going to sell. 2. When you find several candidates for each sound eect, sa ff ve them somewhere on the disk and name the files corresponding to the situation (for example, arrow_shot.wav). If you cannot find the good sound effects or don't want to spend time searching right now, you can use the files I've prepared for you. To do this, open the book's supporting files folder available at Chapter_08/Assets/SoundEffects, and here, you will find four files: arrow_shot.wav, bird_hit.mp3, lose.wav, and win.wav. 3. Create a new group in the Resources group and call it Sound. Add all the four audio files that you have found or have taken from the book's supporting files to this group. It is very important to check that the Add to targets list has Cocohunt checked, as Xcode can unselect this checkbox for some audio formats that are supported, but have less common extensions, and will not include this sound file in the app bundle. Make sure you have settings as shown on the following screenshot: 228 Chapter 8 4. Now it is time to play some sound eects. W ff e will start with the sound of shooting the arrow. Open the Hunter.m file and import the AudioManager.h header at the top as follows: import "AudioManager.h" 5. Then, find the shootAtPoint: method and add the following code at the beginning of the method: -(CCSprite)shootAtPoint:(CGPoint)point AudioManager sharedAudioManager playSoundEffect:"arrow_shot.wav"; //..skipped.. Note that my audio file is named arrow_shot.wav; if you have not used the files that come with the book, then you have to specify the name of your file. 6. Build and run the game. You should hear a sound every time the hunter shoots an arrow. What just happened? We have just played the first sound eect in our g ff ame. I hope you are happy with the sound eect tha ff t you have chosen or with the file I selected if you used the file from the book's supporting files. The player will hear this sound very often, so you have to make sure it is not annoying. If the sound is not playing, check whether you have mistyped the file name and selected the Add to targets checkbox when adding the file. You can check whether the file is included in the app bundle by going to the project properties, selecting the Cocohunt target from the TARGETS list on the left of the screen, then switching to the Build Phases tab and checking whether your sound file is present in the Copy Bundle Resources list, as shown in the following screenshot: 229 Adding Sound Eects and Music ff If you have spent time searching for sound ee ff cts, you must have realized that it takes a lot of time to find a good sound, while playing it using our AudioManager and OALSimpleAudio methods is less time consuming. Let's play the rest of the sound eects. ff Time for action – playing the remaining sound effects We have added all the sound eects files t ff o our project previously, so what we are going to do now is just add some code to play them. We need to add the code in three places: when the arrow hits the bird, when we lose, and when we win the game. Let's start making changes by performing the following steps: 1. Open the Bird.m file and import the AudioManager.h header file at the top as follows: import "AudioManager.h" 2. Next, find the removeBird: method and add the corresponding sound eect tha ff t will be played when the bird is hit by an arrow: -(int)removeBird:(BOOL)hitByArrow //..skipped if (hitByArrow) //..skipped.. AudioManager sharedAudioManager playSoundEffect:"bird_hit.mp3"; //..skipped.. Note that I have used the file named bird_hit.mp3 (which is in the .mp3 file format); if your file is named differently, then you have to adjust that line of code. 3. The final file we need to change is the GameScene.m file. Open it and import the AudioManager.h header file at the top using the following line of code: import "AudioManager.h" 230 Chapter 8 4. Then, scroll down and find the lost and won methods. Add the code to play the corresponding sound at the beginning of each method as follows: -(void)lost AudioManager sharedAudioManager playSoundEffect:"lose.wav"; self.gameState = GameStateLost; self displayWinLoseLabelWithText:"You lose" andFont:"lost.fnt"; -(void)won AudioManager sharedAudioManager playSoundEffect:"win.wav"; self.gameState = GameStateWon; self displayWinLoseLabelWithText:"You win" andFont:"win.fnt"; Don't forget to change the audio file names if you aren't using the files that come with the book. 5. That's it Build and run the game and enjoy the sounds. Win and lose the game to make sure that the corresponding sound is played. You can find snapshot of the project at this stage in the Chapter_08/Cocohunt_08_Sound_Effects folder. What just happened? We have added the code to play three remaining sound eects tha ff t we added earlier. The code itself should be very simple, so I am not going to cover it. The other thing that just happened is that you have probably just used several files under some license. In my case, it was the Creative Commons Attribute license, so I must give the credit to the people who created these sound eects. ff 231 Adding Sound Eects and Music ff I say probably because if you did not use the files that came with the book, you might have used sound files under the Creative Commons Public Domain license and don't have to attribute anyone, but I think it is always a good idea to attribute a person who helped you to make your game. Later, we are going to add an About scene to the game, and normally, I put the credits there, but as I'm writing a book, I'll put some credits right in the text. This book and the sample game use the following sounds from Freesound: arrow_shot.wav by EverHeat at http://freesound.org/people/ EverHeat/sounds/205563/ bird_hit.mp3 by haydensayshi123 http://freesound.org/people/ haydensayshi123/sounds/138678/ lose.wav by Benboncan http://freesound.org/people/ Benboncan/sounds/73581/ win.wav by bone666138 http://freesound.org/people/ bone666138/sounds/198874/ Thank you Have a go hero There is no limit to perfection. This is totally about picking the sound for the game. The following are some thoughts about how you can improve your skills and the game: ‹ If you have not searched for the sound and just used the files that came with the book, I strongly encourage you to do a search and maybe change some files. When you spend some time searching, you will learn to estimate the time required to find the corresponding sound eects. ff ‹ If you have searched but are still unhappy with any sound, try to find a beer one. tt Searching for the exact sound eect (f ff or example, the bird hit by an arrow) does not always work. For example, I've used a melon squash sound for a zombie head explosion eect in one of m ff y games, so you have to think what sound can be close to what you want. ‹ You can add a sound of a falling bird, a sound when you lose one life or a sound when a new bird is spawned. Just don't add a sound that plays for a long duration or the game will end up as a cacophony. 232 Chapter 8 Music and background sounds I hope you agree that the game is so much beer no tt w that it has sounds. Let's add some background sounds and music to make it even beer tt . Time for action – adding background sounds First, we are going to add some background sounds because it is too quiet in our tropical forest. We are going to generate some sound and then use it in the game by performing the following steps: 1. We are going to use an online sound generator website. Visit the http:// naturesoundsfor.me and create a new sound. I've set this up by adding Fire by navigating to Nature Fire, Forest Ambient by navigating to Nature Forest Ambient (both at 20 percent volume), and Grasshopper by navigating to Other Animals Grasshopper at 10 percent volume, but set the grasshopper track to play intermittently (there is a dropdown for that at the bottom). Refer to the following screenshot: My nature sound settings 2. Then, click on the Export to File button in the bottom-right corner and select the length of 1 minute. After processing the file, it will allow you to save the file in the .ogg format. 233 Adding Sound Eects and Music ff 3. The bad news is that the .ogg format is not supported. So, we need to convert it. You can use your favorite audio converter to convert the file to .mp3. I have used the media.io online converter, which is available at http://media. io. Alternatively, you can just grab the naturesounds.mp3 file from the Chapter_08/Assets/BackgroundSound folder. If you converted the file yourself, call the resulting file naturesounds.mp3. 4. Add the naturesounds.mp3 file to the Sound group next to the other sound eects. ff 5. Switch to AudioManager.h and add the following method declaration above the sharedAudioManager class method: -(void)playBackgroundSound:(NSString )soundFile; 6. Then, open the AudioManager.m file and add the implementation of this method as follows: -(void)playBackgroundSound:(NSString )soundFile OALSimpleAudio sharedInstance playBg:soundFile loop:YES; 7. Finally, open the GameScene.m file and add a call to this method in the end of the onEnter method as follows: -(void)onEnter //..skipped.. AudioManager sharedAudioManager playBackgroundSound:"naturesounds.mp3"; 8. This step is optional. If you have not done this already, go to the GameScene.m file, and in the init method, change the number of the birds to spawn and the number of lives to be somewhere near the following values. This will allow you to hear more of the background sound without losing or winning the game: _birdsToSpawn = 30; _birdsToLose = 5; 9. Build and run the game. It should now feel much more like a campfire in a forest. You can find snapshot of the project at this point in the Chapter_08/Cocohunt_08_Ambient folder. 234 Chapter 8 What just happened? You have to be prepared that if you're a one-man studio and are creating games yourself, you will have to learn about different sound file formats and how to convert them from the initial format to the required format. In the first part, we used one of the many online tools that allow you to generate the sounds and convert them. There are many helpful websites, so try searching one every time you need something. Back to the code; let's review the code we have used to play the background sound as follows: OALSimpleAudio sharedInstance playBg:soundFile loop:YES; You might have noticed that we've used the playBg: method instead of the playEffect: method. The playBg: method is intended for playing background audio files more efficiently, but this comes at a price that you can only play one background track at a time. The iPhone supports only one audio track using hardware acceleration, while all other audio tracks are played on CPU. So, the practice is to play the background song in MP3 (heavily compressed audio) and sound eects (which ar ff e smaller and less frequently used) in a lightly compressed format (for example, CAF) in CPU. You can use the afconvert tool in OS X to convert your audio files. Just as with playEffect:, we have used a simplified method with only two parameters, as we only wanted to loop it. All the playBg: methods in the end just call the following method using the default parameters: -(bool) playBg:(NSString) filePath volume:(float) volume pan:(float) pan loop:(bool) loop So, if you need more control, you can use this method. 235 Adding Sound Eects and Music ff Time for action – adding music Background ambient sound is good, but not for our kind of game. What we really need is some music. Let's add the code to play the music, and as we don't want one song playing over and over again, we're going to implement switching between the tracks by performing the following steps: 1. First of all, we will need some music. Create the group called Music in the Resources group. Then, open the book's supporting files available at Chapter_08/Assets/Music and add all the music files into this group. You can use your favorite music instead of the music that comes with the book, just name the files the same way or make sure you adjust the code. Also, don't forget about the licenses if you're going to upload the game into the App Store. 2. Open the AudioManager.h file and import a module using the following import directive: import AVFoundation.AVAudioPlayer; Note that we're using import and not import, as we are importing a module. 3. Then, make the AudioManager class conform to the AVAudioPlayerDelegate protocol by changing its declaration line as follows: interface AudioManager : NSObjectAVAudioPlayerDelegate 4. The last change in the AudioManager.h file is to add the following two method declarations: -(void)playMusic; -(void)stopMusic; 5. Now, switch to the AudioManager.m file and add the following instance variables: implementation AudioManager NSArray _musicFiles; OALAudioTrack _currentTrack; OALAudioTrack _nextTrack; 236 Chapter 8 6. Then, add the init method as shown in the following code: -(instancetype)init if (self = super init) _musicFiles = "track_0.mp3", "track_1.mp3", "track_2.mp3", "track_3.mp3", "track_4.mp3", "track_5.mp3"; _currentTrack = nil; _nextTrack = nil; return self; 7. Add the playMusic method implementation below the init method as follows: -(void)playMusic //1 if (_currentTrack) NSLog("The music is already playing"); return; //2 int startTrackIndex = arc4random() % _musicFiles.count; int nextTrackIndex = arc4random() % _musicFiles.count; NSString startTrack = _musicFiles objectAtIndex:startTrackIndex; NSString nextTrack = _musicFiles objectAtIndex:nextTrackIndex; //3 _currentTrack = OALAudioTrack track; _currentTrack.delegate = self; _currentTrack preloadFile:startTrack; _currentTrack play; //4 _nextTrack = OALAudioTrack track; _nextTrack preloadFile:nextTrack; 237 Adding Sound Eects and Music ff 8. Then, aer the ft playMusic method, add the nextTrack method as follows: -(void)nextTrack //1 if (_currentTrack) return; //2 _currentTrack = _nextTrack; _currentTrack.delegate = self; _currentTrack play; //3 int nextTrackIndex = arc4random() % _musicFiles.count; NSString nextTrack = _musicFiles objectAtIndex:nextTrackIndex; _nextTrack = OALAudioTrack track; _nextTrack preloadFile:nextTrack; 9. Now, add the following audioPlayerDidFinishPlaying: method, which is a part of the AVAudioPlayerDelegate protocol: - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer )player successfully:(BOOL)flag dispatch_async(dispatch_get_main_queue(), self nextTrack; ); 10. Then, add the last method (for now), the stopMusic method, in the AudioManager.m file, as shown in the following code: -(void)stopMusic if (_currentTrack) NSLog("The music is already stopped"); return; _currentTrack stop; _currentTrack = nil; _nextTrack = nil; 238 Chapter 8 11. It is time to play the music. Open the GameScene.m file and replace the following line in the onEnter method: AudioManager sharedAudioManager playBackgroundSound:"naturesounds.mp3"; 12. Replace the preceding line of code with the following: AudioManager sharedAudioManager playMusic; 13. Don't forget that we also need to stop the music when the game stops. Find the lost and won methods and add the following line at the beginning of each method: -(void)lost AudioManager sharedAudioManager stopMusic; //..skipped.. -(void)won AudioManager sharedAudioManager stopMusic; //..skipped.. 14. Build and run the game. Now, instead of the ambient background sound, you should hear some music I hope you like my pick or have managed to change the music to your favorite tracks and are now enjoying them. All sound tracks are taken from the http://www. nosoapradio.us website. This site has old-school music that you can use in your games. Thanks DST (also known as Night Driver) Make sure that you play the game long enough to hear the change of the music tracks. You can either again change the _birdsToSpawn and _birdsToLose settings in the init method or just find some shorter audio tracks. 239 Adding Sound Eects and Music ff What just happened? That was quite a lot of code to play some music Let's start with a bird's eye view on what we've done and why we had to write all this code instead of using the good old playBg: method. The issue with using the playBg: method is that it can play or preload only one file at a time. This means that if you are playing one music track and then trying to play or even preload the next one, the first music track stops. We don't want that This is only true for the background tracks and the playBg: method, you can still play several (up to 32) sound eects simult ff aneously using the playEffect: method. This is why there are no issues when you shoot the arrow and the previous arrow hits the bird at the same moment. Two sound eects ar ff e played at the same time without any problems. We could just wait until the first file completes and starts preloading another one, but it takes some time to preload a file and we will experience a small period of silence when one music track has already stopped and the next one has not yet started playing. Here is how we solve it. We have created two separate OALAudioTrack objects to play the _currentTrack music track and keep the preloaded _nextTrack music track ready. Then, when the _currentTrack music track has finished playing, we immediately start playing the _nextTrack track. At this point, we don't need the _currentTrack music track anymore, but need to preload the next file and store it somewhere. This is why we put the _nextTrack music track in the _currentTrack variable, as it will actually play now and load the new track in the _ nextTrack variable. Then, we keep repeating this process. Now, aer a brie ft f review, let's review each method in detail. We'll start with the following playMusic: method: 1. The first thing this method checks is whether there is any music already playing. The _currentTrack file is used as an indicator in several places. 2. After this, the two random indexes are picked. These indexes are used to pick two random music tracks. Right now, this can be the same music track (same index), and this is not very good, but I will leave it up to you to fix this. 3. This is where the current track is created. Note that there are two important things. First, we set the delegate property to self, as we want to get a notification when this file finishes playing. This is why we have made the AudioManager class conform to the AVAudioPlayerDelegate protocol, to be able to get notifications. The second important thing is that we start to play the track immediately. 240 Chapter 8 4. The next track is created. Unlike the current track, we don't set the delegate property and don't play the file just yet. Okay, now there is one music track playing and another one preloaded and ready to play. The AudioManager class does nothing from this point and waits until the audioPlayerDidFinishPlaying: method of the AVAudioPlayerDelegate protocol is called. If you are not familiar with the delegate concept of Objective-C, I suggest that you visit https://developer.apple.com/library/ios/ documentation/general/conceptual/CocoaEncyclopedia/ DelegatesandDataSources/DelegatesandDataSources.html (short link: http://bit.ly/1spzRWT). In the audioPlayerDidFinishPlaying: method, we simply call the nextTrack method, but we want to call it outside the delegate thread on the main queue, as we're going to change delegate; this is why we use dispatch_async. Now, let's review the nextTrack method, but very briefly, as it is quite easy and does almost the same as the second part of the playMusic method: 1. It checks whether there is a current track to make sure that the next track is never called when the music is stopped. 2. The next track becomes current. Note that we set delegate of this track, as we now want a notification from it. 3. A random number for the next track is generated and the actual next track is created and preloaded. This is how we change tracks until we win or lose. Then, we just stop the music and free the current and preloaded next tracks. By creating several separate OALAudioTrack objects, you can play several background tracks simultaneously. You can even do cross-fade and other mixing eects b ff y gradually decreasing volume of one track while increasing the volume of another one. 241 Adding Sound Eects and Music ff Enhancing Cocohunt sound effects Now that we know how to play sound and music, we will see how we can optimize our code and use some of the more advanced sound eect par ff ameters. Time for action – preloading sound effects Sound eects ar ff e typically much smaller than music files, and using formats such as Core Audio Format (CAF) will decrease the time used to decode the on-disk file into memory and prepare it for playing. Remember that sound eects ar ff e decoded and played on CPU, so we should avoid using too many heavily compressed formats such as MP3 for sound eects. ff This is why I mention different formats such as CAF. Such formats take more space on the disk, but are easier to decode. Of course, for a simple game like ours, we don't have to worry about this. However, if you want to make sure that there is no delay when the sound eect is pla ff yed for the first time, you need to preload it. Let's perform the following steps: 1. Open the AudioManager.h file and add the following define statements at the top, right above the interface declaration as follows: define kSoundArrowShot "arrow_shot.wav" define kSoundBirdHit "bird_hit.mp3" define kSoundWin "win.wav" define kSoundLose "lose.wav" 2. Then, add the following method declaration: -(void)preloadSoundEffects; 3. After this, switch to the AudioManager.m file and add the _soundEffects instance variable as follows: implementation AudioManager NSArray _soundEffects; //..skipped.. 4. Initialize this variable inside the init method as follows: -(instancetype)init if (self = super init) _soundEffects = kSoundArrowShot, 242

Advise: Why You Wasting Money in Costly SEO Tools, Use World's Best Free SEO Tool Ubersuggest.