当前位置: 移动技术网 > 移动技术>移动开发>IOS > cocos2d-x 3.x学习之声音系统

cocos2d-x 3.x学习之声音系统

2018年03月18日  | 移动技术网移动技术  | 我要评论
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "extensions/GUI/CCControlExtension/CCControlSlider.h"
USING_NS_CC;
using namespace CocosDenshion;
using namespace extension;
class AudioSlider;
class HelloWorld : public Layer{
private:
    //音效的id
    unsigned int _soundId;
    //调整背景音乐值和音效值的滑块
    AudioSlider *_sliderMusicVolume;
    AudioSlider *_sliderEffectsVolume;
    AudioSlider *_sliderPitch;
    AudioSlider *_sliderPan;
    AudioSlider *_sliderGain;
public:
    static Scene* createScene();
    virtual bool init();
    //背景音乐滑块响应函数
    void musicValueChanged(Ref* pSender,Control::EventType controlEvent);
    //音效滑块响应函数
    void effectsValueChanged(Ref* pSender,Control::EventType controlEvent);
    void menuCloseCallback(cocos2d::Ref* pSender);
    CREATE_FUNC(HelloWorld);
};
#include "HelloWorldScene.h"
// 根据不同平台选择不同的音效格式文件
#if (CC_TARGET_PLATFORM == CC_PLATFOR_ANDROID)
#define EFFECT_FILE        "effect2.ogg"
#elif( CC_TARGET_PLATFORM == CC_PLATFOR_MARMALADE)
#define EFFECT_FILE        "effect1.raw"
#else
#define EFFECT_FILE        "effect1.wav"
#endif
// 根据不同平台选择不同的背景音乐格式文件
#if (CC_TARGET_PLATFORM == CC_PLATFOR_WIN32)
#define MUSIC_FILE        "music.mid"
#elif (CC_TARGET_PLATFORM == CC_PLATFOR_BLACKBERRY || CC_TARGET_PLATFORM == CC_PLATFOR_LINUX )
#define MUSIC_FILE        "background.ogg"
#else
#define MUSIC_FILE        "background.mp3"
#endif
class Button : public Node{
public:
    //使用图片路径创建精灵
    static Button *createWithSprite(const char *filePath){
        auto b = new Button();
        if(b && !b->initSpriteButton(filePath)){
            delete b;
            b = NULL;
        }
        return b;
    }
    //使用文本创建精灵
    static Button *createWithText(const char *text){
        auto b = new Button();
        if(b && !b->initTextButton(text)){
            delete b;
            b = NULL;
        }
        return b;
    }
    //析构函数
    ~Button(){
    
    }
    //绑定的响应事件函数
    void onTriggered(const std::function &onTriggered){
        _onTriggered = onTriggered;
    }
private:
    Button():_child(NULL){
      //创建单点触摸事件监听器
        auto listener = EventListenerTouchOneByOne::create();
        listener->setSwallowTouches(true);
        listener->onTouchBegan = [=](Touch* touch,Event *event){
            const bool hits = touchHits(touch);
            if(hits)
                scaleButtonTo(0.9f);
            return hits;
        };
        //触摸结束,调用响应函数,同时缩放标签
        listener->onTouchEnded = [=](Touch *touch,Event *event){
            const bool hits = touchHits(touch);
            if(hits && _onTriggered)
                _onTriggered();
            scaleButtonTo(1);
        };
        //触摸取消。缩放标签
        listener->onTouchCancelled = [=](Touch *touch,Event *event){
            scaleButtonTo(1);
        };
        //添加场景优先事件监听器
        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
    }
    //使用图片路径创建精灵
    bool initSpriteButton(const char *filePath){
        _child = Sprite::create(filePath);
        addChild(_child);
        return true;
    }
    //使用文本创建精灵
    bool initTextButton(const char *text){
        _child = Label::createWithSystemFont(text,"Arial", 32);
        addChild(_child);
        return true;
    }
    //判断触摸位置是否在标签之内
    bool touchHits(Touch *touch){
        const Rect area(0,0,_child->getContentSize().width,_child->getContentSize().height);
        return area.containsPoint(_child->convertToNodeSpace(touch->getLocation()));
    }
    //缩放标签动作
    void scaleButtonTo(float scale){
        auto action = ScaleTo::create(0.1f, scale);
        action->setTag(900);
        stopActionByTag(900);
        runAction(action);
    }
    Node *_child;
    std::function _onTriggered;
};
//自定义音量调节类
class AudioSlider : public Node{
  //create函数,如果init函数调用出错则回收对象
public:
    static AudioSlider *create(){
        auto ret = new AudioSlider();
        if(ret && !ret->init()){
            delete ret;
            ret = NULL;
        }
        return ret;
    }
    //返回滑块当前值
    float getValue()const{
        return _slider->getValue();
    }
    void setValue(float minValue,float maxValue,float value){
      //设置音量滑块的范围最小值,最大值和当前值
        _slider->setMinimumValue(minValue);
        _slider->setMaximumValue(maxValue);
        _slider->setValue(value);
        //创建滑块上面显示的最小值和最大值的标签
        char buffer[32];
        sprintf(buffer,"%.2f",minValue);
        _lblMinValue = Label::createWithSystemFont(buffer,"Arial",18);
        addChild(_lblMinValue);
        sprintf(buffer,"%.2f",maxValue);
        _lblMaxValue = Label::createWithSystemFont(buffer,"Arial",18);
        addChild(_lblMaxValue);
    }
    //设置滑块、最小值标签、最大值标签位置
    void setSliderPosition(float x,float y){
        Size visibleSize = Director::getInstance()->getVisibleSize();
        _slider->setPosition(visibleSize.width * x,visibleSize.height * y);
        _lblMinValue->setPosition(visibleSize.width * (x - 0.1),visibleSize.height * (y + 0.05));
        _lblMaxValue->setPosition(visibleSize.width * (x + 0.1),visibleSize.height * (y + 0.05));
        
    }
    //返回滑块对象
    ControlSlider* getSlider(){
        return _slider;
    }
private:
    bool init(){
        _slider = ControlSlider::create("sliderTrack.png","sliderProgress.png","sliderThumb.png");
        addChild(_slider);
        return true;
    }
    ControlSlider *_slider;//调整滑块
    Label *_lblMinValue;//最小音量
    Label *_lblMaxValue;//最大音量
};
Scene* HelloWorld::createScene(){
    auto scene = Scene::create();
    auto layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}
