通过XACT添加声音——Sound类
Sound類
創建Sound類真的很簡單。你已經在第一章看到了一些Sound類,sound cue回放非常簡單。為了使使用起來更簡單,您可以定義一個枚舉包含所有的聲音cue名稱。通過這種方式可以確保每一個sound cue確實存在,而且你不會輸錯名稱。這樣做的另一個優點是智能感知,它將會顯示隱藏在XACT項目中所有可用的sound cue?;ㄙM兩分鐘時間寫這些枚舉是值得的。在Sound類中的Play方法幫助下,現在播放sound cue很容易。
/// <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)
您也可以通過讓字符串私有使得只允許聲音枚舉。如果sound bank無法在構造函數中初始化(例如,如果該文件丟失)此方法將立即返回而您無法播放任何聲音。錯誤會被記錄到日志文件中。接著你調用PlayCue播放并忘記sound cue。如果失敗你只寫入日志文件,因為你不想因為某些聲音文件的丟失打斷正常的程序邏輯。
正如你之前所見,您也可以使用GetCue方法記住一個sound cue,然后做多個事情。如果您想自己停止cue而不是等待聲音放完,這樣做是很有用的。作為一個例子,下面的代碼用來停止播放音樂:
someSoundCue = soundBank.GetCue("SomeSound");
someSoundCue.Play();
...
someSoundCue.Stop(AudioStopOptions.Immediate);
本書中的游戲的Sound類中的大部分代碼是相同的,下面看看不同和特殊功能(見圖9-14)。
圖 9-14
首先你會發現在Sound枚舉中有不同的sound cue名稱。Rocket Commander和賽車游戲使用自定義的picth cue。XNA Shooeter不使用任何特殊設置,你只需在游戲開始時播放音樂,然后播放所有音效。
為了使輸入播放聲音的代碼更舒適,創建了幾個輔助方法。例如,PlayExplosionSound只是取代了下面的代碼使其能更快并更容易編寫:
Sound.Play(Sound.Sounds.Explosion);
對于音樂播放添加了兩個額外的方法:StartMusic和StopMusic,它們也保存了music cue的音軌。
每個sound類中還有一個單元測試用來檢查回放聲音是否正常,并檢查音量是否正確。下面是Rocket Commander聲音類中的單元測試:
/// <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.KeyboardKeyJustPressed(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(Keys.D7))
{
Sound.PlayRocketMotorSound(0.75f);
Sound.ChangeRocketMotorPitchEffect(0.5f);
} // else if
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()
最后,Update方法被BaseGame類中的Update方法自動調用。Update方法只為您確保在XACT中所有參數,循環,時間值的更新。
火箭發動機聲音
快速看一下Rocket Commander中的火箭發動機聲音。前面你已經看到完成這個工作所需的代碼,下面是如何整合在一起并配合Rocket Commander游戲引擎,一開始這是用DirectSound寫的,但在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()
游戲開始后你只需調用PlayRocketMotorSound方法就能播放火箭的聲音,然后通過ChangeRocketMotorPitchEffect方法修改它:
// Adjust rocket playback frequency to flying speed Sound.ChangeRocketMotorPitchEffect(0.66f + speed * 0.9f);
如果你失敗或任務結束,則調用StopRocketMotorSound方法停止播放火箭的聲音。
賽車游戲中的聲音邏輯工作方法類似,但更加復雜,因為你有13個不同的發動機聲音??匆幌沦愜囉螒虻膕ound類了解更多細節。
Whoosh,那是什么呀?
初版本的Rocket Commander使用自己的3D音效計算公式并使用DirectSound的音量和和panning屬性。在XNA中不能改變panning。所有聲音必須以在XACT中創建和設置的方式播放。對于3D聲音,你應該使用真實的3D聲音代碼,在XNA電測版本中我寫了一些播放3D聲音的代碼,并實現了一個在三維世界中的3D監聽對象。
這個3D監聽對象在XNA中被移除,現在您不能使用3D音效。希望將來會做出改變,如果3D可以被實現,我一定會更新這本書中的代碼,但現在你只能播放單聲道的聲音,沒有立體聲或環繞聲。
如果你可以使用X3DAudio和X3DAudioListener (這些類可能有不同的名稱,重要的是您可以設置和播放3D音頻效果,并且在3D listener類的幫助下確定玩家的位置),在設置了所有重要的cue后,下面的代碼用于播放3D聲音:
// Setup 3D listener for 3D sound Sound.Listener = new X3DAudioListener( zAxis, yAxis, cameraPosition, movementVector);
現在,為每個聲音設置發射器并播放3D音頻實例。目前還沒有C#代碼可以做到這一點,如果你對此感到困惑,你可以看看下面的鏈接去了解X3Daudio類是如何使用C++的。在C#中做法類似,但希望能更容易編寫。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/ audio_xact_overview_x3daudio.asp
菜單聲音
這里有一些關于菜單提示聲音的小技巧:
使用如PlayMenuHighlight或PlayMenuClick之類的輔助方法播放聲音,而不是使用Sound枚舉。
如果你想用不同的音量播放菜單聲音,例如主要按鈕聲音響而小控件聲音輕,可以在XACT中建立兩個sound cue而不是編寫自己的自定義代碼,這樣做工作量很大而且沒有必要。
嘗試寫輔助方法判斷鼠標是否移到了控件上并重用此代碼,這樣,你就無需每次都自己處理播放點擊或高亮的聲音。
請確認您還支持Xbox 360控制器和鍵盤。編寫一個只支持鼠標的游戲在Xbox 360毫無意義,因為Xbox 360不支持鼠標。
當移動到菜單項時播放高亮的聲音,用戶按下手柄鍵或按下space或Enter鍵選擇菜單時播放點擊的聲音。
總結
以上是生活随笔為你收集整理的通过XACT添加声音——Sound类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 女贼用失主抖音号发视频被抓:以为换了头像
- 下一篇: Phaserjs V2的state状态解