Cocos2d-x3.3RC0 Cpp-test分析之NewAudioEngineDemo

前端之家收集整理的这篇文章主要介绍了Cocos2d-x3.3RC0 Cpp-test分析之NewAudioEngineDemo前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1、.h文件

#ifndef __NewAudioEngineDemo__NewAudioEngineDemo__
#define __NewAudioEngineDemo__NewAudioEngineDemo__

#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include "VisibleRect.h"
#include "audio/include/AudioEngine.h"

USING_NS_CC;
using namespace ui;

class NewAudioEngineDemo : public Scene
{
public:
    CREATE_FUNC(NewAudioEngineDemo);
    virtual bool init();
};

class BaseTest : public Layer
{
public:
    CREATE_FUNC(BaseTest);
    virtual bool init();
    virtual std::string title() const;//主标题
    virtual std::string subtitle() const;//副标题
    virtual void onExit() override;
    
    virtual void restartCallback(Ref* sender);//重新执行当前test
    virtual void nextCallback(Ref* sender);//下一个test
    virtual void backCallback(Ref* sender);//上一个test

    void menuCloseCallback(cocos2d::Ref* pSender);//关闭菜单回调函数
};

class AudioControlTest : public BaseTest
{
public:
    CREATE_FUNC(AudioControlTest);
    virtual ~AudioControlTest();
    virtual bool init();
    virtual void update(float dt);
    virtual std::string subtitle() const override;
private:
    int _audioID;
    bool _loopEnabled;
    float _volume;
    float _duration;
    float _timeRatio;
    
    void* _playItem;
    void* _timeSlider;
    bool _updateTimeSlider;

};

class PlaySimultaneouslyTest : public BaseTest
{
public:
    CREATE_FUNC(PlaySimultaneouslyTest);
    virtual ~PlaySimultaneouslyTest();
    virtual bool init();
    virtual std::string subtitle() const override;
private:
    static const int TEST_COUNT = 10;
    std::string _files[TEST_COUNT];
    void* _playItem;
    int _playingcount;
};

class AudioProfileTest : public BaseTest
{
public:
    CREATE_FUNC(AudioProfileTest);
    virtual bool init();
    virtual ~AudioProfileTest();
    virtual std::string subtitle() const override;
    virtual void update(float dt);
private:
    static const int FILE_COUNT = 2;
    std::string _files[FILE_COUNT];
    cocos2d::experimental::AudioProfile _audioProfile;
    int _audioCount;
    Label* _showLabel;
    float _time;
    float _minDelay;
    void* _timeSlider;
};
class InvalidAudioFileTest : public BaseTest
{
public:
    CREATE_FUNC(InvalidAudioFileTest);
    virtual bool init();
    virtual ~InvalidAudioFileTest();
    virtual std::string subtitle() const override;
};
class LargeAudioFileTest : public BaseTest
{
public:
    CREATE_FUNC(LargeAudioFileTest);
    virtual bool init();
    virtual ~LargeAudioFileTest();
    virtual std::string subtitle() const override;
};
#endif /* defined(__NewAudioEngineDemo__NewAudioEngineDemo__) */

2、.cpp文件

#include "NewAudioEngineDemo.h"
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
using namespace cocos2d::experimental;


#define CL(__className__) [](){ return __className__::create();}
static int sceneIdx = -1;

static std::function<Layer*()> createFunctions[] =
{
    CL(AudioControlTest),CL(PlaySimultaneouslyTest),CL(AudioProfileTest),CL(InvalidAudioFileTest),CL(LargeAudioFileTest)};

#define MAX_LAYER    (sizeof(createFunctions) / sizeof(createFunctions[0]))

static Layer* nextAction()
{
    sceneIdx++;
    sceneIdx = sceneIdx % MAX_LAYER;
    
    auto layer = (createFunctions[sceneIdx])();
    return layer;
}

static Layer* backAction()
{
    sceneIdx--;
    int total = MAX_LAYER;
    if( sceneIdx < 0 )
        sceneIdx += total;
    
    auto layer = (createFunctions[sceneIdx])();
    return layer;
}

