聲音是遊戲很重要的一環,聲光效果都有的遊戲才會吸引人玩下去
在 XNA Framework 中,如果要加入音樂、音效等效果
必須使用 XACT - Microsoft Cross-Platform Audio Creation Tool 來幫忙達成
以下 XNA MSDN 的範例將一步步示範如果在遊戲中加入聲音
##CONTINUE##
準備工作,使用 XACT 建立聲音專案
開啟上一篇 XNA Game Studio Express 控制模組的移動 範例中的專案
並參考 XNA Game Studio Express 顯示 3D 模組 的文章中
由先前建立的 Spacewar Windows Starter Kit 專案取出聲音檔作示範
首先在開啟專案中先建立相關目錄 Content\Audio\Waves
並 Copy Spacewar Windows Starter Kit 專案中的
Ships\engine_2.wav 及 Weapons\hyperspace_activate.wav 到此專案的相同目錄下
1. 從 Windows 開始選單,選擇 所有程式 -> Microsoft XNA Game Studio Express -> Tools,執行 Microsoft Cross-Platform Audio Creation Tool (XACT)
2. 開啟 XACT 軟體後,儲存專案在此專案的 Contant\Audio 下名稱為 MyGameAudio
3. 新增 New Wave Bank 及 New Sound Bank,並在 Wave Bank 下加入剛才 Copy 至專案目錄下的兩個聲音檔
將剛才加入 Wave Bank 的兩個聲音檔,拖曳到 Sound Bank 視窗的 Cue Name Panel 中
如下所示
最後,指定當我們播放 engine_2 聲音時,它必須不斷環境播放
這點就像是遊戲不斷環境播放的背景音樂一樣,總不希望背景音樂只播放一次就停止了吧
在 Sound Bank 視窗中選擇 engine_2 聲音,並在右上方視窗選擇 Play Wave 字樣
並在視窗最左下方 LoopEvent 中選擇 Infinite 指定環境播放
最後儲存離開 XACT 軟體
進行到此步驟,XACT 會將我們加入的聲音檔案指定相對目錄及聲音檔的播放動作
以 MyGameAudio.xap 描述檔儲存在 Content\Audio 這個指定的目錄下
接下來就可以將 XACT project 加入示範專案的 Content Pipeline 中
加入聲音至專案
回到 Visual Studio 2005 Express 示範專案中,在 Content\Audio 目錄按右鍵
加入 -> 現有項目,選擇剛才建立的 MyGameAudio.xap
在 Initialize 函式下加入以下程式碼將聲音資料載入遊戲中
AudioEngine: 讀入 XACT 專案,副檔名為 .xgs
WaveBank: 取出 AudioEngine 元件中 Wave Bank 的聲音資料,副檔名為 .xwb
SoundBank: 取出 AudioEngine 元件中 Sound Bank 的聲音資料,副檔名為 .xsb
AudioEngine audioEngine;
WaveBank waveBank;
SoundBank soundBank;
protected override void Initialize()
{
audioEngine = new AudioEngine("Content\\Audio\\MyGameAudio.xgs");
waveBank = new WaveBank(audioEngine, "Content\\Audio\\Wave Bank.xwb");
soundBank = new SoundBank(audioEngine, "Content\\Audio\\Sound Bank.xsb");
base.Initialize();
}
程式中使用 Cue 物件來處理聲音播放、停止的功能
在 update 函式中判斷鍵盤輸入及決定聲音的輸出與否
需注意的是,update 函式會不斷的被呼叫,必須判斷聲音播放的狀態決定執行的動作
避免已在播放中時還不斷的要求播放,造成系統的負載
// Cue so we can hang on to the sound of the engine.
Cue engineSound = null;
protected void UpdateInput()
{
// Get the game pad state.
KeyboardState keyboard_currentState = Keyboard.GetState();
if (keyboard_currentState != null)
{
// Rotate the model using the left thumbstick, and scale it down.
if (keyboard_currentState.IsKeyDown(Keys.Left) == true)
modelRotation += 1 * 0.10f;
if (keyboard_currentState.IsKeyDown(Keys.Right) == true)
modelRotation -= 1 * 0.10f;
// Create some velocity if the right trigger is down.
Vector3 modelVelocityAdd = Vector3.Zero;
// Find out what direction we should be thrusting, using rotation.
modelVelocityAdd.X = -(float)Math.Sin(modelRotation);
modelVelocityAdd.Z = -(float)Math.Cos(modelRotation);
// Now scale our direction by how hard the trigger is down.
if (keyboard_currentState.IsKeyDown(Keys.Up) == true)
modelVelocityAdd *= 3;
if (keyboard_currentState.IsKeyDown(Keys.Down) == true)
modelVelocityAdd *= 0.3F;
// Finally, add this vector to our velocity.
modelVelocity += modelVelocityAdd;
// Set some audio based on whether we're pressing a trigger.
if (keyboard_currentState.IsKeyDown(Keys.Up) == true)
{
if (engineSound == null)
{
engineSound = soundBank.GetCue("engine_2");
engineSound.Play();
}
else if (engineSound.IsPaused)
{
engineSound.Resume();
}
}
else
{
if (engineSound != null && engineSound.IsPlaying)
{
engineSound.Pause();
}
}
// In case you get lost, press A to warp back to the center.
if (keyboard_currentState.IsKeyDown(Keys.Space) == true)
{
modelPosition = Vector3.Zero;
modelVelocity = Vector3.Zero;
modelRotation = 0.0f;
// Make a sound when we warp.
soundBank.PlayCue("hyperspace_activate");
}
}
// Get the game pad state.
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
if (currentState.IsConnected)
{
// Rotate the model using the left thumbstick, and scale it down.
modelRotation -= currentState.ThumbSticks.Left.X * 0.10f;
// Create some velocity if the right trigger is down.
Vector3 modelVelocityAdd = Vector3.Zero;
// Find out what direction we should be thrusting, using rotation.
modelVelocityAdd.X = -(float)Math.Sin(modelRotation);
modelVelocityAdd.Z = -(float)Math.Cos(modelRotation);
// Now scale our direction by how hard the trigger is down.
modelVelocityAdd *= currentState.Triggers.Right;
// Finally, add this vector to our velocity.
modelVelocity += modelVelocityAdd;
GamePad.SetVibration(PlayerIndex.One, currentState.Triggers.Right,
currentState.Triggers.Right);
// Set some audio based on whether we're pressing a trigger.
if (currentState.Triggers.Right > 0)
{
if (engineSound == null)
{
engineSound = soundBank.GetCue("engine_2");
engineSound.Play();
}
else if (engineSound.IsPaused)
{
engineSound.Resume();
}
}
else
{
if (engineSound != null && engineSound.IsPlaying)
{
engineSound.Pause();
}
}
// In case you get lost, press A to warp back to the center.
if (currentState.Buttons.A == ButtonState.Pressed)
{
modelPosition = Vector3.Zero;
modelVelocity = Vector3.Zero;
modelRotation = 0.0f;
// Make a sound when we warp.
soundBank.PlayCue("hyperspace_activate");
}
}
}
原本 XNA MSDN 範例中以 XBOX360 為示範平台
天秤將它改成以 PC 鍵盤輸入操作及聲音輸出
範例中按下上鍵時飛行器會加速,並發出加速的聲音,由於 engine_2 聲音在 XACT 中被指定為不斷播放,所以按住上鍵時會持續的播放直到放開
按下 Space 鍵時飛行器會回到預設值,並發出 hyperspace_activate 聲音
下載: 本範例程式碼及執行檔下載
0 意見:
張貼留言