要是能为自己的游戏添加上动人的背景音乐和音效,无疑能提升不少游戏体验,不至于让玩家感觉毫无代入感。
今天我来讲一下世嘉MD游戏开发怎么运用音乐和音效。
我自己也是慢慢摸索的,说的不全面也是情理之中的,但是能满足最基本的需求。
世嘉MD的音频通道有4个通道,背景音乐默认用第一个通道,音效最好是用2,3, 4这三个通道,我一开始不懂音频播放原理,播放音效的时候总是把音乐覆盖掉,后来才摸索出来,原来要活用声音通道才行。
代码里定义的声音通道如下:
#define SOUND_PCM_CH1 Z80_DRV_CH0_SFT#define SOUND_PCM_CH2 Z80_DRV_CH1_SFT#define SOUND_PCM_CH3 Z80_DRV_CH2_SFT#define SOUND_PCM_CH4 Z80_DRV_CH3_SFT
用的时候也很简单,背景音乐不需要事先设置,先来说一下怎么设置音效吧,主要是下面的这个函数:
/*** \简介* 为XGM音乐播放器驱动程序声明一个新的PCM示例(最大值 = 255)。* 小于64的数保留用于音乐,大于等于64的用于SFX音效* 因此,如果要声明新的SFX PCM音效,请使用id>= 64** \参数 id* 不允许id为0* 1-63用于音乐* 64-255用于音效** \参数 sample* //我也不懂啥意思* Sample address, should be 256 bytes boundary aligned* //看懂这一句就可以了,SGDK自动给你处理* SGDK automatically align sample resource as needed** \参数 len* //size必须是256的整数倍* Size of sample in bytes, should be a multiple of 256* //不用担心,SGDK自动给你处理* SGDK automatically adjust resource size as needed* 用sizeof()获取音效的长度*/
void XGM_setPCM(const u8 id, const u8 *sample, const u32 len);
播放音乐就很简单了,用如下函数:
void XGM_startPlay(const u8 *song);
播放音效的时候用以下函数:
/*** \简介* 在指定的声道上播放PCM音频,仅用于XGM音乐驱动.* 如果当前声道正在播放PCM音频,则比较样本的优先级,根据优先级确定是否替换播放新的音效* 注意:音乐使用通道1,最好用通道2-4播放音效** \参数 id* Sample id (set #XGM_setPCM method)** \参数 priority* 值的范围是0-15,0优先级最低,15优先级最高。* \参数 channel* #SOUND_PCM_CH1 = channel 1 (通常用于音乐)* #SOUND_PCM_CH2 = channel 2* #SOUND_PCM_CH3 = channel 3* #SOUND_PCM_CH4 = channel 4*/
void XGM_startPlayPCM(const u8 id, const u8 priority, const u16 channel);
SGDK的资源文件都是要事先写在一个.res文件中的,详情见:SGDK\bin\rescomp.txt,里面定义了各种资源的书写规则,要严格按照规则写,不然会报错。所以我们用到的声音文件我是这么处理的,我把所有资源都放到res目录里,新建resources.res文件,在里面写上如下代码:
XGM music "GTR Attack!.vgm" 0WAV sound1 "sound1.wav" 5
WAV sound2 "sound2.wav" 5
WAV sound3 "sound3.wav" 5
WAV sound4 "sound4.wav" 5
这样就算声明了一个XGM格式的音乐,叫music。
声明了一个WAV格式的音乐,叫sound1,依次类推。
逻辑部分的代码如下:
/*播放背景音乐的同时还可以播放音效
*/#include <genesis.h>
#include <vdp.h>
#include "resources.h"//用来标记音乐是否播放了
bool startPlay = FALSE;//按键输入事件,前面有讲过
void inputHandle(u16 joy, u16 changed, u16 state)
{//changed & state & BUTTON_START 意思就是刚按下的时候,不是连发的那种,只触发一次//START键播放或者暂停音乐if (changed & state & BUTTON_START){if (startPlay == FALSE){XGM_startPlay(music);startPlay = TRUE;}else if (startPlay){if (XGM_isPlaying())XGM_pausePlay();elseXGM_resumePlay();}}//ABCX键分别播放对应的音效if (changed & state & BUTTON_A){XGM_startPlayPCM(64, 1, SOUND_PCM_CH2);}if (changed & state & BUTTON_B){XGM_startPlayPCM(65, 2, SOUND_PCM_CH3);}if (changed & state & BUTTON_C){XGM_startPlayPCM(66, 3, SOUND_PCM_CH4);}if (changed & state & BUTTON_X){XGM_startPlayPCM(67, 4, SOUND_PCM_CH2);}
}int main()
{VDP_drawText("Music & Sound", 0, 0);{ //设置音效的IDXGM_setPCM(64, sound1, sizeof(sound1));XGM_setPCM(65, sound2, sizeof(sound2));XGM_setPCM(66, sound3, sizeof(sound3));XGM_setPCM(67, sound4, sizeof(sound4));}JOY_setEventHandler(inputHandle);while (TRUE){VDP_waitVSync();}return 0;
}
至于XGM音乐文件(.vgm格式)从何而来呢,我推荐大家一个制作这种音乐的软件,叫做DefleMask,有兴趣的可以去研究一下,这就是另一个知识领域了。
电脑端可以看到工程文件的下载入口,大家可以自行下载工程文件。