static Layer* restartAction()
{
    auto layer = (createFunctions[sceneIdx])();
    return layer;
}

//基类Layer
bool BaseTest::init()
{
    bool bRet = false;
    do{
        CC_BREAK_IF(!Layer::init());
        
        Size visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
        
        /////////////////////////////
        // 2. add a menu item with "X" image,which is clicked to quit the program
        //    you may modify it.
        
        // add a "close" icon to exit the progress. it's an autorelease object
        auto closeItem = MenuItemImage::create(
                                               "CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(BaseTest::menuCloseCallback,this));
        closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2,origin.y + visibleSize.height - closeItem->getContentSize().height/2));
        
        // create menu,it's an autorelease object
        auto menu1 = Menu::create(closeItem,NULL);
        menu1->setPosition(Vec2::ZERO);
        this->addChild(menu1,1);
        
        std::string str = title();
        const char * pTitle = str.c_str();
        TTFConfig ttfConfig("fonts/tahoma.ttf",35);
        auto label = Label::createWithTTF(ttfConfig,pTitle);
        addChild(label,9999);
        label->setPosition( Vec2(VisibleRect::center().x,VisibleRect::top().y - 30) );
        
        std::string strSubtitle = subtitle();
        if( ! strSubtitle.empty() )
        {
            ttfConfig.fontFilePath = "fonts/tahoma.ttf";
            ttfConfig.fontSize = 30;
            auto l = Label::createWithTTF(ttfConfig,strSubtitle.c_str());
            addChild(l,9999);
            l->setPosition( Vec2(VisibleRect::center().x,VisibleRect::top().y - 100) );
        }
        
        auto item1 = MenuItemFont::create("backCallback",CC_CALLBACK_1(BaseTest::backCallback,this) );
        auto item2 = MenuItemFont::create("restartCallback",CC_CALLBACK_1(BaseTest::restartCallback,this) );
        auto item3 = MenuItemFont::create("nextCallback",CC_CALLBACK_1(BaseTest::nextCallback,this) );
        
        auto menu = Menu::create(item1,item2,item3,NULL);
        
        menu->setPosition(Vec2::ZERO);
        item1->setPosition(Vec2(VisibleRect::center().x - item2->getContentSize().width*2,VisibleRect::bottom().y+item2->getContentSize().height/2));
        item2->setPosition(Vec2(VisibleRect::center().x,VisibleRect::bottom().y+item2->getContentSize().height/2));
        item3->setPosition(Vec2(VisibleRect::center().x + item2->getContentSize().width*2,VisibleRect::bottom().y+item2->getContentSize().height/2));
        
        addChild(menu,9999);
        
        bRet = true;
    }while(0);
    return bRet;
}

void BaseTest::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
    MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif
    
    Director::getInstance()->end();
    
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

//重新执行当前test
void BaseTest::restartCallback(cocos2d::Ref *sender)
{
    auto s = new (std::nothrow) NewAudioEngineDemo();
    s->addChild(restartAction());
    Director::getInstance()->replaceScene(s);
    s->release();
}
//下一个test
void BaseTest::nextCallback(cocos2d::Ref *sender)
{
    auto s = new (std::nothrow) NewAudioEngineDemo();
    s->addChild(nextAction());
    Director::getInstance()->replaceScene(s);
    s->release();
}
//上一个test
void BaseTest::backCallback(cocos2d::Ref *sender)
{
    auto s = new (std::nothrow) NewAudioEngineDemo();
    s->addChild(backAction());
    Director::getInstance()->replaceScene(s);
    s->release();
}
//onExit函数
void BaseTest::onExit()
{
    AudioEngine::stopAll();
    Layer::onExit();
}

std::string BaseTest::title() const
{
    return "NewAudioEngineDemo Test";
}

std::string BaseTest::subtitle() const
{
    return "";
}

