cocos2d-x 3.x学习之声音系统
程序员文章站
2022-07-03 11:30:44
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "...
#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 }