This lesson covers how to play sounds in XNA. It's actually pretty straightforward and can add a lot to the gameplay of your game.
This lesson begins where Lesson 12 leaves off.
Lesson 13 Completed Source Code: http://www.bluerosegames.com/brg/XnaLesson13.zip
Sound effects are so important to game development. You can do a great sprite animation for an explosion, but without the KABOOM! it loses a lot of its impact.
NOTE: For this lesson, you will need the DirectX SDK August 2006 installed on your machine. Earlier versions will give you an error when you try to run your program. You can download the August 2006 DirectX SDK here: http://www.microsoft.com/downloads/details.aspx?Fa...
XBOX 360 Homebrew has a great XNA Audio Tutorial 1 on adding sound effects to your game, and instead of duplicating it all here, I recommend you go and check it out: http://xbox360homebrew.com/blogs/audio/archive/200...
We will be using the Sound class that is laid out in that article. I'm currently using the exact same class in the game I'm developing. So step through that tutorial, and when you get to the section on adding .WAV files to your Wave Bank, add the following wav file:
http://www.flashkit.com/downloads/soundfx/wav/7730/Boing.zip
You'll have to download the wav file from that link and unzip it. Flash Kit is a great place to get free sound effects. Another great place is A1 Free Sound Effects: http://www.a1freesoundeffects.com/noflash.htm
After adding the Boing-Sith_Mas-479.wav file to the wave bank, rename it to "boing" to make things easier later. This is the name that we will need to use inside the program when playing the sound. Follow the rest of the steps in the tutorial. Make sure you save your sound project as "gameaudio.xap". Also in the Sound.cs file, replace the line:
namespace WindowsGame1
with:
namespace MyFirstGame
because the namespace for the program in their sample is different from ours, and we need to make them match. Alternatively, you could add a "using WindowsGame1;" statement to the top of our Game1.cs and BouncingBall.cs files.
When you get to the part about adding the Sound.Play() call, we'll do the following instead...
In the BouncingBall.Update() method, add this declaration to the beginning of the method:
bool bounced = false;
This declares a boolean, or true and false value, that we can use as a flag to determine whether a bounce took place. As part of the declaration, we are setting its initial value to false. It will keep that value until the end of the method unless it is changed.
So now inside the both of the two conditional "if" blocks, add the following statement:
bounced = true;
and lastly, at the end of the method, if bounced is true, meaning we hit a wall, we want to play the sound. So add the following lines:
if (bounced == true)
{
Sound.Play("boing");
}
In C#, the double equals sign in the "if" conditional statement means we are doing a comparison, not an assignment. If we used a single equals sign there, the code would think we wanted to set bounced to true instead of checking to see if it was true, and so the conditional would always be true, and the sound would always play.
Make sure you make the changes to the Game1 class that the tutorial calls for in the Game1.Initialize() method and the Game1.Update() method.
Run the program again. If all went well, you should get a boing sound every time a ball hits a wall. This one's a bit tricky to get right, with all the new files that have been added to the project, so if you have some trouble you may want to download the completed project at the top of this lesson and use it as a guide.
Now if you look at the Sound class, there's something we haven't covered before. It is a static class. This means that you can't create objects of type Sound. You can only call the methods of class Sound by specifying the class name. This is useful if you have a class that doesn't need multiple copies of its data, and it needs to be accessed from multiple other classes, but you don't want to pass the object into each method call or force each object that calls the class to store a reference to the class.
In this case, we don't need multiple copies of the AudioEngine, WaveBank, and SoundBank objects that the Sound class contains, and actually if we had multiple copies it would probably cause problems. Also we want to be able to play a sound from anywhere. So it makes sense for the Sound class to be static. Typically, as it is with this Sound class, static classes will contain an Initialize() or similar method since no actual objects of type Sound are created, therefore we can't use Sound's constructor to initalize the Fields in the class.