音频播放是一个游戏不可或缺的部分,优质的音乐和特效可以把游戏的质量整体上升一个层次。播放声音的方法很多,Windows 本身就支持简单的声音播放,但是如果想要更高级的特效,就需要专门的音效引擎了。教程的目标是实现 C语言小游戏的开发 ,所以音频播放的要求要低很多,主要包括两个方面:

  • 音乐。主要是只背景音乐,通常这种音乐的播放时间都会很长,甚至贯穿整个游戏的始终。

  • 音效。这种声音一般都是很短的音频,这种音效主要是用来做一些提示,是交互的一种补充形式。

1. PlaySound

在 Windows 默认 API 中有一个叫做 PlaySound 的接口,它可以播放一个指定的声音文件。函数的原型如下:

BOOL PlaySound(
   LPCTSTR pszSound,
   HMODULE hmod,
   DWORD   fdwSound
);

参数 pszSound 用来指定需要播放的声音,该参数是一个字符串类型,本身根据 fdwSound 标识的不同,会表示不同的含义。例如当 fdwSound 包含 SND_FILENAME 标识时,pszSound 表示要播放的文件路径;当 fdwSound 包含 SND_RESOURCE 时,pszSound 代表资源标识。

参数 hmod 一般为 NULL,只有当 fdwSound 包含 SND_RESOURCE 标识时,该参数为声音资源句柄。

最后一个参数用来存放标识位,不同的标识位有不同的含义,它们可以按位组合到一起,例如:SND_ASYNC | SND_FILENAME 标识异步播放声音文件。

虽然用这个函数可以播放声音,但是它却有一个致命的缺陷,无法同时播放多个声音文件。大多数的时候,我们并不需要同时播放多个音效,但是却需要一边播放背景音乐,一边播放音效,显然仅用 PlaySound 无法满足我们的要求。这时候就需要再引入一个 API 接口播放背景音乐。

2. mciSendString

mciSendString 是 Windows 中用来播放多媒体文件的接口,其中 mci 代表 Media Control Interface。mciSendString 使用方法非常神奇,主要是一种发送命令的方式执行。函数原型如下:

MCIERROR mciSendString(
   LPCTSTR lpszCommand,
   LPTSTR  lpszReturnString,
   UINT    cchReturn,
   HANDLE  hwndCallback
);

lpszCommand 表示要执行的命令,后三个参数一般直接传 NULL 或者 0。例如我要播放一个 sound.wav 文件,则直接将 lpszCommand 填充为 play 命令:

mciSendString(TEXT("play sound.wav"), NULL, 0, NULL);

其中的命令包含很多中,可以在 MSDN 中查找相应的选项。