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

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

2016-07-10 20:49 399 查看
#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<void(void)> &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<void(void)> _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-&
4000
gt;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<ControlSlider*>(pSender);
//获取滑块当前值
const float musicVolume = pSlider->getValue();
//设置背景音乐值
SimpleAudioEngine::getInstance()->setBackgroundMusicVolume(musicVolume);

}
void HelloWorld::effectsValueChanged(Ref *pSender, Control::EventType controlEvent){
ControlSlider* pSlider = dynamic_cast<ControlSlider*>(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
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: