cocos2dx基础篇(17) 音乐音效SimpleAudioEngine
【3.x】
(1)获取单例:sharedEngine() 改为 getInstance()
(2)实现了:音量的调节。
(3)修改了播放音效 playEffect() 的参数:
//
// 现在还不能完全支持所有参数,限制的功能如下:
// 在Samsung Galaxy S2上如果启用了OpenSL那么pitch参数无效;
// 在emscrippten, win32, marmalade上pitch/pan/gain参数无效
virtual unsigned int playEffect (
const char* pszFilePath, // 音效文件的路径
bool bLoop = false, // 是否循环播放,默认为false,不循环
float pitch = 1.0f, // 频率,正常情况下为1.0,在播放时也可以改变该值
float pan = 0.0f, // 声道,范围为-1到1,为-1时表示只有左声道,为1时表示只有右声道
float gain = 1.0f // 音量增益, 范围为0到1,默认值为1
)
//
【SimpleAudioEngine】
音乐音效是每个游戏中不可或缺的部分,一个好的声音会给玩家留下深刻的印象,当一听到游戏的声音,就会不自觉得说出游戏的名称来。就像《中国好声音》一样,笔者对那首《斑马,斑马》印象就非常深刻,当然唱这首歌的那个妹子也不错。
好了,不扯了,继续学习……
1、音乐音效介绍
声音分为两类:背景音乐、音效。
(1)背景音乐:一般是贯穿整个游戏的音乐,时间长、重复次数少。
(2)音效: 一般是很短的那种声音特效,如砍杀、爆炸、走路等,短暂但使用比较频繁。
cocos2dx是一个跨平台的游戏引擎,它支持多种声音格式(比如MP3、WAV等)。可是呢,对于不同的平台,声音的格式可不一定是统一的。这就需要大家根据不同的平台,选择合适的声音格式了。
根据两种声音的特点,其采用的声音格式也有所不同。以下列出各平台所推荐的声音格式(当然并不是全部支持的格式,如IOS中背景音乐除了MP3和CAF外,还可以使用AAC、AMR等等)。
背景音乐 | 音效 | |
Win32 | MP3、MID、WAV | MID、WAV |
Android | MP3、MID、WAV | OGG |
IOS | MP3、CAF | CAF |
由此可见,背景音乐最适合的选择是MP3格式。虽然音效也可以使用MP3格式,但是MP3是一种有损的压缩格式,而音效多数是短暂而快速的声响,有损的压缩方式可能导致有些采样音源消失,故音效不推荐使用MP3格式。而每个平台的音效格式均不相同,故需要根据不同平台,选用合适的格式。
2、SimpleAudioEngine
cocos2dx为我们提供了声音模块CocosDenshion。而其中有个SimpleAudioEngine类,是我们学习研究的对象。
使用SimpleAudioEngine时需要引入头文件和命名空间:
//
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
//
SimpleAudioEngine和CCDirector一样,也是一个单例类。说的通俗一点,它就是一个全局静态类。第一次调用时会创建一个全局静态对象,整个游戏的运行过程中会一直存在,全局都可以访问。
3、获取单例对象
SimpleAudioEngine的单例对象获取方法:
//
//通过SimpleAudioEngine::sharedEngine()获得
static SimpleAudioEngine* sharedEngine();
//
4、背景音乐的函数
相关操作:预加载、播放、停止、暂停、恢复、重播,以及设置音量等。
//
void preloadBackgroundMusic('音乐路径const char*'); //预加载
void playBackgroundMusic('音乐路径const char*', bool bLoop = false); //播放,是否循环,默认不循环
void stopBackgroundMusic(bool bReleaseData = false); //停止,是否释放音乐资源
void pauseBackgroundMusic(); //暂停
void resumeBackgroundMusic(); //恢复
void rewindBackgroundMusic(); //重播
//返回是否将要播放背景音乐
bool willPlayBackgroundMusic();
//返回是否正在播放背景音乐
//注意:暂停也算正在播放,只有停止了才算未播放。
bool isBackgroundMusicPlaying();
//设置音量,取值范围0~1.0
//查看了内部源码,发现音量的设置没有实现,即音量永远是1.0
float getBackgroundMusicVolume();
void setBackgroundMusicVolume(float volume);
//
5、音效的函数
相关操作:预加载、播放、停止、暂停、恢复、卸载,以及设置音量等。
//
void preloadEffect('音乐路径const char*'); //预加载
unsigned int playEffect('音乐路径const char*', bool bLoop = false); //播放,返回该音效的ID。是否循环
void stopEffect(unsigned int nSoundId); //停止指定ID的音效
void stopAllEffects(); //停止所有音效
void pauseEffect(unsigned int nSoundId); //暂停指定ID的音效
void pauseAllEffects(); //暂停所有音效
void resumeEffect(unsigned int nSoundId); //恢复指定ID的音效
void resumeAllEffects(); //恢复所有音效
void unloadEffect(const char* pszFilePath); //卸载音效资源
//设置音量,取值范围0~1.0
//查看了内部源码,发现音量的设置没有实现,即音量永远是1.0
float getEffectsVolume();
void setEffectsVolume(float volume);
//
6、关于预加载
加载音乐和音效通常是一个耗时的过程,为了防止由即时加载产生的延迟导致实际播放与游戏不协调的现象发生,在播放音效和背景音乐之前,记得要预加载音乐文件preload。另外需要根据不同的平台,选择不同的预加载音乐格式。
具体操作如下:
其中MUSIC_FILE就是音乐文件相对Resources文件夹的相对路径下的文件名。
//
/**
* 根据平台选择音乐音效的格式
*/
//音效文件
//Android平台只支持OGG的音效格式
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#define EFFECT_FILE "music/effect2.ogg"
#elif( CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
#define EFFECT_FILE "music/effect1.raw"
#else
#define EFFECT_FILE "music/effect1.wav"
#endif
//音乐文件
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#define MUSIC_FILE "music/music.mid"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX )
#define MUSIC_FILE "music/background.ogg"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
#define MUSIC_FILE "music/background.wav"
#else
#define MUSIC_FILE "music/background.mp3"
#endif
/**
* 预加载音乐音效
*/
//加载背景音乐
SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic(MUSIC_FILE);
//加载音效
SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic(EFFECT_FILE);
//
7、关于音量调节
我在测试调节音量大小的时候,惊人的发现:cocos2dx中的音量设置没有实现,即使你设置了音量大小也没用,它永远都是1.0。所以要想调节音量大小,还是通过设置系统的音量吧……
PS:在V3.x中已经实现了音量的调节。
源码如下:
//
float SimpleAudioEngine::getBackgroundMusicVolume()
{
return 1.0;
}
void SimpleAudioEngine::setBackgroundMusicVolume(float volume)
{
}
float SimpleAudioEngine::getEffectsVolume()
{
return 1.0;
}
void SimpleAudioEngine::setEffectsVolume(float volume)
{
}
//
8、使用技巧
(1)通过SimpleAudioEngine::sharedEngine()获取单例对象,然后调用相关函数。
(2)当退出程序时,记得要通过如下函数来释放单例对象,释放所有声音资源。
//
SimpleAudioEngine::sharedEngine()->end()
//
(3)加载音乐和音效通常是一个耗时的过程,为了防止由即时加载产生的延迟导致实际播放与游戏不协调的现象发生,在播放音效和背景音乐之前,记得要预加载音乐文件preload。
【代码实战】
代码来源于cocos2dx的官方项目TestCpp中。
1、资源文件
将音乐音效文件资源放在项目的“Resources\music”目录下。
资源来自官方项目TestCpp中。
2、引入头文件和命名空间
//
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
//
3、预加载音乐音效
//
/**
* 根据平台选择音乐音效的格式
*/
//音效文件
//Android平台只支持OGG的音效格式
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#define EFFECT_FILE "music/effect2.ogg"
#elif( CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
#define EFFECT_FILE "music/effect1.raw"
#else
#define EFFECT_FILE "music/effect1.wav"
#endif
//音乐文件
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#define MUSIC_FILE "music/music.mid"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX )
#define MUSIC_FILE "music/background.ogg"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
#define MUSIC_FILE "music/background.wav"
#else
#define MUSIC_FILE "music/background.mp3"
#endif
/**
* 预加载音乐音效
*/
//加载背景音乐
SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic(MUSIC_FILE);
//加载音效
SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic(EFFECT_FILE);
//
4、创建控制音乐音效的菜单按钮
用菜单按钮来控制音乐的播放、暂停、停止、恢复等。
//
//创建控制音乐音效的菜单按钮
std::string testItems[] = {
"play background music",
"stop background music",
"pause background music",
"resume background music",
"rewind background music",
"is background music playing",
"play effect",
"play effect repeatly",
"stop effect",
"pause effect",
"resume effect",
"pause all effects",
"resume all effects",
"stop all effects",
"unload effect",
"add background music volume",
"sub background music volume",
"add effects volume",
"sub effects volume"
};
//创建菜单
CCMenu* pMenu = CCMenu::create();
pMenu->setContentSize(CCSizeMake(480,1000));
for (int i = 0; i < 19; ++i)
{
CCLabelTTF* label = CCLabelTTF::create(testItems[i].c_str(), "Arial", 24);
CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(HelloWorld::menuCallback));
pMenuItem->setPosition( ccp(mysize.width/2, 1000 - (i+1)*50 ) );
pMenu->addChild(pMenuItem, 0, i);
}
//将菜单作为容器,放入滚动视图中
CCScrollView* scrollView = CCScrollView::create(CCSizeMake(480, 320), pMenu);
scrollView->setDirection(kCCScrollViewDirectionVertical);
scrollView->setPosition(CCPointZero);
pMenu->setPosition( ccp(0, 320-1000) );
this->addChild(scrollView);
//
5、编写菜单按钮回调函数
根据点击的菜单项Tag,来控制音乐音效。
//
void HelloWorld::menuCallback(CCObject* sender)
{
//获取菜单按钮编号
int idx = ((CCMenuItem*)sender)->getTag();
switch(idx)
{
//音乐控制
case 0: SimpleAudioEngine::sharedEngine()->playBackgroundMusic(MUSIC_FILE, true); break; //播放音乐,循环
case 1: SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(); break; //停止音乐
case 2: SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); break; //暂停音乐
case 3: SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); break; //恢复音乐
case 4: SimpleAudioEngine::sharedEngine()->rewindBackgroundMusic(); break; //重播音乐
case 5:
if (SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying()) //是否正在播放背景音乐
{
CCLOG("background music is playing");
}
else
{
CCLOG("background music is not playing");
}
break;
//音效控制
case 6: m_soundID = SimpleAudioEngine::sharedEngine()->playEffect(EFFECT_FILE); break; //播放音效,不循环
case 7: m_soundID = SimpleAudioEngine::sharedEngine()->playEffect(EFFECT_FILE, true); break; //播放音效,循环
case 8: SimpleAudioEngine::sharedEngine()->stopEffect(m_soundID); break; //停止指定ID的音效
case 9: SimpleAudioEngine::sharedEngine()->pauseEffect(m_soundID); break; //暂停指定ID的音效
case 10: SimpleAudioEngine::sharedEngine()->resumeEffect(m_soundID); break; //恢复指定ID的音效
case 11: SimpleAudioEngine::sharedEngine()->pauseAllEffects(); break; //暂停所有音效
case 12: SimpleAudioEngine::sharedEngine()->resumeAllEffects(); break; //恢复所有音效
case 13: SimpleAudioEngine::sharedEngine()->stopAllEffects(); break; //停止所有音效
case 14: SimpleAudioEngine::sharedEngine()->unloadEffect(EFFECT_FILE); break; //卸载音效
//音量控制
case 15:
SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(SimpleAudioEngine::sharedEngine()->getBackgroundMusicVolume() + 0.1f);
break;
case 16:
SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(SimpleAudioEngine::sharedEngine()->getBackgroundMusicVolume() - 0.1f);
break;
case 17:
SimpleAudioEngine::sharedEngine()->setEffectsVolume(SimpleAudioEngine::sharedEngine()->getEffectsVolume() + 0.1f);
break;
case 18:
SimpleAudioEngine::sharedEngine()->setEffectsVolume(SimpleAudioEngine::sharedEngine()->getEffectsVolume() - 0.1f);
break;
}
}
//
6、运行结果
声音不是视觉效果,所以自己实现代码后,玩耍去吧!
cocos2dx基础篇(17) 音乐音效SimpleAudioEngine的更多相关文章
- cocos2dx基础篇(3) 常用重要类
---------------------------------------- 入口类main.cpp 主要控制类AppDelegate.cpp -------------------------- ...
- 【Cocos2d入门教程二】Cocos2d-x基础篇
上一章已经学习了环境的搭建.这一章对基础概念进行掌握.内容大概有: 1.导演 2.场景 3.节点 4.层 4.精灵 1.导演(Director) 导演存在的主要作用: a.环境设定(帧率 初始化ope ...
- cocos2dx基础篇(26) 单例模式
单例模式,说的通俗一点就是:创建某个类的全局唯一静态实例对象.也就是说从它创建开始,一直到整个游戏程序结束才会释放资源,期间一直保存的着数据. 单例类在大部分游戏中应该是必不可少的部分,如整个游戏音乐 ...
- 2000条你应知的WPF小姿势 基础篇<1-7>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师,对C#和WPF有着极深的热情.最为出色的是他维护了两个博客:2,000Things You Should Know ...
- 从零开始之ecshop基础篇(17)
目标:基于自定义的mvc框架开发的案例(项目) 项目周期 需求分析 典型的业务逻辑: 电子商务:商城(京东),B2C,C2C(淘宝),团购,秒杀,代购 内容管理:新浪门户类,优酷视频管理, ...
- cocos2dx基础篇(23) 粒子系统CCParticleSystem
[3.x] (1)去掉"CC" (2)粒子位置模式 tPositionType 改为强枚举类型 ParticleSystem::PositionType:: // ...
- cocos2dx基础篇(22) 基本动画CCAnimation/CCAnimate
[小知识] CCSpriteFrame :精灵帧. 它是相对动画而产生的,其实就是一张纹理图片. CCAnimationFrame :动画帧. 由精灵帧与间隔帧数组成,是动画CC ...
- cocos2dx基础篇(18) 数据存储CCUserDefault
在cocos2dx中提供了一个数据存储类CCUserDefault,可以作为一个轻量级的数据库来使用.它支持五种数据bool.int.float.double.string的存储. [3.x] ...
- cocos2dx基础篇(15) 列表视图CCTableView
[3.x] (1)去掉 "CC" (2)TableViewCell 中: > unsigned int getIdx() 返回类型改为 ssize_t(类型为 long) ( ...
随机推荐
- 探索super()的执行顺序和__mro__方法
class Base(object): def func(self): print('Base.func') class Foo(Base): def func(self): # 方式一:根据mro的 ...
- outlook 使用临时邮箱 使用旧数据
控制面板-->邮件32位 显示配置文件 删除再添加 具体可参考 https://blog.csdn.net/liuyukuan/article/details/80043840 偷懒,图片从网上 ...
- Maven灵活构建(转载)
https://blog.csdn.net/sin90lzc/article/details/7552033
- mac安装测试myCat
参考博文https://www.cnblogs.com/chanshuyi/p/head_first_of_mycat.html 1.下载解压mycat的mac版(位置不限) 2.cd进bin文件 ...
- mysql存储ip数值
字段使用 int unsigned 类型就可以满足存贮ip2long(ip)的数值 插入时,可以使用inet_aton('100.200.30.22') 将ip地址转换为数值 查询时,使用inet_n ...
- html button标签 语法
html button标签 语法 button标签怎么用? 作用:定义一个按钮. 语法:<button type="button">按钮</button> ...
- Lucene实践:全文检索的基本原理
一.总论 根据http://lucene.apache.org/java/docs/index.html 定义: "Apache Lucene(TM) is a high-performan ...
- 【BZOJ2409】 地下车会
Description 小Y喜欢速度与激情,于是他参加了地下车会. 地下车会设有N 个分赛区,M种赛事.每个分赛区有C[i]场比赛.由于地下车会经营者想要赚到更多的钱,规定小 Y 必须参加某一些赛区 ...
- CentOS查看进程端口号以及kill操作
查看端口: 使用 netstat -anp | grep 8090即:netstat –apn | grep 8090 查看进程:1.ps 命令用于查看当前正在运行的进程,grep 是 ...
- springboot集成fastjson
@Configuration @EnableWebMvc public class WebMvcConfigurer extends WebMvcConfigurerAdapter { /** * f ...