您的位置:首页 > 移动开发 > Cocos引擎

【amazing cocos2d-x 3.0之十九】游戏的背景音乐和音效

2014-04-13 15:51 295 查看
玩游戏的时候,背景音乐和音效能够使一款游戏增添不少色彩。

背景音乐:时间相对比较长,同一时间内只能播放一首背景音乐。

音效:时间相对比较短,同一时间内可以播放多个音效。

不管是音乐还是音效,cocos2d-x中都采用SimpleAudioEngine类实现跨平台的声音引擎。

1. 游戏背景音乐

1.1 背景音乐在不同平台下所支持的声音

关于背景音乐,cocos2d-x 在不同平台下所支持的格式如下:

平台名称 支持类型

Android android.media.MediaPlayer类支持的格式,包括MP3、W***和3GP

iOS cocos2d-iPhone中cocosDenshion支持的类型,推荐MP3和CAF

Win32 MID和W***

1.2 背景音乐SimpleAudioEngine类常用的函数

函数名 返回类型 描述

preloadBackgroundMusic 空 预加载背景音乐

playBackgroundMusic 空 播放背景音乐

stopBackgroundMusic 空 停止背景音乐

pauseBackgroundMusic 空 暂停背景音乐

resumeBackgroundMusic 空 重新开始背景音乐

rewindBackgroundMusic 空 回放背景音乐

willPlayBackgroundMusic 布尔型 是否会播放背景音乐

isBackgroundMusicPlaying 布尔型 是否正播放背景音乐

getBackgroundMusicVolume 浮点型 获得背景音乐音量

setBackgroundMusicVolume 空 设置背景音乐音量

2. 游戏音效

2.1 音效在不同平台下所支持的音效格式

平台名称 支持类型

Android 对应OGG格式支持最好,同时支持W***格式

iOS cocos2d-iPhone中cocosDenshion支持的类型,推荐CAF

Win32 MID和W***

2.2 音效SimepleAudioEngine类常用的函数

函数名 返回类型 描述

getEffectsVolume 浮点型 获得音效音量

setEffectsVolume 空 设置音效音量

playEffect 整型 播放音效,参数为文件路径和是否循环

pauseEffect 空 暂停音效,参数为播放时获得的ID号

pauseAllEffects 空 暂停所有音效

resumeEffect 空 开始音效,参数为播放时获得的ID号

resumeAllEffects 空 开始所有音效

stopEffect 空 停止音效,参数为播放时获得的ID号

stopAllEffects 空 停止所有音效

preloadEffect 空 预加载音效

unloadEffect 空 将预加载的音效从缓存中删除

备注:预加载音乐和音效能够提高程序的执行效率,但是这样也会增加内存的占用。所以,在实际使用时,要根据项目特点来平衡效率和内存压力的问题。



3. 实例代码

相信源码就是最好的教材了,以下实例来自源码。

运行TestCpp,打开CocosDenshionTest,界面如下:



你可以一个个试试,然后再品尝以下原滋原味的代码,相信会有不少的收获。源码如下:

CocosDenshionTest.h

#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__


CocosDenshionTest.cpp

#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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: