游戏音乐与音效的播放

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;

相关文档
最新文档