在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。
WaveBank waveBank;
SoundBank soundBank;
AudioEngine最主要就是要來讀取XACT(.xgs)的專案,WaveBank是聲音檔(.WAV)的集合,也就是加入到專案到WAV檔案,而SoundBank是cue的集合,在使用前先在Initialize在函數中宣告它們所讀取到檔案的位置,
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。
播放音效程式範例:
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_voice
15 {
16 public class Game1 : Microsoft.Xna.Framework.Game
17 {
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