bool HelloWorld::init(){
    if ( !Layer::init() ){
        return false;
    }
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
	closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);
    //预加载音乐和音效
    SimpleAudioEngine::getInstance()->preloadBackgroundMusic(MUSIC_FILE);
    SimpleAudioEngine::getInstance()->preloadEffect(EFFECT_FILE);
    //背景音乐控制标签
    auto lbMusic = Label::createWithSystemFont("背景音乐控制","Arial",32);
    lbMusic->setPosition(visibleSize.width * 0.25,visibleSize.height * 0.9);
    this->addChild(lbMusic);
    //播放背景音乐
    auto playMusic = Button::createWithText("播放");
    playMusic->onTriggered([]{
        SimpleAudioEngine::getInstance()->playBackgroundMusic(MUSIC_FILE);
    });
    playMusic->setPosition(visibleSize.width * 0.1,visibleSize.height * 0.8);
    this->addChild(playMusic);
    //停止背景音乐
    auto stopMusic = Button::createWithText("停止");
    stopMusic->onTriggered([]{
        SimpleAudioEngine::getInstance()->stopBackgroundMusic();
    });
    stopMusic->setPosition(visibleSize.width * 0.25,visibleSize.height * 0.8);
    this->addChild(stopMusic);
    //回访背景音乐
    auto rewinMusic = Button::createWithText("回放");
    rewinMusic->onTriggered([]{
        SimpleAudioEngine::getInstance()->rewindBackgroundMusic();
    });
    rewinMusic->setPosition(visibleSize.width * 0.40,visibleSize.height * 0.8);
    this->addChild(rewinMusic);
    //暂停背景音乐
    auto pauseMusic = Button::createWithText("暂停");
    pauseMusic->onTriggered([]{
        SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
    });
    pauseMusic->setPosition(visibleSize.width * 0.10,visibleSize.height * 0.65);
    this->addChild(pauseMusic);
    //继续背景音乐
    auto resumeMusic = Button::createWithText("继续");
    resumeMusic->onTriggered([]{
        SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
    });
    resumeMusic->setPosition(visibleSize.width * 0.25,visibleSize.height * 0.65);
    this->addChild(resumeMusic);
    //音效控制标签
    auto lblSound = Label::createWithSystemFont("音效控制","Arial",32);
    lblSound->setPosition(visibleSize.width * 0.75,visibleSize.height * 0.9);
    this->addChild(lblSound);
    //播放音效
    auto playEffect = Button::createWithText("播放");
    playEffect->onTriggered([this]{
        const float pitch = _sliderPitch->getValue();
        const float pan = _sliderPan->getValue();
        const float gain = _sliderGain->getValue();
        _soundId = SimpleAudioEngine::getInstance()->playEffect(EFFECT_FILE,false,pitch,pan,gain);
    });
    playEffect->setPosition(visibleSize.width * 0.6,visibleSize.height * 0.8);
    this->addChild(playEffect);
    //暂停音效
    auto pauseEffect = Button::createWithText("暂停");
    pauseMusic->onTriggered([this]{
        SimpleAudioEngine::getInstance()->pauseEffect(_soundId);
    });
    pauseEffect->setPosition(visibleSize.width * 0.75,visibleSize.height * 0.8);
    this->addChild(pauseEffect);
    //继续音效
    auto resumeEffect = Button::createWithText("继续");
    resumeEffect->onTriggered([this]{
        SimpleAudioEngine::getInstance()->resumeEffect(_soundId);
    });
    resumeEffect->setPosition(visibleSize.width * 0.9,visibleSize.height * 0.8);
    this->addChild(resumeEffect);
    //停止音效
    auto stopEffect = Button::createWithText("停止");
    stopEffect->onTriggered([this]{
        SimpleAudioEngine::getInstance()->stopEffect(_soundId);
    });
    stopEffect->setPosition(visibleSize.width * 0.6,visibleSize.height * 0.7);
    this->addChild(stopEffect);
    //循环播放音效
    auto playEffectInLoop = Button::createWithText("循环播放");
    playEffectInLoop->onTriggered([this]{
        const float pitch = _sliderPitch->getValue();
        const float pan = _sliderPan->getValue();
        const float gain = _sliderGain->getValue();
        _soundId = SimpleAudioEngine::getInstance()->playEffect(EFFECT_FILE,true,pitch,pan,gain);
    });
    playEffectInLoop->setPosition(visibleSize.width * 0.75,visibleSize.height * 0.70);
    this->addChild(playEffectInLoop);
    //暂停所有音效
    auto pauseAllEffect = Button::createWithText("暂停所有");
    pauseAllEffect->onTriggered([this]{
        SimpleAudioEngine::getInstance()->pauseAllEffects();
    });
    pauseAllEffect->setPosition(visibleSize.width * 0.55,visibleSize.height * 0.60);
    this->addChild(pauseAllEffect);
    //继续所有音效
    auto resumeAllEffect = Button::createWithText("继续所有");
    resumeAllEffect->onTriggered([this]{
        SimpleAudioEngine::getInstance()->resumeAllEffects();
    });
    resumeAllEffect->setPosition(visibleSize.width * 0.75,visibleSize.height * 0.60);
    this->addChild(resumeAllEffect);
    //停止所有音效
    auto stopAllEffect = Button::createWithText("停止所有");
    stopAllEffect->onTriggered([this]{
        SimpleAudioEngine::getInstance()->stopAllEffects();
    });
    stopAllEffect->setPosition(visibleSize.width * 0.92,visibleSize.height * 0.60);
    this->addChild(stopAllEffect);
    //音量调整标签
    auto lblMusicVolume = Label::createWithSystemFont("音量","Arial",24);
    lblMusicVolume->setPosition(visibleSize.width * 0.08,visibleSize.height * 0.45);
    this->addChild(lblMusicVolume);
    //音量大小调整滑块
    _sliderMusicVolume = AudioSlider::create();
    _sliderMusicVolume->setValue(0.00f,1.00f, 1.0f);
    _sliderMusicVolume->setSliderPosition(0.28,0.45);
    //绑定音量事件处理函数,当滑块被拖动时被调用
    _sliderMusicVolume->getSlider()->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::musicValueChanged),Control::EventType::VALUE_CHANGED);
    this->addChild(_sliderMusicVolume);
    //音效调整标签
    auto lblEffectsVolume = Label::createWithSystemFont("音效","Arial", 24);
    lblEffectsVolume->setPosition(visibleSize.width * 0.60,visibleSize.height * 0.45);
    this->addChild(lblEffectsVolume);
    //音效大小调整滑块
    _sliderEffectsVolume = AudioSlider::create();
    _sliderEffectsVolume->setValue(0.00f, 1.00f, 1.0f);
    _sliderEffectsVolume->setSliderPosition(0.80,0.45);
    //绑定音量事件处理函数,当滑块被拖动时被调用
    _sliderEffectsVolume->getSlider()->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::effectsValueChanged),Control::EventType::VALUE_CHANGED);
    this->addChild(_sliderEffectsVolume);
    //高音调整标签
    auto lblPltich = Label::createWithSystemFont("高音","Arial",24);
    lblPltich->setPosition(visibleSize.width * 0.60,visibleSize.height * 0.35);
    this->addChild(lblPltich);
    //高音大小调整滑块
    _sliderPitch = AudioSlider::create();
    _sliderPitch->setValue(-0.50f, 2.00f, 1.0f);
    _sliderPitch->setSliderPosition(0.85, 0.35);
    this->addChild(_sliderPitch);
    //立体效果调整标签
    auto lblPan = Label::createWithSystemFont("立体效果","Arial", 24);
    lblPan->setPosition(visibleSize.width * 0.60,visibleSize.height * 0.25);
    this->addChild(lblPan);
    //立体效果调整滑块
    _sliderPan = AudioSlider::create();
    _sliderPan->setValue(-1.00f, 1.00f, 0.0f);
    _sliderPan->setSliderPosition(0.80, 0.25);
    this->addChild(_sliderPan);
    //音量调整标签
    auto lblGain = Label::createWithSystemFont("音量","Arial",24);
    lblGain->setPosition(visibleSize.width * 0.60,visibleSize.height * 0.15);
    this->addChild(lblGain);
    //音量调整滑块
    _sliderGain = AudioSlider::create();
    _sliderGain->setValue(0.00f, 1.00f, 1.0f);
    _sliderGain->setSliderPosition(0.80, 0.15);
    this->addChild(_sliderGain);
    return true;
}
void HelloWorld::musicValueChanged(Ref *pSender, Control::EventType controlEvent){
  //将pSender类型转换成拖动滑块ControlSlider
    ControlSlider* pSlider = dynamic_cast(pSender);
    //获取滑块当前值
    const float musicVolume = pSlider->getValue();
    //设置背景音乐值
    SimpleAudioEngine::getInstance()->setBackgroundMusicVolume(musicVolume);
    
}
void HelloWorld::effectsValueChanged(Ref *pSender, Control::EventType controlEvent){
    ControlSlider* pSlider = dynamic_cast(pSender);
    const float effectVolume = pSlider->getValue();
    SimpleAudioEngine::getInstance()->setEffectsVolume(effectVolume);
}
void HelloWorld::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
}

\

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网