0669_05_AUDIOPACK.zip
file from the book's website and extract the files to a temporary folder. Sounds
. .WAV
files from the audio pack temporary folder to your new Sounds
folder in the content project. using
directives to the top of the SoundManager class file:using System.Diagnostics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content;
public static
before the declaration:public static class SoundManager
private static List<SoundEffect> explosions = new List<SoundEffect>(); private static int explosionCount = 4; private static SoundEffect playerShot; private static SoundEffect enemyShot; private static Random rand = new Random();
Initialize()
method to the SoundManager class:public static void Initialize(ContentManager content) { try { playerShot = content.Load<SoundEffect>(@"SoundsShot1"); enemyShot = content.Load<SoundEffect>(@"SoundsShot2"); for (int x = 1; x <= explosionCount; x++) { explosions.Add( content.Load<SoundEffect>(@"SoundsExplosion" + x.ToString())); } } catch { Debug.Write("SoundManager Initialization Failed"); } }
PlayExplosion()
method to the SoundManager class:public static void PlayExplosion() { try { explosions[rand.Next(0, explosionCount)].Play(); } catch SoundManager classPlayExplosion() method, adding{ Debug.Write("PlayExplosion Failed"); } }
PlayPlayerShot()
method to the SoundManager class:public static void PlayPlayerShot() { try { playerShot.Play(); } catch { Debug.Write("PlayPlayerShot Failed"); } }
PlayEnemyShot()
method to the SoundManager class:public static void PlayEnemyShot() { try { enemyShot.Play(); } catch { Debug.Write("PlayEnemyShot Failed"); } }
By creating our SoundManager class as a static class, we can use its methods from anywhere in our program without creating instances of the class. In fact, we can never create instances of a static class, and all members of the class must also be declared static.
Also unlike a normal (non-static) class, we do not have an instance constructor. While C# supports static constructors, we do not want to use one in this case because we need to pass the ContentManager
object to the class in order for it to load sounds.
The Initialize()
method does the work that a class constructor would normally do. It uses the ContentManager
to load SoundEffect
objects in exactly the same way we load textures or fonts. Once the SoundEffect
has been loaded, it supports a Play()
method that causes the sound effect to be played once.
SoundEffect and SoundEffectInstance classes
XNA defines these two classes to assist in playing sound effects. In reality, all actual sounds are played by SoundEffectInstances. The SoundEffect.Play()
method creates a new instance, plays the sound, and disposes off the instance. This allows "fire and forget" handling of sound effects. If you wish to have more control over the effects, you can create instances directly with SoundEffect.CreateInstance()
. SoundEffectInstances can be played, stopped, and looped. Windows can play any number of sounds at the same time (subject to hardware limitations and performance issues) while the Zune is limited to 16 actively playing SoundEffectInstances. On the Xbox 360, a total of 300 SoundEffectInstances (stopped or playing) can exist at any one time. If you create a SoundEffectInstance manually, you must also dispose it off manually (via the Dispose()
method) when you no longer need it.
Everything in the Initialize()
and Play...()
methods are surrounded by try...catch
blocks that attempt to execute the code inside the try
block and, if an exception is generated, executes the catch
block. We added the System.Diagnostics
namespace to our using directives in order to use the Debug.Write()
method that will output a debugger message indicating any problems encountered. We need to do this because on a system without audio hardware, attempting to load or play a sound effect will cause an exception, crashing the game. Since we simply want to do nothing if the call fails, the catch
blocks write a debug message and take no other action.
3.16.81.94