//封装按钮
class TextButton : public cocos2d::Label
{
public:
    //静态创建函数
    static TextButton* create(const std::string& text,const std::function<void(TextButton*)>& onTriggered)
    {
        //如果非配内存失败,返回0
        auto ret = new(std::nothrow) TextButton();
        TTFConfig ttfconfig("fonts/arial.ttf",25);
        //创建成功,设置Label
        if(ret && ret->setTTFConfig(ttfconfig))
        {
            //设置内容
            ret->setString(text);
            //设置回调函数
            ret->_onTriggered = onTriggered;
            ret->autorelease();
            return ret;
        }
        delete ret;
        return nullptr;
    }
    //设置触摸响应
    void setEnabled(bool enabled)
    {
        _enabled = enabled;
        //如果没有触摸
        if(_enabled)
        {
            //设置Lable颜色为White
            this->setColor(Color3B::WHITE);
        }else{
            //如果已经触摸,设置颜色Gray
            this->setColor(Color3B::GRAY);
        }
    }
private:
    //构造函数,_enabled为true,_onTriggered为nullptr
    TextButton()
    :_enabled(true),_onTriggered(nullptr)
    {
        //注册监听事件
        auto listener = EventListenerTouchOneByOne::create();
        listener->setSwallowTouches(true);//事件禁止向下传递
        //触摸事件类型
        listener->onTouchBegan = CC_CALLBACK_2(TextButton::onTouchBegan,this);
        listener->onTouchEnded = CC_CALLBACK_2(TextButton::onTouchEnded,this);
        listener->onTouchCancelled = CC_CALLBACK_2(TextButton::onTouchCancelled,this);
        //加入事件
        Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
    }
    //判断是否在触摸范围内
    bool touchHits(Touch* touch)
    {
        //将屏幕坐标转为节点坐标
        auto hitPos = this->convertToNodeSpace(touch->getLocation());
        //触摸点在节点坐标内,返回true,否则返回false
        if(hitPos.x >= 0 && hitPos.y >= 0 && hitPos.x <= _contentSize.width && hitPos.y <= _contentSize.height)
        {
            return true;
        }
        return false;
    }
    //触摸开始
    bool onTouchBegan(Touch* touch,Event* event)
    {
        //调用touchHit函数,返回true,在节点上
        auto hits = touchHits(touch);
        if(hits)
        {
            scaleButtonTo(0.95f);//执行按钮缩放
        }
        return hits;//响应后面触摸事件
    }
    //触摸结束
    void onTouchEnded(Touch* touch,Event* event)
    {
        //如果没有触摸
        if(_enabled)
        {
            //判断是否在节点上
            auto hits = touchHits(touch);
            //如果在节点上,且响应事件不为nullptr
            if(hits && _onTriggered)
            {
                //调用响应事件
                _onTriggered(this);
            }
        }
        //执行按钮缩放
        scaleButtonTo(1);
    }
    //触摸取消
    void onTouchCancelled(Touch* touch,Event* event)
    {
        scaleButtonTo(1);
    }
    //缩放操作
    void scaleButtonTo(float scale)
    {
        auto action = ScaleTo::create(0.05f,scale);
        action->setTag(10000);
        stopActionByTag(10000);
        runAction(action);
    }
    //事件回调函数指针
    std::function<void(TextButton*)> _onTriggered;
    bool _enabled;//是否触摸
};

