cocos2dx[2.x](14)--音樂音效SimpleAudioEngine

【嘮叨】

本節比較簡單,主要講講cocos2dx引擎中的音樂音效SimpleAudioEngine。

【致謝】
http://gl.paea.cn/contents/f86d1f6e2a52e7ea.html

【小知識】

單例類:說的通俗一點,它就是一個全局靜態類。第一次調用時會創建一個全局靜態對象,整個遊戲的運行過程中會一直存在,全局都可以訪問。

【Demo下載】
https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E9%9F%B3%E4%B9%90%E9%9F%B3%E6%95%88SimpleAudioEngine

【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
    )
(4)其他變化不大。

【SimpleAudioEngine】

音樂音效是每個遊戲中不可或缺的部分,一個好的聲音會給玩家留下深刻的印象,當一聽到遊戲的聲音,就會不自覺得說出遊戲的名稱來。就像《中國好聲音》一樣,筆者對那首《斑馬,斑馬》印象就非常深刻,當然唱這首歌的那個妹子也不錯。i_f32.gif

好了,不扯了,繼續學習……

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。t_0012.gif所以要想調節音量大小,還是通過設置系統的音量吧……

    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、運行結果

    聲音不是視覺效果,所以自己實現代碼後,玩耍去吧!

這裏寫圖片描述
轉載網址:http://blog.51cto.com/shahdza/1545820

發佈了7 篇原創文章 · 獲贊 1 · 訪問量 7421
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章