作者:慧科集团华东校区-朱家聪老师,转载请注明出处及本链接。
游戏背景音乐和音效
在一个完整的游戏中,音频是必不可少的部分,而音频又分为背景音乐和音效两部分。背景音乐指的是在场景中长时间循环播放的音频,会占用比较大的内存空间。同一时间只能播放一个背景音乐。音效指的是在游戏进程中偶尔出现的声音,比如游戏角色执行一个动作时所对应的发出的声音。这种音频相对来说占用更少的时间和内存资源。可以允许有多个音效同时存在。在Cocos2d-x中提供了Audio音频引擎用于对背景音乐和音效的播放管理。
音频文件类型
由于Cocos2d-x是一个跨平台的游戏引擎,所以在游戏中的音频文件也要考虑到多种平台的文件兼容性。而音频文件又可以分为无损格式和有损格式,再考虑到游戏本体容量的时候,就需要对不同格式进行选择。
常用音频文件格式
格式名称 | 特点 |
---|---|
WAV | 目前最流行的无损压缩格式,但是文件体积比较大,不适于移动设备使用。 |
MP3 | 通过MPEG audio layer 3技术,讲音频文件已1:10 甚至1:12的压缩比例压缩成更小体积的文件,具有压缩比例高,损失相对较小的特点,非常适合移动设备使用。 |
WMA | WMA(Windows Media Audio)是微软发布的一款有损压缩格式,常用于Windows平台下。其压缩率和音频质量和MP3不相上下。 |
CAFF | CAFF(Core Audio File Fomat)是苹果在macOS和iOS系统中所使用的有损压缩格式,等价于WMA在Windows中的地位。 |
AIFF | AIFF(Audio Interchange File Fomat)苹果开发的专业音频文件格式,具有1:4的压缩率,专门运用于macOS和iOS系统。 |
MID | MID文件是MIDI(Musical Instrument Digital Interface)格式,即专业音频格式,允许数字合成器和其他设备交换数据。 |
Ogg | OGGVobis,是一种全新的音频压缩格式,类似于MP3等格式。这是一种完全免费,开发,没有专利限制的音频格式。Ogg文件格式可以不断地进行大小和音质的改良,而不影响旧有的编码器和播放器。 |
跨平台音频文件支持性
由于Cocos2d-x可以支持iOS,Android,Windows、Mac和Linux等操作系统。但是不同操作系统中对于音频文件的格式要求又会有不同的区别,所以通过简单整理来总结一下各平台下所支持的音频格式类型。
平台 | 背景音乐播放 | 音效播放 |
---|---|---|
Android | android.media.MediaPlayer | Ogg(推荐)、WAV |
iOS/macOS | MP3、CAFF | CAFF |
Windows | MIDI、WAV、MP3 | MIDI、WAV |
使用Audio引擎播放背景音乐
音频文件预处理
在开始播放音频文件之前,我们需要对音频进行预处理,预处理是对音频文件进行解压等处理。如果不进行预处理,播放的音频则会出现卡顿等情况。在整个程序运行周期中只需要进行一次即可,所以一般我们选择在AppDelegate中对所需要用到的音频进行预处理。
#include "audio/include/SimpleAudioEngine.h"
using namespace CocosDenshion;
bool AppDelegate::applicationDidFinishLaunching() {
// run
director->runWithScene(scene);
//预处理背景音乐音频文件
SimpleAudioEngine::getInstance()->preloadBackgroundMusic("sound/Jazz.mp3");
return true;
}
播放和停止背景音乐
我们可以通过SimpleAudioEngine音频播放引擎来简单的播放操作
//播放背景音乐 第二个参数为是否循环播放
SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Jazz.mp3", true);
//停止播放当前的背景音乐
SimpleAudioEngine::getInstance()->stopBackgroundMusic();
如果在一个游戏中只有一个场景,这个场景中只有一个背景音乐,那么直接在当前场景的init函数中播放背景音乐,在场景的onExit函数中停止播放即可。但是我们的游戏一般都是由多个场景构成的,每个场景都有自己的背景音乐。如何在这些场景切换时合理的控制各个背景音乐的播放和暂停是我们需要研究的内容。
以Scene1跳转到Scene2为例,场景的生命周期如下所示
op1=>operation: Scene2::init
op2=>operation: Scene1::onExitTransitionDidStart
op3=>operation: Scene1::cleanup
op4=>operation: Scene2::onEnter
op5=>operation: Scene1::onExit
op6=>operation: Scene2::onEnterTransitionDidFinish
op1->op2->op3->op4->op5->op6
因为我们在停止当前场景的背景音乐时,使用的是stopBackgroundMusic()
函数,而这个函数会取消当前正在播放的背景音乐。所以对于这样的场景切换时背景音乐的处理需要把握其开始播放和停止播放的时间点。我们可以在一个场景的cleanup()
函数中停止当前场景的背景音乐。在onEnterTransitionDidFinish()
函数中开启当前场景的背景音乐。因为一个游戏中同一时间只有一个背景音乐,所有有些情况下可以不停止当前场景的背景音乐,直接开始背景音乐即可。
暂停和继续背景音乐
通常情况下,我们不会去暂停背景音乐。游戏程序进入后台是一个比较特殊的情况,在游戏进入到后台时一般需要暂停背景音乐的播放。我们可以通过AppDelegate中的函数来监听程序的运行状态。
void AppDelegate::applicationDidEnterBackground() {
//停止动画效果
Director::getInstance()->stopAnimation();
//暂停所有背景音乐
SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
//暂停所有音效
SimpleAudioEngine::getInstance()->pauseAllEffects();
}
void AppDelegate::applicationWillEnterForeground() {
//播放当前动画
Director::getInstance()->startAnimation();
//继续播放背景音乐
SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
//继续播放音效
SimpleAudioEngine::getInstance()->resumeAllEffects();
}
音效的暂停和继续播放
音效的播放和停止操作和背景音乐基本一致,唯一的区别在于音效可以同时存在多个,所以也可以分别控制不同音效暂停和播放。
SimpleAudioEngine *engine = SimpleAudioEngine::getInstance();
//播放第一个音效
auto soundID1 = engine->playEffect("sound/Blip.wav");
//播放第二个音效
auto soundID2 = engine->playEffect("sound/Blip.wav");
//暂停第一个音效
engine->pauseEffect(soundID1);
//停止第二个音效
engine->stopEffect(soundID2);
//继续播放第一个音效
engine->resumeEffect(soundID1);
//停止播放所有音效
engine->stopAllEffects();
//暂停播放所有音效
engine->pauseAllEffects();
//继续播放所有音效
engine->resumeAllEffects();
网友评论