玩游戏的时候,背景音乐和音效能够使一款游戏增添不少色彩。
背景音乐:时间相对比较长,同一时间内只能播放一首背景音乐。
音效:时间相对比较短,同一时间内可以播放多个音效。
不管是音乐还是音效,cocos2d-x中都采用SimpleAudioEngine类实现跨平台的声音引擎。
关于背景音乐,cocos2d-x 在不同平台下所支持的格式如下:
平台名称 支持类型
Android android.media.MediaPlayer类支持的格式,包括MP3、WAV和3GP
iOS cocos2d-iPhone中cocosDenshion支持的类型,推荐MP3和CAF
Win32 MID和WAV
函数名 返回类型 描述
preloadBackgroundMusic 空 预加载背景音乐
playBackgroundMusic 空 播放背景音乐
stopBackgroundMusic 空 停止背景音乐
pauseBackgroundMusic 空 暂停背景音乐
resumeBackgroundMusic 空 重新开始背景音乐
rewindBackgroundMusic 空 回放背景音乐
willPlayBackgroundMusic 布尔型 是否会播放背景音乐
isBackgroundMusicPlaying 布尔型 是否正播放背景音乐
getBackgroundMusicVolume 浮点型 获得背景音乐音量
setBackgroundMusicVolume 空 设置背景音乐音量
平台名称 支持类型
Android 对应OGG格式支持最好,同时支持WAV格式
iOS cocos2d-iPhone中cocosDenshion支持的类型,推荐CAF
Win32 MID和WAV
函数名 返回类型 描述
getEffectsVolume 浮点型 获得音效音量
setEffectsVolume 空 设置音效音量
playEffect 整型 播放音效,参数为文件路径和是否循环
pauseEffect 空 暂停音效,参数为播放时获得的ID号
pauseAllEffects 空 暂停所有音效
resumeEffect 空 开始音效,参数为播放时获得的ID号
resumeAllEffects 空 开始所有音效
stopEffect 空 停止音效,参数为播放时获得的ID号
stopAllEffects 空 停止所有音效
preloadEffect 空 预加载音效
unloadEffect 空 将预加载的音效从缓存中删除
备注:预加载音乐和音效能够提高程序的执行效率,但是这样也会增加内存的占用。所以,在实际使用时,要根据项目特点来平衡效率和内存压力的问题。
相信源码就是最好的教材了,以下实例来自源码。
运行TestCpp,打开CocosDenshionTest,界面如下:
你可以一个个试试,然后再品尝以下原滋原味的代码,相信会有不少的收获。源码如下:
#ifndef __COCOS_DENSHION_TEST__ #define __COCOS_DENSHION_TEST__ #include "../testBasic.h" class CocosDenshionTest : public CCLayer { public: CocosDenshionTest(void); ~CocosDenshionTest(void); void menuCallback(CCObject * pSender); virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); virtual void onExit(); private: CCMenu* m_pItmeMenu; CCPoint m_tBeginPos; int m_nTestCount; unsigned int m_nSoundId; }; class CocosDenshionTestScene : public TestScene { public: virtual void runThisTest(); }; #endif //__COCOS_DENSHION_TEST__
#include "CocosDenshionTest.h" #include "cocos2d.h" #include "SimpleAudioEngine.h" // android effect only support ogg #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #define EFFECT_FILE "effect2.ogg" #elif( CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE) #define EFFECT_FILE "effect1.raw" #else #define EFFECT_FILE "effect1.wav" #endif // CC_PLATFORM_ANDROID #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #define MUSIC_FILE "music.mid" #elif (CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX ) #define MUSIC_FILE "background.ogg" #elif (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) #define MUSIC_FILE "background.wav" #else #define MUSIC_FILE "background.mp3" #endif // CC_PLATFORM_WIN32 USING_NS_CC; using namespace CocosDenshion; #define LINE_SPACE 40 CocosDenshionTest::CocosDenshionTest() : m_pItmeMenu(NULL), m_tBeginPos(CCPointZero), m_nSoundId(0) { 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", "unload effect", "add background music volume", "sub background music volume", "add effects volume", "sub effects volume", "pause effect", "resume effect", "pause all effects", "resume all effects", "stop all effects" }; // add menu items for tests m_pItmeMenu = CCMenu::create(); m_nTestCount = sizeof(testItems) / sizeof(testItems[0]); for (int i = 0; i < m_nTestCount; ++i) { //#if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE) // CCLabelBMFont* label = CCLabelBMFont::create(testItems[i].c_str(), "fonts/arial16.fnt"); //#else CCLabelTTF* label = CCLabelTTF::create(testItems[i].c_str(), "Arial", 24); //#endif CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(CocosDenshionTest::menuCallback)); m_pItmeMenu->addChild(pMenuItem, i + 10000); pMenuItem->setPosition( ccp( VisibleRect::center().x, (VisibleRect::top().y - (i + 1) * LINE_SPACE) )); } m_pItmeMenu->setContentSize(CCSizeMake(VisibleRect::getVisibleRect().size.width, (m_nTestCount + 1) * LINE_SPACE)); m_pItmeMenu->setPosition(CCPointZero); addChild(m_pItmeMenu); setTouchEnabled(true); // preload background music and effect SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic( MUSIC_FILE ); SimpleAudioEngine::sharedEngine()->preloadEffect( EFFECT_FILE ); // set default volume SimpleAudioEngine::sharedEngine()->setEffectsVolume(0.5); SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(0.5); } CocosDenshionTest::~CocosDenshionTest() { } void CocosDenshionTest::onExit() { CCLayer::onExit(); SimpleAudioEngine::sharedEngine()->end(); } void CocosDenshionTest::menuCallback(CCObject * pSender) { // get the userdata, it's the index of the menu item clicked CCMenuItem* pMenuItem = (CCMenuItem *)(pSender); int nIdx = pMenuItem->getZOrder() - 10000; switch(nIdx) { // play background music case 0: SimpleAudioEngine::sharedEngine()->playBackgroundMusic(MUSIC_FILE, true); break; // stop background music case 1: SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(); break; // pause background music case 2: SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); break; // resume background music case 3: SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); break; // rewind background music case 4: SimpleAudioEngine::sharedEngine()->rewindBackgroundMusic(); break; // is background music playing case 5: if (SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying()) { CCLOG("background music is playing"); } else { CCLOG("background music is not playing"); } break; // play effect case 6: m_nSoundId = SimpleAudioEngine::sharedEngine()->playEffect(EFFECT_FILE); break; // play effect case 7: m_nSoundId = SimpleAudioEngine::sharedEngine()->playEffect(EFFECT_FILE, true); break; // stop effect case 8: SimpleAudioEngine::sharedEngine()->stopEffect(m_nSoundId); break; // unload effect case 9: SimpleAudioEngine::sharedEngine()->unloadEffect(EFFECT_FILE); break; // add bakcground music volume case 10: SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(SimpleAudioEngine::sharedEngine()->getBackgroundMusicVolume() + 0.1f); break; // sub backgroud music volume case 11: SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(SimpleAudioEngine::sharedEngine()->getBackgroundMusicVolume() - 0.1f); break; // add effects volume case 12: SimpleAudioEngine::sharedEngine()->setEffectsVolume(SimpleAudioEngine::sharedEngine()->getEffectsVolume() + 0.1f); break; // sub effects volume case 13: SimpleAudioEngine::sharedEngine()->setEffectsVolume(SimpleAudioEngine::sharedEngine()->getEffectsVolume() - 0.1f); break; case 14: SimpleAudioEngine::sharedEngine()->pauseEffect(m_nSoundId); break; case 15: SimpleAudioEngine::sharedEngine()->resumeEffect(m_nSoundId); break; case 16: SimpleAudioEngine::sharedEngine()->pauseAllEffects(); break; case 17: SimpleAudioEngine::sharedEngine()->resumeAllEffects(); break; case 18: SimpleAudioEngine::sharedEngine()->stopAllEffects(); break; } } void CocosDenshionTest::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) { CCSetIterator it = pTouches->begin(); CCTouch* touch = (CCTouch*)(*it); m_tBeginPos = touch->getLocation(); } void CocosDenshionTest::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) { CCSetIterator it = pTouches->begin(); CCTouch* touch = (CCTouch*)(*it); CCPoint touchLocation = touch->getLocation(); float nMoveY = touchLocation.y - m_tBeginPos.y; CCPoint curPos = m_pItmeMenu->getPosition(); CCPoint nextPos = ccp(curPos.x, curPos.y + nMoveY); if (nextPos.y < 0.0f) { m_pItmeMenu->setPosition(CCPointZero); return; } if (nextPos.y > ((m_nTestCount + 1)* LINE_SPACE - VisibleRect::getVisibleRect().size.height)) { m_pItmeMenu->setPosition(ccp(0, ((m_nTestCount + 1)* LINE_SPACE - VisibleRect::getVisibleRect().size.height))); return; } m_pItmeMenu->setPosition(nextPos); m_tBeginPos = touchLocation; } void CocosDenshionTestScene::runThisTest() { CCLayer* pLayer = new CocosDenshionTest(); addChild(pLayer); pLayer->autorelease(); CCDirector::sharedDirector()->replaceScene(this); }