//封装进度条类,拖动进度条响应事件
class SliderEx : public Slider
{
public:
    //触摸事件,按下,移动,抬起,取消
    enum class TouchEvent
    {
        DOWN,MOVE,UP,CANCEL
    };
    //定义函数函数指针
    typedef std::function<void(SliderEx*,float,TouchEvent)> ccSliderExCallback;
    //静态创建函数
    static SliderEx* create()
    {
        //std::nothrow分配内存失败返回0,必须包含头文件#include <new>
        auto ret = new(std::nothrow)SliderEx();
        if(ret && ret->init())
        {
            //初始化进度条
            ret->_callback = nullptr;
            ret->loadBarTexture("sliderTrack.png");
            ret->loadSlidBallTextures("sliderThumb.png","sliderThumb.png","");
            ret->loadProgressBarTexture("sliderProgress.png");
            ret->autorelease();
            return ret;
        }
        //如果分配内存失败,删除ret并置空
        CC_SAFE_DELETE(ret);
        return ret;
    }
    //设置回调函数
    void setCallBack(const ccSliderExCallback& callback){
        _callback = callback;
    }
    //设置进度比
    void setRatio(float ratio)
    {
        if(ratio > 1.0f)
        {
            ratio = 1.0f;
        }else if(ratio < 0.0f)
        {
            ratio = 0.0f;
        }
        
        _ratio = ratio;
        _percent = 100* _ratio;
        
        //设置进度条光标的位置,
        float dis = _barLength * _ratio;
        _slidBallRenderer->setPosition(dis,_contentSize.height/2.0f);
        
        //设置进度条已走过的进度
        if(_scale9Enabled)
        {
            //如果开启9宫格精灵,设置进度条已走过的进度比
            _progressBarRenderer->setPreferredSize(Size(dis,_progressBarTextureSize.height));
        }else{
            //如果没有开启9宫格精灵
            //首先获取进度条ProgressBar的精灵
            auto spriteRenderer = _progressBarRenderer->getSprite();
            //精灵不为空
            if(nullptr != spriteRenderer)
            {
                //获取精灵的Rect
                Rect rect = spriteRenderer->getTextureRect();
                rect.size.width = _progressBarTextureSize.width * _ratio;//设置获取精灵的Rect大小
                spriteRenderer->setTextureRect(rect,spriteRenderer->isTextureRectRotated(),rect.size);//设置ProgressBar精灵的Rect
            }
        }
    }
    //触摸开始事件
    virtual bool onTouchBegan(Touch* touch,Event* unusedEvent) override{
        //进度条开始触摸
        auto ret = Slider::onTouchBegan(touch,unusedEvent);
        //_callback不为空
        if(ret && _callback){
            _touchEvent = TouchEvent::DOWN;
            Vec2 nsp = convertToNodeSpace(_touchBeganPosition);//触摸点坐标转为节点坐标
            _ratio = nsp.x / _barLength;//取得进度比,当前触摸位置除以进度条的长度
            if(_ratio < 0.0f)
            {
                _ratio = 0.0f;
            }else if(_ratio > 1.0f)
            {
                _ratio = 1.0f;
            }
            _callback(this,_ratio,_touchEvent);//回调事件
        }
        return ret;
    }
    //移动触摸
    virtual void onTouchMoved(Touch* touch,Event* unusedEvent) override{
        _touchEvent = TouchEvent::MOVE;//设置触摸类型
        Slider::onTouchMoved(touch,unusedEvent);//Slider基类触摸
        Vec2 nsp = convertToNodeSpace(_touchMovePosition);//触摸点坐标转为节点坐标
        _ratio = nsp.x / _barLength;
        if(_ratio < 0.0f)
        {
            _ratio = 0.0f;
        }else if(_ratio > 1.0f)
        {
            _ratio = 1.0f;
        }
        if(_callback)
        {
            _callback(this,_touchEvent);//事件回调
        }
    }
    //取消触摸
    virtual void onTouchCancelled(Touch* touch,Event* unusedEvent) override
    {
        _touchEvent = TouchEvent::CANCEL;
        Slider::onTouchCancelled(touch,unusedEvent);
        if (_callback) {
            _callback(this,_touchEvent);//事件回调
        }
    }
    
private:
    TouchEvent _touchEvent;//触摸事件类型
    float _ratio;//进度比
    ccSliderExCallback _callback;//回调事件的指针函数
};
//基类Scene
bool NewAudioEngineDemo::init()
{
    bool bRet;
    do{
        CC_BREAK_IF(!Scene::init());
        //初始化AudioEngine
        CCASSERT(AudioEngine::lazyInit(),"Fail to initialize AudioEngine!");
        //初始化sceneIdx
        sceneIdx = -1;
        //执行nextAction,执行第一个test
        auto layer = nextAction();
        //加入NewAudioEngineDemo场景
        addChild(layer);
        //切换场景
        Director::getInstance()->replaceScene(this);

        bRet = true;
    }while(0);
    return bRet;
}

