在XNA中如何播放聲音
接下來將介紹遊戲中不可或缺的要素,那就是音樂或是音效等聲音,一個遊戲如果沒有了聲音,姑且不論它是否好玩有趣,想必也沒什麼好玩的了,因為聲音可以用來幫助我們融入這個遊戲的情境,適時的使用聲音可以使玩家更快的融入遊戲當中,所以就必須了解一下XNA在聲音上是如何處理的。
之前介紹了一下XNA在音效處理上是使用了XACT這個工具來處理聲音,下面就會真正來介紹如何來實現它和它操作的流程。
設定XACT專案:
開啟XACT之後,必須先將專案存在指定的地方,之後才可以開始設定專案裡的東西。
之後在右方Wave Banks上按右鍵選取New Wave Bank。
然後在右方Sound Banks上按右鍵選取New Sound Bank。
之後在Wave Bank的視窗上按右鍵選取Insert Wave File之後去選你要放在遊戲中的音樂或音效。
再來就是將Wave Bank視窗中所有的聲音檔用拖移的方式拉到Sound Bank的視窗中,CueName有顯示出檔名才代表成功。
之後就調整一下聲音檔的一些控制,像是循環播放幾次或是聲音大小等設定,需要注意的是Loop Count=0,是代表不重複播放,故聲音只會發生一次,而我們在遊戲中所使用的音效就是需要設定為0,而背景音樂則必須勾選intinite,代表無限撥放,調整完之後必須存檔,設定在程式中才能夠有效。
播放音效程式流程:
將XACT專案設定完畢之後就可以開始在我們的程式上使用,開啟程式後必須先將專案放入Content裡面以便程式讀取,這裡不需要將音樂檔也加入到專案中,但是音樂檔還是必須要放在該專案的Content目錄裡面,以供XACT專案檔能夠搜尋的到。
然後在程式一開始必須先宣告會使用到的變數AudioEngine、WaveBank、SoundBank。
AudioEngine audioEngine;
WaveBank waveBank;
SoundBank soundBank;AudioEngine最主要就是要來讀取XACT(.xgs)的專案,WaveBank是聲音檔(.WAV)的集合,也就是加入到專案到WAV檔案,而SoundBank是cue的集合,在使用前先在Initialize在函數中宣告它們所讀取到檔案的位置,
audioEngine = new AudioEngine("Content\\sound.xgs");
waveBank = new WaveBank(audioEngine, "Content\\Wave Bank.xwb");
soundBank = new SoundBank(audioEngine, "Content\\Sound Bank.xsb");在AudioEngine函數裡面需要填入你想要讀取的XACT專案的名稱,副檔名是xgs,WaveBank函數裡面則是填入你在聲音專案中WaveBanks所取的名稱,副檔名是xwb,SoundBank函數裡面則是填入你在聲音專案中SoundBanks所取的名稱,副檔名是xsb,這裡需要注意的是路徑位置,路徑位置是輸入編譯後的檔案位置,預設的情況下都會在編譯完的檔案都會放在該專案資料夾/bin/x86/debug/Content底下,因此我們在輸入路徑時就必須在加上「Content\\」,表示在這個資料夾底下。
在來就是真正的播放聲音了,剛剛說SoundBank是Cue的集合,所以就是需要用到它裡面的成員函數PlayCue,裡面要填入的就是WAV的檔名,但不需要輸入副檔名.wav。
soundBank.PlayCue("wav檔名無須加上副檔名");播放音效程式範例:
using System;02
using System.Collections.Generic;03
using System.Linq;04
using Microsoft.Xna.Framework;05
using Microsoft.Xna.Framework.Audio;06
using Microsoft.Xna.Framework.Content;07
using Microsoft.Xna.Framework.GamerServices;08
using Microsoft.Xna.Framework.Graphics;09
using Microsoft.Xna.Framework.Input;10
using Microsoft.Xna.Framework.Media;11
using Microsoft.Xna.Framework.Net;12
using Microsoft.Xna.Framework.Storage;13

14
namespace test_voice15
{16
public class Game1 : Microsoft.Xna.Framework.Game17
{18
GraphicsDeviceManager graphics;19
SpriteBatch spriteBatch;20
//紀錄健盤的按鍵21
KeyboardState oldState;22
//存放音樂專案資訊23
AudioEngine audioEngine;24
WaveBank waveBank;25
SoundBank soundBank;26

27 public Game1()
28
{29
graphics = new GraphicsDeviceManager(this);30
Content.RootDirectory = "Content";31
}32

33 protected override void Initialize()
34
{35
audioEngine = new AudioEngine("Content\\sound.xgs");36
waveBank = new WaveBank(audioEngine, "Content\\Wave Bank.xwb");37
soundBank = new SoundBank(audioEngine, "Content\\Sound Bank.xsb");38
base.Initialize();39
}40

41 protected override void LoadContent()
42
{43
spriteBatch = new SpriteBatch(GraphicsDevice); 44
}45

46 protected override void UnloadContent()
47
{48
}49

50 protected override void Update(GameTime gameTime)
51
{52
KeyboardState newState = Keyboard.GetState();53
if (newState.IsKeyDown(Keys.A))54
{55
if (!oldState.IsKeyDown(Keys.A))56
{57
soundBank.PlayCue("0164"); //播放聲音58
}59
}60
else if (newState.IsKeyDown(Keys.S))61
{62
if (!oldState.IsKeyDown(Keys.S))63
{64
soundBank.PlayCue("Bat"); //播放聲音65
}66
}67
oldState = newState;68
base.Update(gameTime);69
}70

71 protected override void Draw(GameTime gameTime)
72
{73
GraphicsDevice.Clear(Color.CornflowerBlue);74
base.Draw(gameTime);75
}76
}77
}78
此範例還加入了鍵盤按鍵的控制,按鍵A和S有個別的聲音,在被按下的時候才會發出聲音。
最後附上播放音效專案檔:test-voice.rar






using