遊戲音樂與音效的播放 (轉)
在環境下,音效的方法太多了,而且有一個共同點就是:你不需要花很大的心力就可以得到你需要的東西。延續主題式的探討,這一期我們著重在音樂與音效的播放。
□ 遊戲的配樂
我相信很多人一定同意音樂在遊戲裡面所佔的地位,回想一下國內RPG的經典「仙劍奇俠傳」,剝掉音樂這一個層面,整個遊戲將會遜色不少,尤其適當的場景搭配適當的音樂,更能讓玩家融入劇情當中。該哭的時候哭,該笑的時候笑,大概就很切中要領了。RPG剩下的音效部份,並不特別突出,大抵上知道砍人的時候有揮劍的就可以了,所以在音效的表現方面,通常比較不那麼注重。而即時戰鬥的遊戲著重在廝殺的音效表現上,一大片人馬,一片混雜的聲音,這其中牽涉到混音的部份,我們底下也會探討到。讀完這篇文章,你會學習到什麼時候該用什麼樣的程式作法來表現遊戲的另一個生命:音樂與音效。
□從MIDI開始
早期DOS下的音樂部份,大多數採用聲霸卡的規格,副檔名為CMF者便是這種格式,當然遊戲通常不會讓你看到真正的作法,但是內部採用這種格式居多是無庸置疑的。而WINDOW下的遊戲以光碟發行者居多,為了充分達到空間利用的階段,遊戲中會大量使用WAV格式的檔案,或是直接將音樂燒成音軌的格式。尤其很多遊戲喜歡採用第一片資料片,第二片音樂片的作法,平常不玩遊戲還可以當成音樂CD來聽,算是滿有質感的一件事。當然,我的意思是這些音樂必須要聲聲入耳,如果音樂本身庸庸碌碌的,即使燒成音軌,一樣是庸庸碌碌,改變不了這個事實。
在WINDOW下,考量到空間的大小,MIDI格式的音樂檔絕對是最佳的選擇,一首五分鐘的MIDI了不起十萬字元的大小,這跟WAV格式一分鐘佔用量以MB計,簡直是小巫見大巫,所以網站上的音樂,遊戲的音樂,都很適合用MIDI來表現,而音樂部份我個人注重旋律,至於一首音樂本身使用到的樂器數量,我倒是很少去注意,人的耳朵聽東西有一定的極限,只要不產生雜音,配合優美的旋律,大致上都可以接受。
□播放MIDI的程式作法
遊戲中播放音樂的要點就是迴圈播放,也就是播放完畢以後,要讓他從頭開始播放,直到場景更換,或是遊戲結束為止。所以當MIDI檔案播放完畢以後,必須要能通知程式,讓程式做出適當的處理。播放MIDI的作法只要藉由WINDOW的多的支援,馬上就搞定了,甚至直接從HELP的作法剪過來,稍微修改一下,也能符合需要,因為這種東西相當公式化,A君和B君寫出來的程式碼也大致上會長得差不多,廢話不多說,看看程式多麼簡單便是:
class CMidi
{
public:
D Play(HWND,char* FileName);
void Replay();
void Stop();
private:
裝置代號
DWORD dwReturn;
MCI_OPEN_PARMS mciOpenParms;
MCI_PLAY_PARMS mciPlayParms;
MCI_STATUS_PARMS mciStatusParms;
MCI_SEQ_SET_PARMS mciSeqSetParms;
};
將他包裝成一個類別來使用也可以,而介面的部份需要單純化,從直覺上來說,第一個動作就是播放(Play),接著是重播(Replay),最後當然是善後的工作了(Stop),不多不少,剛好三個,當然你會想到,是不是需要一個暫停的介面,沒問題,這不是什麼難事,花額外的三分鐘應該可以勝任愉快。
瞭解類別大致上的長相以後,讓我們來看看實作的部份是怎麼一回事,先從CMidi::Play()開始:
DWORD CMidi::Play(HWND hwnd,char* MidiFile)
{
開啟Midi的硬體裝置,我們使用一般內定值
mciOpenParms.lpstrDeviceType = "sequencer";
這個叄數就是要播放的MIDI檔案名稱
mciOpenParms.lpstrElementName = MidiFile;
使用Message的方式來播放MIDI而不是STRING的方式
if (dwReturn = mciSendCommand(NULL, MCI_OPEN,
MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID) &mciOpenParms)
return (dwReturn);
// The device opened succesully; get the device ID.
wDeviceID = mciOpenParms.wDeviceID;
// Check if the output port is the MIDI mapper.
mciStatusParms.dwItem = MCI_SEQ_STATUS_PORT;
if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,
MCI_STATUS_ITEM, (DWORD)(LPVOID) &mciStatusParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
return (dwReturn);
}
為了達成重複播放的目的,必須讓我們的程式能夠接收到
的訊息,這個函示呼叫的方式,就是傳遞
訊息給裝置,叫他開始播放。
mciPlayParms.dwCallback = (DWORD) hwnd;
if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY,
(DWORD)(LPVOID) &mciPlayParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
return (dwReturn);
}
return (0L);
};
播放MIDI的方式有兩種,第一種是利用字串命令硬體動作,第二種是傳遞訊息的方式,我們採用第二種,原因很清楚了,必須透過訊息的傳遞,我們才能得知音樂是否播放完畢了。
接下來我們看看Cmidi::Replay是怎麼一回事:
void CMidi::Replay()
{
mciSendCommand(wDeviceID, MCI_SEEK,MCI_SEEK_TO_START, NULL);
mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);
}
真是不可思議地簡單呀,函示裡面只包含兩條呼叫,第一條呼叫送訊息給裝置,叫他把MIDI的播放指標移到最開頭的部份,也就是MCI_SEEK_TO_START,
作法就像移動檔案指標一樣。接著第二條指令光看也明白,就是叫他繼續播放就是了,而且別忘了MCI_NOTIFY,當下次播放完畢,還是得用訊息通知我們的程式。
最後看一下Cmidi::Stop()的作法:
void CMidi::Stop()
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
}
越來越單純了,裡面只有包含一個函示呼叫,其中的訊息叄數MCI_CLOSE,就是結束整個音樂的播放。當你結束播放以後,要播放另一首音樂,很簡單,再次呼叫Cmidi::Play()即可。
整個類別的使用方法大致上是這樣的:首先一個實際的CMidi物件給程式,只要在全域的地方下條指令 CMidi midi;即可,爾後midi就是真實的物件了。在場景初始化的部份呼叫midi.Play(hwnd,"ff3celes.mid");,輸入正確的MIDI檔名即可。此處我播放的是太空戰士三代的音樂,只是示範一下,當然這首音樂確實很棒就是了。而在訊息迴圈裡面,我們必須定義一個訊息:
case MM_MCINOTIFY:
midi.Replay();
break;
在音樂播放完畢以後,我們的訊息迴圈會收到MM_MCINOTIFY這個訊息,這時候如同我們前面所言,呼叫Cmidi::Replay()即可。而當場景更換,要重新一首新的音樂,或是程式結束的時候,就是呼叫Cmidi::Stop()的時機。因為一個場景同時間只會存在一首音樂,所以我們的類別表現良好,不用擔心。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-987297/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 遊戲基礎知識——音效和音樂的作用遊戲
- 影響遊戲玩家沉浸感的因素——背景音樂&音效遊戲
- 遊戲音樂與影視音樂的異同遊戲
- 一文帶你實現遊戲中的音樂、音效設定遊戲
- 遊戲音訊工作室SIDE收購Vibe Avenue,擴張音樂音效業務遊戲音訊IDE
- 遊戲音樂的認識與製作三遊戲
- c#音樂播放C#
- 《虛構世界》:是音遊又不是音遊的音樂遊戲遊戲
- vue音樂播放器Vue播放器
- 遊戲中的哥特音樂遊戲
- 遊戲音樂和影視音樂有什麼不同?遊戲
- Monkey 執行的時候,音樂播放..
- 千千音樂 for Mac(原百度音樂播放器)Mac播放器
- 好音樂是如何與好遊戲打成一片的?遊戲
- 音樂播放器:Swinsian for Mac播放器Mac
- Listen 1音樂播放器播放器
- TurnTable for Mac音樂播放器Mac播放器
- 基於Android的音樂播放器的設計與實現Android播放器
- 解密《Unheard-疑案追聲》中的音效(音樂)製作解密
- 如何實現遊戲陪玩系統中語音的錄製與播放?遊戲
- 《音遊詩人》:國風音樂創意小遊戲的誕生與DIY編輯器探索遊戲
- Android開源線上音樂播放器——波尼音樂Android播放器
- mac音樂播放器:Decibel for MacMac播放器
- Swinsian for Mac(mac音樂播放器)Mac播放器
- TurnTable for Mac(iTunes音樂播放器)Mac播放器
- MacYouTube音樂播放器——Muse for MacMac播放器
- Mac音樂播放器——TurnTable for MacMac播放器
- 仿網易雲音樂播放介面
- H5音樂播放器H5播放器
- 將通用安卓音樂播放器轉化為 instant 應用安卓播放器
- 微信小遊戲開發(10)-音訊播放遊戲開發音訊
- 音樂播放器WordPress外掛 WP-Player (支援網易雲音樂, 蝦米音樂, QQ音樂, 百度音播放器
- Linux 上最好的五款音樂播放器Linux播放器
- 音樂能給遊戲加多少分?《原神》音樂創作背後的故事遊戲
- Android開源音樂播放器之高仿雲音樂黑膠唱片Android播放器
- 高階音樂播放器:Swinsian for Mac播放器Mac
- js播放背景音樂失敗處理JS
- Colibri for mac(無損音樂播放器)Mac播放器
- Clementine for Mac - 現代音樂播放器Mac播放器