bool AudioControlTest::init()
{
    bool bRet = false;
    do{
        CC_BREAK_IF(!BaseTest::init());
        
        _audioID = AudioEngine::INVAILD_AUdio_ID;
        //是否循环
        _loopEnabled = false;
        //音量大小
        _volume = 1.0f;
        //
        _duration = AudioEngine::TIME_UNKNOWN;
        //更新间隔
        _timeRatio = 0.0f;
        //更新进度条
        _updateTimeSlider = true;
        //字体路径
        std::string fontFilePath = "fonts/arial.ttf";
        //当前Size
        auto layerSize = this->getContentSize();
        //play按钮,第一个参数是按钮名称,第二个参数是回调函数,在触摸结束后响应
        auto playItem = TextButton::create("play",[&](TextButton* button)
        {
            //判断ID是否为INVAILD_AUTIO_ID
            if(_audioID == AudioEngine::INVAILD_AUdio_ID)
            {
                //播放音乐,第一个参数音乐文件路径,第二个参数,是否循环播放,第三个参数,音量,跟进去发现函数返回一个int值,值为0
                _audioID = AudioEngine::play2d("background.mp3",_loopEnabled,_volume);
                log("_audioID = %d",_audioID);//打印0,即unordered_map的对象个数
                log("INVAILD_AUdio_ID = %d",AudioEngine::INVAILD_AUdio_ID);//打印-1
                //如果ID不等于AudioEngine::INVAILD_AUdio_ID,执行以下代码
                if(_audioID != AudioEngine::INVAILD_AUdio_ID)
                {
                    //设置按钮被按下,设置Lable字体颜色为灰色
                    button->setEnabled(false);
                    //如果音乐播放完毕的回调函数
                    AudioEngine::setFinishCallback(_audioID,[&](int id,const std::string& filePath)
                    {
                        //重新恢复ID值为-1
                        _audioID = AudioEngine::INVAILD_AUdio_ID;
                        ((TextButton*)_playItem)->setEnabled(true);//设置按钮为非触摸状态,即没有被按下,按钮字体颜色为White
                        _timeRatio = 0.0f;//更新时间间隔为0
                        ((SliderEx*)_timeSlider)->setRatio(_timeRatio);//设置进度比
                    });
                }
            }
        });
        _playItem = playItem;//将当前playItem赋值给_playItem,这一步在初始化时执行,先于触摸playItem前执行
        playItem->setPosition(layerSize.width*0.3f,layerSize.height*0.7f);
        addChild(playItem);
        //停止按钮
        auto stopItem = TextButton::create("stop",[&](TextButton* button){
            if(_audioID != AudioEngine::INVAILD_AUdio_ID)
            {
                AudioEngine::stop(_audioID);
                _audioID = AudioEngine::INVAILD_AUdio_ID;
                ((TextButton*)_playItem)->setEnabled(true);//停止按钮按下,play按钮字体颜色变为White
            }
        });
        stopItem->setPosition(layerSize.width*0.7f,layerSize.height*0.7f);
        addChild(stopItem);
        //暂停按钮
        auto pauseItem = TextButton::create("pause",[&](TextButton* button){
            if(_audioID != AudioEngine::INVAILD_AUdio_ID)
            {
                AudioEngine::pause(_audioID);
            }
        });
        pauseItem->setPosition(layerSize.width*0.3f,layerSize.height*0.6f);
        addChild(pauseItem);
        //恢复播放按钮
        auto resumeItem = TextButton::create("resume",[&](TextButton* button){
            if(_audioID != AudioEngine::INVAILD_AUdio_ID)
            {
                AudioEngine::resume(_audioID);
            }
        });
        resumeItem->setPosition(layerSize.width*0.7f,layerSize.height*0.6f);
        addChild(resumeItem);
        //是否循环播放
        auto loopItem = TextButton::create("enable-loop",[&](TextButton* button){
            _loopEnabled = !_loopEnabled;//取非,使_loopEnabled循环
            if(_audioID != AudioEngine::INVAILD_AUdio_ID)
            {
                AudioEngine::setLoop(_audioID,_loopEnabled);//设置是否循环
            }
            //设置循环播放按钮字体内容
            if(_loopEnabled)
            {
                button->setString("disable-loop");
            }else{
                button->setString("enable-loop");
            }
        });
        loopItem->setPosition(layerSize.width*0.3f,layerSize.height*0.5f);
        addChild(loopItem);
        
        //加载缓冲
        auto uncacheItem = TextButton::create("uncache",[&](TextButton* button){
            AudioEngine::uncache("background.mp3");
            _audioID = AudioEngine::INVAILD_AUdio_ID;
            ((TextButton*)_playItem)->setEnabled(true);//设置play按钮为非触摸状态
        });
        uncacheItem->setPosition(layerSize.width*0.7f,layerSize.height*0.5f);
        addChild(uncacheItem);
        //声音进度条
        auto volumeSlider = SliderEx::create();
        volumeSlider->setPercent(100);
        volumeSlider->setCallBack([&](SliderEx* sender,float ratio,SliderEx::TouchEvent event){
            _volume = ratio;//获取音量值
            if(_audioID != AudioEngine::INVAILD_AUdio_ID)
            {
                //设置音量
                AudioEngine::setVolume(_audioID,_volume);
            }
        });
        volumeSlider->setPosition(Vec2(layerSize.width*0.5f,layerSize.height*0.35f));
        addChild(volumeSlider);
        
        //时间进度条
        auto timeSlider = SliderEx::create();
        //参数引用类对象,参数传递在触摸事件中
        timeSlider->setCallBack([&](SliderEx* sender,SliderEx::TouchEvent event){
            switch (event) {
                case SliderEx::TouchEvent::MOVE:
                case SliderEx::TouchEvent::DOWN:
                    _updateTimeSlider = false;//按钮和移动状态下,不更新时间进度条
                    break;
                case SliderEx::TouchEvent::UP://抬起
                    if(_audioID != AudioEngine::INVAILD_AUdio_ID && _duration != AudioEngine::TIME_UNKNOWN)
                    {
                        //设置当前时间进度条的进度
                        AudioEngine::setCurrentTime(_audioID,_duration*ratio);
                    }
                    break;
                case SliderEx::TouchEvent::CANCEL:
                    _updateTimeSlider = true;//取消动作,继续更新进度条
                    break;
                default:
                    break;
            }
        });
        timeSlider->setPosition(Vec2(layerSize.width*0.5f,layerSize.height*0.25f));
        addChild(timeSlider);
        _timeSlider = timeSlider;
        
        //音量标签
        auto volumeSliderPos = volumeSlider->getPosition();
        auto sliderSize = volumeSlider->getContentSize();
        auto volumeLabel = Label::createWithTTF("volume:",fontFilePath,20);
        volumeLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
        volumeLabel->setPosition(volumeSliderPos.x - sliderSize.width/2,volumeSliderPos.y);
        addChild(volumeLabel);
        //时间标签
        auto timeSliderPos = timeSlider->getPosition();
        auto timeLabel = Label::createWithTTF("time:",20);
        timeLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
        timeLabel->setPosition(timeSliderPos.x-sliderSize.width/2,timeSliderPos.y);
        addChild(timeLabel);
        //每0.1秒更新帧
        this->schedule(CC_CALLBACK_1(AudioControlTest::update,this),0.1f,"update_key");
        
        bRet = true;
    }while(0);
    return bRet;
}
void AudioControlTest::update(float dt)
{
    //如果有音乐播放
    if(_audioID != AudioEngine::INVAILD_AUdio_ID)
    {
        //并且时间未知
        if(_duration == AudioEngine::TIME_UNKNOWN)
        {
            //设置时间间隔
            _duration = AudioEngine::getDuration(_audioID);
        }
        if(_duration != AudioEngine::TIME_UNKNOWN)
        {
            //如果时间间隔不为TIME_UNKNOWN,获取当前的播放时间
            auto time = AudioEngine::getCurrentTime(_audioID);
            _timeRatio = time / _duration;//计算时间进度比
            if(_updateTimeSlider)//如果更新进度条为true
            {
                ((SliderEx*)_timeSlider)->setRatio(_timeRatio);//设置时间进度条的进度
            }
        }
    }
}
AudioControlTest::~AudioControlTest()
{
    
}
std::string AudioControlTest::subtitle() const
{
    return "audio control test";
}

