消灭星星游戏程序设计【连载十一】——在线程中解决音效卡顿问题
大家每次都可以在页面中下载本节内容的实现代码,一步一步从简单开始,逐步完成游戏的各种功能,如果大家有任何问题也欢迎留言交流。
游戏整体效果展示:
1、本节要达到的效果
前面的章节,我们添加了小星星爆炸时的音效,游戏效果得到了极大的提升。但是我们现在又发现一个新的问题,每次在播放爆炸音效时,小星星在移动时都会出现卡顿的情况。而且这种卡顿的情况影响比较严重,计算机在图片的显示上显卡处理的速度非常快不会有问题,问题就出在音效的播放上,所以这个声音播放的卡顿问题亟待解决。
2、用线程去解决音效卡顿
这里我们就到线程的概念,因为我们每次声音的播放只存在刚刚开始时0.0几秒的卡顿,从耳朵听是听不出来差别,但从视觉上就会感觉到图像动画不连续的问题。因此,我们在线程中处理声音,声音播放卡顿是在线程中卡顿,卡顿的0.0几秒它不会影响到游戏效果,最主要的主程序中图像效果不会受到声音播放卡顿的影响,可以完美解决问题。
3、线程的具体操作
要使用线程,我们需要做的就是在主程序中创建一个线程,这个线程我们需要通过创建函数告诉需要程序,在线程中运行的一个自定义循环操作函数,然后我们根据自己的需求,在这个循环函数中完成声音的操作。
//定义全局线程对象,用以管理、操作音效资源
HANDLE hMusicThread=NULL;
//定义全局线程同步对象,用以使用线程时确保音效资源数组有效操作
HANDLE hMusicMutex=NULL;
case WM_CREATE:
......
//在线程中处理音效的加载、播放、设置、删除
hMusicThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)GameMusicThread,NULL,0,0);
//创建线程同步对象,使用互斥对象保证同一时刻只允许一个线程操作音效资源数组
hMusicMutex=CreateMutex(NULL,FALSE,NULL);
......
同时需要自定义一个循环操作函数,并在这个循环体内处理我们需要音乐的操作。这里我们要注意一个问题,加入线程后,所有的声音操作,有声音的加载、播放、暂停、卸载操作必须要全部在线程中处理。不能出现在主程序中加载声音,在线程中播放声音的操作,这样的操作也是播放不出来声音的。因此我们对声音的实质性操作必须放在线程中。简单一点说,音乐的加载、播放、停止操作必须在这个线程函数中处理。这里使用了CreateMutex和WaitForSingleObject和ReleaseMutex函数,主要是为了解决不同线程中避免同时对某些变量进行操作而导致的操作冲突。
//在线程中处理音效的加载、播放、设置、删除
void GameMusicThread()
{
//进入处理音效的循环
while(true)
{
//锁定音效资源数组操作
WaitForSingleObject(hMusicMutex,INFINITE);
//在线程中自动处理音效的各种操作,包括加载、播放、停止等操作
......
//关闭锁定音效资源数组操作
ReleaseMutex(hMusicMutex);
//防止系统过载运行
Sleep(1);
}
}
4、线程中音效资源的操作
为了能够统一操作音效资源,我们采用一个指针数组来存储所有的Music类指针,方便统一操作。同时在Music类的构造函数中自动将指针保存到指针数组中,省去了后期逐个添加音效指针到数组中的重复操作。
//设置所有的音乐类的最大个数
#define MUSICSAVERMAXNUM 30
//保存所有的音乐类,便于统一管理
Music *ptMusicSaver[MUSICSAVERMAXNUM