Sound class
Creating a sound class is really easy. You have seen some sound classes in the first chapter, and sound cue playback is very simple. To make it easier to use, you can define an enumeration that contains all the voice cue names. This method ensures that every sound cue exists, and you do not enter the wrong name. Another advantage of this is smart sensing, which will show all available sound cue hidden in the xact project. It is worthwhile to write these enumerations in two minutes. With the help of the play method in the sound class, it is easy to play sound cue now.
/// <Summary> /// play /// </Summary> /// <Param name = "soundname"> sound name </param> Public static void play (string soundname) {If (soundbank = NULL) return; try {soundbank. playcue (soundname);} // try catch (exception ex) {log. write ("Playing Sound" + soundname + "failed:" + ex. tostring ();} // catch} // play (soundname) /// <summary> /// play /// </Summary> /// <Param name = "sound"> sound </param> Public static void play (sounds sound) {play (sound. tostring ();} // play (sound)
You can also allow only sound enumeration by making the string private. If the sound bank cannot be initialized in the constructor (for example, if the file is lost), this method returns immediately and you cannot play any sound. Errors are recorded in log files. Then you call playcue to play the video and forget the sound cue. If it fails, you only write the log file, because you do not want to interrupt the normal operation because of the loss of some audio files.ProgramLogic.
As you have seen before, you can also use the getcue method to remember a sound cue and then do multiple things. This is useful if you want to stop cue by yourself instead of waiting for the sound to finish. As an example, the followingCodeUsed to stop playing music:
Somesoundcue = soundbank. getcue ("somesound"); somesoundcue. Play ();... somesoundcue. Stop (audiostopoptions. Immediate );
Most of the Code in the sound class of the Games in this book is the same. Let's take a look at different and special features (see Figure 9-14 ).
Figure 9-14
First, you will find that there are different sound cue names in the sound enumeration. Rocket commander and racing games use custom picth cue. XNa shooeter does not use any special settings. You only need to play the music at the beginning of the game and then play all the sound effects.
Several auxiliary methods are created to make the input playback sound code more comfortable. For example, playexplosionsound only replaces the following code to make it faster and easier to write:
Sound. Play (sound. Sounds. EXPLOSION );
Two additional methods are added for playing music: startmusic and stopmusic. They also save Music cue audio tracks.
each sound class also has a unit test to check whether the playback sound is normal and whether the volume is correct. The unit test in the rocket Commander sound class is as follows:
/// <Summary> /// test play sounds /// </Summary> Public static void testplaysounds () {testgame. start (delegate {If (input. mouseleftbuttonjustpressed | input. gamepadajustpressed) sound. play (sounds. bomb); else if (input. mouserightbuttonjustpressed | input. gamepadbjustpressed) sound. play (sounds. click); else if (input. keyboardkeyjustpressed (keys. d1) sound. play (sounds. gamemusic); else if (input. keyboa Rdkeyjustpressed (keys. d2) sound. play (sounds. menumusic); else if (input. keyboardkeyjustpressed (keys. d3) sound. play (sounds. EXPLOSION); else if (input. keyboardkeyjustpressed (keys. d4) sound. play (sounds. fuel); else if (input. keyboardkeyjustpressed (keys. d5) sound. play (sounds. victory); else if (input. keyboardkeyjustpressed (keys. d6) sound. play (sounds. defeat); else if (input. keyboardkeyjustpressed (Key S. d7) {sound. playrocketmotorsound (0.75f); sound. changerocketmotorpitcheffect (0.5f);} // else if (input. keyboardkeyjustpressed (keys. d8) sound. stoprocketmotorsound (); texturefont. writetext (2, 30, "press 1-8 or a/B or left/right" + "mouse buttons to play back sounds! ") ;}) ;}// Testplaysounds ()
Finally, the update method is automatically called by the update method in the basegame class. The update method only ensures that all parameters, loops, and time values in xact are updated.
Rocket Engine Sound
Let's take a quick look at the rocket engine sound in the rocket Commander. You have seen the Code required to complete this job. The following shows how to integrate and cooperate with the rocket Commander game engine. At first, this was written using directsound, but it worked well in xact:
/// <Summary> /// play rocket motor sound /// </Summary> Public static void playrocketmotorsound () {// get new cue everytime this is called, else we get xact throwing // This: the method or function called cannot be used in the manner // requested. rocketmotorsound = soundbank. getcue (sounds. rocketmotor. tostring (); // plays the sound looped, set in xact rocketmotorsound. play (); // make motor Category A Little silent motorcategory. setvolume (0.86f);} // playrocketmotorsound (volume) /// <summary> // change rocket motor pitch effect // </Summary> /// <Param name = "pitchfactor"> pitch factor </param> Public static void changerocketmotorpitcheffect (float pitchfactor) {rocketmotorsound. setvariable ("pitch", 55 * mathhelper. clamp (pitchfactor-1,-1, 1);} // changerocketmotorpitcheffect (pitchfactor) /// <summary> // stop rocket motor sound // </Summary> Public static void stoprocketmotorsound () {rocketmotorsound. stop (audiostopoptions. immediate);} // stoprocketmotorsound ()
After the game starts, you only need to call the playrocketmotorsound method to play the rocket sound, and then use the changerocketmotorpitcheffect method to modify it:
// Adjust rocket playback frequency to flying speedsound. changerocketmotorpitcheffect (0.66f + speed * 0.9f );
If you fail or the task ends, call the stoprocketmotorsound method to stop playing the rocket sound.
The sound logic in racing games works in a similar way, but it is more complicated because you have 13 different engine sounds. Let's take a look at the sound class of racing games for more details.
Whoosh, what is that?
In the first version, the rocket Commander uses its own 3D sound effect calculation formula and uses the volume and panning attribute of directsound. Panning cannot be changed in xNa. All sounds must be played in the form created and set in xact. For 3D sound, you should use real 3D sound code. In the xNa electric test version, I wrote some code for playing 3D sound and implemented a 3D listening object in the 3D world.
This 3D listening object is removed from xNa and you cannot use 3D sound effects now. I hope that changes will be made in the future. If 3D can be implemented, I will update the code in this book. But now you can only play single-channel sound without stereo or loop sound.
If you can use x3daudio and x3daudiolistener (these classes may have different names, but importantly, you can set and play 3D audio effects, and determine the player location with the help of the 3D listener class). After setting all the important cue, the following code is used to play the 3D sound:
// Setup 3D listener for 3D soundsound. Listener = new x3daudiolistener (zaxis, yaxis, cameraposition, movementvector );
Now, set the transmitter for each sound and play the 3D audio instance. Currently, no C # code can do this. If you are confused about this, you can refer to the following link to learn how the x3daudio class uses C ++. The practice in C # is similar, but it is expected to be easier to write.
Http://msdn.microsoft.com/library/default.asp? Url =/library/en-US/directx9_c/audio_xact_overview_x3daudio.asp
Menu sound
Here are some tips about the menu sound:
- Play a sound using an auxiliary method such as playmenuhighlight or playmenuclick, instead of using sound enumeration.
- If you want to play the menu sound at different volumes, for example, when the main button sound and the minor control sound light, you can create two sound cue in xact instead of writing your own custom code, this process is heavy and unnecessary.
Try to write an auxiliary method to determine whether the mouse is moved to the control and re-use this code. In this way, you do not have to process the click or highlighted sound each time.
Make sure that you also support the Xbox 360 controller and keyboard. Writing a game that only supports the mouse makes no sense in Xbox 360, because Xbox 360 does not support the mouse.
When you move to a menu item, the highlighted sound is played. When you press the handle key or space or enter to select a menu, the clicked sound is played.