bool PlaySimultaneouslyTest::init()
{
    bool bRet = false;
    do{
        CC_BREAK_IF(!BaseTest::init());
        
        char text[36];
        int tmp = 81;
        //获取音乐文件
        for(int index = 0; index < TEST_COUNT;++index)
        {
            sprintf(text,"FX0%d.mp3",tmp+index);
            _files[index] = text;
        }
        //统计正在播放数量
        _playingcount = 0;
        //创建播放按钮,回调函数的参数button在TextButton的触摸事件中,传递的是this对象,即当前playItem对象
        auto playItem = TextButton::create("play-simultaneously",[&](TextButton* button){
            int audioId;
            _playingcount = 0;
            //设置按钮为触摸状态,即按下按钮
            button->setEnabled(false);
            //获取当前时间,返回今天当前秒和微秒的值
            auto startTime = utils::gettime();
            for(int index = 0; index < TEST_COUNT; ++index)
            {
                //播放_files里的音乐
                audioId = AudioEngine::play2d(_files[index]);
                if(audioId != AudioEngine::INVAILD_AUdio_ID)
                {
                    //正在播放增加1
                    _playingcount += 1;
                    //播放完毕的回调函数
                    AudioEngine::setFinishCallback(audioId,const std::string& filePath){
                        //正在播放减1
                        _playingcount -= 1;
                        //如果正在播放的数量小于等于-1,设置播放按钮为true,即未按下状态
                        if(_playingcount <= 0)
                        {
                            ((TextButton*)_playItem)->setEnabled(true);
                        }
                    });
                }else//如果ID等于-1,则没有音乐文件播放,或播放音乐文件失败
                {
                    log("%s,%d,Fail to play File:%s",__FILE__,__LINE__,_files[index].c_str());
                }
            }
            //打印播放的时长
            log("diff time:%lf",utils::gettime() - startTime);
        });
        //设置像素级坐标
        playItem->setNormalizedPosition(Vec2(0.5f,0.5f));
        this->addChild(playItem);
        _playItem = playItem;
        
        bRet = true;
    }while(0);
    return bRet;
}
PlaySimultaneouslyTest::~PlaySimultaneouslyTest()
{
    
}
std::string PlaySimultaneouslyTest::subtitle() const
{
    return "PlaySimultaneously Test";
}

