#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
}