游戏音乐与音效的播放
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
游戏音乐与音效的播放
发表日期:2006-08-23 作者:[转贴] 出处:目录:
文档内容:
在Win32环境下,播放音乐音效的方法太多了,而且有一个共同点就
是:你不需要花很大的心力就可以得到你需要的东西。延续主题式的
探讨,这一期我们着重在音乐与音效的播放。
□游戏的配乐
我相信很多人一定同意音乐在游戏里面所占的地位,回想一下国内RPG的
经典「仙剑奇侠传」,剥掉音乐这一个层面,整个游戏将会逊色不少,尤其
适当的场景搭配适当的音乐,更能让玩家融入剧情当中。该哭的时候哭,该
笑的时候笑,大概就很切中要领了。RPG剩下的音效部份,并不特别突出,
大抵上知道砍人的时候有挥剑的声音就可以了,所以在音效的表现方面,通
常比较不那麽注重。而即时战斗的游戏着重在厮杀的音效表现上,一大片人
马,一片混杂的声音,这其中牵涉到混音的部份,我们底下也会探讨到。读
完这篇文章,你会学习到什麽时候该用什麽样的程式作法来表现游戏的另一
个生命:音乐与音效。
□从MIDI开始
早期DOS下的音乐部份,大多数采用声霸卡的规格,副档名为CMF者便是
这种格式,当然游戏通常不会让你看到真正的作法,但是内部采用这种格式
居多是无庸置疑的。而WINDOW下的游戏以光碟发行者居多,为了充分达
到空间利用的阶段,游戏中会大量使用WAV格式的档案,或是直接将音乐
烧成音轨的格式。尤其很多游戏喜欢采用第一片资料片,第二片音乐片的作
法,平常不玩游戏还可以当成音乐CD来听,算是满有质感的一件事。当然,
我的意思是这些音乐必须要声声入耳,如果音乐本身庸庸碌碌的,即使烧成
音轨,一样是庸庸碌碌,改变不了这个事实。
在WINDOW下,考量到空间的大小,MIDI格式的音乐档绝对是最佳的选择,一首五分钟的MIDI了不起十万字元的大小,这跟WAV格式一分钟占用量以MB计,简直是小巫见大巫,所以网站上的音乐,游戏的音乐,都很适合用MIDI来表现,而音乐部份我个人注重旋律,至於一首音乐本身使用到的乐器数量,我倒是很少去注意,人的耳朵听东西有一定的极限,只要不产生杂音,配合优美的旋律,大致上都可以接受。
□播放MIDI的程式作法
游戏中播放音乐的要点就是循环播放,也就是播放完毕以後,要让他从头开始播放,直到场景更换,或是游戏结束为止。所以当MIDI档案播放完毕以後,必须要能通知程式,让程式做出适当的处理。播放MIDI的作法只要藉由WINDOW的多媒体的支援,马上就搞定了,甚至直接从HELP的作法剪过来,稍微修改一下,也能符合需要,因为这种东西相当公式化,A君和B 君写出来的程式码也大致上会长得差不多,废话不多说,看看程式多麽简单便是:
class CMidi
{
public:
DWORD Play(HWND,char* FileName);
void Replay();
void Stop();
private:
UINT wDeviceID; wDeviceID = ;
MIDI = MCI_SEQ_STATUS_PORT;
if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,
MCI_STATUS_ITEM, (DWORD)(LPVOID)
&mciStatusParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
return (dwReturn);
}
0L
= sizeof(DSBUFFERDESC);
//使用默认的设置(音量之类)
= DSBCAPS_CTRLDEFAULT;
//3秒钟长度的缓冲(3-second buffer)
= 3 *
= (LPWAVEFORMATEX)&pcmwf;
//创建缓冲
hr = lpDirectSound->lpVtbl->CreateSoundBuffer(lpDirectSound,
&dsbdesc, lplpDsb, NULL);
if SUCCEEDED(hr)
{
//成功
return TRUE;
}
else
{
//失败
*lplpDsb = NULL;
return FALSE;
}
}
很简单是吧,只要填两个STRUCT就OK了。
因为DirectSound对先创建的缓冲优先分配硬件资源,所以你应该先创建重要的缓冲。如果你事先声明要创建一硬件缓冲(和放在显存里的表面差不多),就应该在DSBUFFERDESC结构里设置DSBCAPS_LOCHARDWARE标志,但是如果你得不到足够的硬件资源(硬件内存或混音容量hardware memory or mixing capacity),将无法创建缓冲。
创建缓冲时,也可以声明是静态缓冲(设置DSBCAPS_STATIC标志)还是流缓冲;默认值是流缓冲(上面就是使用的默认值)。
缓冲是和DirectSound对象相关联的,如果释放了DirectSound对象,则它所有的缓冲也都将被释放。缓冲控制选项
你创建一辅助缓冲时,还应该声明该缓冲需要用到的控制选项。这项工作需要你为DSBUFFERDESC 结构设置以DSBCAPS_CTRL为首的标志(这些标志可以是单独的来使用,也可以同时设置几个)。
可用的控制有3-D属性、频率、Pan(左右正道的差值)、音量、Position notification(可能是指播放时的进度)。
为了能在所有的声卡上都可以获得做好的效果,最好只设置需要的控制选项。如果一块声卡支持硬件缓冲但不支持底盘控制(pan control),那么DiractSound只会在DSBCAPS_CTRLPAN标志没有被声明时使用硬件加速。这也就是说,DirectSound通过控制选项来决定如何为缓冲来分配硬件资源。
如果你使用一个缓冲不支持的控制,譬如为一个并没有声明DSBCAPS_CTRLVOLUME标志的缓冲调用IDirectSoundBuffer::SetVolume方法,是不可能成功的。
主缓冲的存取
如果你不满意DirectSound的工作,可以直接的操纵主声音缓冲,也可以说是直接的操纵硬件了,但是这将意味着DirectSound的部分特性不可用,包括辅助缓冲的混音和混音的硬件加速。
主缓冲其实是硬件缓冲,它的大小是由硬件来决定的,而这个值通常是很小的,因此你应该使用数据流的方式来访问该缓冲。而且如果硬件不提供主缓冲,你就不能直接的访问它了(其实是访问DX软件仿真的主缓冲);你应该调用IDirectSoundBuffer::GetCaps方法来检查DSBCAPS结构里是否有DSBCAPS_LOCHARDWARE标志,有才可以设置DSSCL_WRITEPRIMARY合作级别来访问主缓冲。
//写主缓冲时的初始化工作
BOOL AppCreateWritePrimaryBuffer( LPDIRECTSOUND lpDirectSound, LPDIRECTSOUNDBUFFER *lplpDsb, LPDWORD lpdwBufferSize, HWND hwnd )
{
DSBUFFERDESC dsbdesc;