bool AudioProfileTest::init()
{
    bool bRet = false;
    do{
        CC_BREAK_IF(!BaseTest::init());
        
        char text[30];
        _files[0] = "background.mp3";
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC
        _files[1] = "background.caf";
#else
        _files[1] = "background.ogg";
#endif
        std::string fontFilePath = "fonts/arial.ttf";
        _minDelay = 1.0f;//两个声音的最小时间间隔
        _time = 0.0f;
        
        _audioProfile.name = "AudioProfileTest";//name不可为空
        _audioProfile.maxInstances = 3;//音乐文件数量
        _audioProfile.minDelay = 1.0;//两个声音的最小时间间隔
        Vec2 pos(0.5f,0.7f);
        for(int index = 0; index < FILE_COUNT; ++index)
        {
            sprintf(text,"play %s",_files[index].c_str());
            auto playItem = TextButton::create(text,[&](TextButton* button){
                int index = button->getTag();
                //播放文件,参数1:文件路径,参数2:不循环播放,参数3:音量,参数4:AudioProfile对象,设置相关配置
                auto id = AudioEngine::play2d(_files[index],false,1.0f,&_audioProfile);
                if(id != AudioEngine::INVAILD_AUdio_ID)
                {
                    _time = _minDelay;
                    _audioCount += 1;
                    char show[30];
                    sprintf(show,"audio count:%d",_audioCount);
                    _showLabel->setString(show);
                    //播放完毕回调事件
                    AudioEngine::setFinishCallback(id,const std::string& filePath){
                        _audioCount = -1;
                        char show[30];
                        sprintf(show,_audioCount);
                        _showLabel->setString(show);
                    });
                }
            });
            playItem->setTag(index);
            playItem->setNormalizedPosition(pos);
            this->addChild(playItem);
            pos.y -= 0.15f;
        }
        
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
        Size winSize = Director::getInstance()->getVisibleSize();
        
        auto profileInfoLabel = Label::createWithTTF("AudioProfile Info:\n  max instance:3  \n  minimum delay:1.0",20);
        profileInfoLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT);
        profileInfoLabel->setPosition(Vec2(origin.x,origin.y+winSize.height*0.65f));
        addChild(profileInfoLabel);
        
        _audioCount = 0;
        //初始化_showLabel对象
        _showLabel = Label::createWithTTF("audio count:0",20);
        _showLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT);
        _showLabel->setPosition(Vec2(origin.x,origin.y+winSize.height*0.5f));
        addChild(_showLabel);
        
        //初始化timeSlider对象
        auto timeSlider = SliderEx::create();
        timeSlider->setEnabled(false);
        timeSlider->setNormalizedPosition(pos);
        addChild(timeSlider);
        _timeSlider = timeSlider;
        this->schedule(CC_CALLBACK_1(AudioProfileTest::update,0.05f,"update_key");
        
        bRet = true;
    }while(0);
    return bRet;
}

