CHAPTER 6
There aren’t many games that won’t benefit from good sound effects and music. Even board games can use sound to enhance the play experience. Playing sounds for tokens moving around the board and landing on special areas, cards flipping or moving, etc. can be used to enhance the game. Many games make the sound portion of the game development process the lowest priority, unless it’s a game in the music genre.
As with most other areas of the game development process, getting audio into your game is fairly easy with MonoGame. The object-oriented nature of the framework makes it easy to work with your audio files. At the most basic level, you need just two lines of code to play a sound (assuming you already have a ContentManager object, which by this point you do):
SoundEffect se = Content.Load<SoundEffect>("soundname"); se.Play(); |
Code Listing 56 – SoundEffectInstance State Enum
If you need to control the volume, pitch, or panning of a sound, you can call the overloaded Play method that takes these three parameters:
se.Play(1.0f, 0.0f, 0.0f); |
Code Listing 57 – SoundEffectInstance State Enum
The parameters’ possibilities are shown in the following table:
Volume | Ranges from 0.0 (silence) to 1.0 (full volume) |
Pitch | Ranges from -1.0 (down an octave) to 0.0 (no change) to 1.0 (up an octave) |
Pan | Range from -1.0 (left speaker) to 0.0 (centered), 1.0 (right speaker) |
Table 10 – Play Method Parameters
Both methods return a SoundEffectInstance object, which you can keep around if you need to work with the sound after you start playing it, including adjusting the previously mentioned properties or playing it as a 3D sound using AudioListener and AudioEmitter objects.
If you’re working with a SoundEffectInstance object, you may need to know what state it’s in at some point. If the object is currently playing, you probably don’t want to try playing it again. If, for some reason, you’ve paused the sound in one section of code, you may need to know in another section if it’s still paused. You can use the State property of the SoundEffectInstance class to find out the state of the object. It will return one of three states:
public enum SoundState { Paused, Playing, Stopped } |
Code Listing 58 – SoundEffectInstance State Enum
Our sound system will not use instances, as it’s extremely simple. We’ll keep a collection of sounds in the Game class and load the collection in the Initialize method:
public enum Sounds { GhostDie, Menu, PlayerDie, Title, Zap } public Dictionary<Sounds, SoundEffect> GameSounds; protected override void Initialize() { GameSounds = new Dictionary<Ghost_Arena.Sounds, SoundEffect>(); GameSounds.Add(Sounds.GhostDie, Content.Load<SoundEffect>("ghostdie")); GameSounds.Add(Sounds.Zap, Content.Load<SoundEffect>("zap")); GameSounds.Add(Sounds.Menu, Content.Load<SoundEffect>("menu")); GameSounds.Add(Sounds.PlayerDie, Content.Load<SoundEffect>("playerdie")); GameSounds.Add(Sounds.Title, Content.Load<SoundEffect>("title"));
. . . |
Code Listing 59 – SoundEffectInstance State Enum
The sounds will be used in the EntityManager, MainMenuScreen, and MenuScreen classes. In the MenuScreen’s HandleInput method, we’ll add one line after the OnSelectEntry(_selectedEntry); line:
((Game1)ScreenManager.Game).GameSounds[Sounds.Menu].Play(); |
Code Listing 60 – MenuScreen Item Selected Sound
We have three places in the EntityManager where we play sounds. In the Update method, the following code goes after the _entities.Remove(_entities[i]); line. The other two existing methods should be replaced with the following.
public void Update(GameTime gameTime) { . . . if (_entities[0].Health <= 0) { Game1.Instance.GameSounds[Sounds.PlayerDie].Play(); } . . . } public void PlayerFire() { if (_entities.Count > 0) { if (_entities[0].SpawnBullet()) Game1.Instance.GameSounds[Sounds.Zap].Play(); } } private void SpawnGhost() { int num = _rnd.Next(0, 10); _entities.Add(new Entity(EntityType.Ghost, _ghostSpawnPoints[num], _ghostSpawnDirections[num], 4, _ghostTexture.Width, Game1.Instance)); Game1.Instance.GameSounds[Sounds.GhostDie].Play(); } |
Code Listing 61 – EntityManager Sound Code
When the game starts we’ll play the Title sound. Add the following line as the first line in the Initialize method:
((Game1)ScreenManager.Game).GameSounds[Sounds.Title].Play(); |
Code Listing 62 – MainMenuScreen Sound Code
That’s all there is to sound in our game. For most simple games, there probably won’t be much more than this. Larger games could do things like use 3D sound or distort sounds.
We just have a bit more to add to make our game complete. This is the last stretch—take a deep breath and dive in.