void AudioProfileTest::update(float dt)
{
    if(_time > 0.0f)
    {
        _time -= dt;
        //设置进度比
        ((SliderEx*)_timeSlider)->setRatio(_time / _minDelay);
    }
}

AudioProfileTest::~AudioProfileTest()
{
    
}
std::string AudioProfileTest::subtitle() const
{
    return "AudioProfile test";
}

bool InvalidAudioFileTest::init()
{
    bool bRet = false;
    do{
        CC_BREAK_IF(!BaseTest::init());
        
        auto playItem = TextButton::create("play unsupported media type",[&](TextButton* button){
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC
            AudioEngine::play2d("background.ogg");
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
            AudioEngine::play2d("background.caf");
#endif
        });
        playItem->setNormalizedPosition(Vec2(0.5f,0.6f));
        this->addChild(playItem);
        //播放不存在的音乐文件,查看控制台
        auto playItem2 = TextButton::create("play not-existent file",[&](TextButton* button){
            AudioEngine::play2d("not-existent file.mp3");
        });
        playItem2->setNormalizedPosition(Vec2(0.5f,0.4f));
        this->addChild(playItem2);
        
        bRet = true;
    }while(0);
    return bRet;
}

InvalidAudioFileTest::~InvalidAudioFileTest()
{
    
}
std::string InvalidAudioFileTest::subtitle() const
{
    return "InvalidAudioFile test";
}
//播放比较大的音乐文件
bool LargeAudioFileTest::init()
{
    bool bRet = false;
    do{
        CC_BREAK_IF(!BaseTest::init());
        
        auto playItem = TextButton::create("play large audio file",[&](TextButton* button){
            AudioEngine::play2d("LuckyDay.mp3");
        });
        playItem->setNormalizedPosition(Vec2::ANCHOR_MIDDLE);
        this->addChild(playItem);
        
        bRet = true;
    }while(0);
    return bRet;
}

LargeAudioFileTest::~LargeAudioFileTest()
{
    
}
std::string LargeAudioFileTest::subtitle() const
{
    return "LargeAudioFile Test";
}
#endif

猜你在找的Cocos2d-x相关文章