上文中创建了游戏的About场景,在今天的这篇博文中将加入Option场景。在看这个之前我们先上张图片吧,无图无真相
在这个场景了我们将会实现对背景音乐的开关及返回菜单场景的实现,首先看一下这个类的头文件:
optionlayer.h
1 #ifndef _OPTION_LAYER_H 2 #define _OPTION_LAYER_H 3 4 #include "BaserLayer.h" 5 6 7 USING_NS_CC; 8 9 class OptionLayer : public BaserLayer 10 { 11 public: 12 OptionLayer(); 13 ~OptionLayer(); 14 15 virtual bool init(); 16 17 CREATE_FUNC(OptionLayer); 18 19 static CCScene *scene(); 20 21 void setViews(); 22 23 void music_triggerCallback(CCObject *obj); 24 void backCallback(CCObject *obj); 25 }; 26 27 #endif 28
这个类继承自BaserLayer和之前的代码并无太大的区别,就此略过。接着看看其实现代码,由于其基本结构和之前的并无太大差别,所以在这里我们只列出初始化界面的部分,完整的源代码会在最后列出:
1 void OptionLayer::setViews() 2 { 3 setBackGroundImage("loading.png"); 4 5 CCSprite *title = CCSprite::create("menuTitle.png",CCRectMake(0,0,135,35)); 6 title->setAnchorPoint(ccp(0.5,1)); 7 title->setPosition(ccp(getWinSize().width/2,getWinSize().height-20)); 8 9 this->addChild(title); 10 11 CCMenuItemToggle *music_trigger = CCMenuItemToggle::createWithTarget(this,menu_selector(OptionLayer::music_triggerCallback), 12 CCMenuItemFont::create("Music : On"),CCMenuItemFont::create("Music : Off"),NULL); 13 14 music_trigger->setPosition(ccp(getWinSize().width/2,getWinSize().height/2)); 15 16 17 if(SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying()) 18 { 19 music_trigger->setSelectedIndex(1); 20 } 21 else 22 { 23 music_trigger->setSelectedIndex(0); 24 } 25 26 //menu->setPosition(ccp(getWinSize().width/2,getWinSize().height/2)); 27 28 CCLabelBMFont *back = CCLabelBMFont::create("back","arial-14.fnt"); 29 30 back->setScale(1.25f); 31 CCMenuItemLabel *backLable = CCMenuItemLabel::create(back,this,menu_selector(OptionLayer::backCallback)); 32 backLable->setAnchorPoint(ccp(0.5,1)); 33 backLable->setPosition(ccp(getWinSize().width/2,50)); 34 35 CCMenu *menu = CCMenu::create(music_trigger,backLable,NULL); 36 menu->setPosition(CCPointZero); 37 38 this->addChild(menu); 39 }
在这里我们看到了菜单项的另一个子类:CCMenuItemToggle。看这个意思就知道是用来作为一个开关变量的,其可以添加多个对象,当我们点击该选项时是轮流显示的
接着我们看看点下该选项时的其回调函数
1 void OptionLayer::music_triggerCallback(CCObject *obj) 2 { 3 4 if(SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying()) 5 { 6 // music_trigger->setSelectedIndex(2); 7 SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); 8 CCUserDefault::sharedUserDefault()->setBoolForKey("music_trigger",true); 9 } 10 else 11 { 12 SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); 13 CCUserDefault::sharedUserDefault()->setBoolForKey("music_trigger",false); 14 } 15 16 }
在这个函数里出现了两个新的东西:SimpleAudioEngine和CCUserDefault。下面我们看看分别看看其出要是干什么的:
SimpleAudioEngine是用来播放音乐的,在这里的Audio是实现为单实例的,在程序运行期间只会存在一个实例,我们可以通过其提供的函数获取其实例对象。需要注意的是因为我们之前已经播放过该音乐了,所以在上述两个函数里我们只调用了它的pause方法和resume方法,如果是第一播放要调用其play方法。
需要注意的是我在linux下学习的时候默认不会链接Audio的模块,需要修改一下Makefile文件。需要在Makefile中加入头文件的路径和库文件的路径具体修改如下:
1 INCLUDES = -I.. -I../Classes -I../../../CocosDenshion/include #加入头文件
加入链接库:
1 SHAREDLIBS += -lcocos2d -lcocosdenshion
CCUserDefault用来保存全局的配置文件类似android的sharedpreferences用来保存程序的配置文件,不过其只支持几种基本的数据格式,如果需要自己的格式则需要自己去实现。
接着我们看看返回按钮的操作函数:
1 void OptionLayer::backCallback(CCObject *obj) 2 { 3 CCDirector::sharedDirector()->pushScene(CCTransitionFade::create(0.5f, WelcomeLayer::scene() )); 4 }
在这个函数中我们会完成游戏场景的切换。下面我贴出其代码的完整实现:
1 #include "optionlayer.h" 2 #include "welcomelayer.h" 3 4 OptionLayer::OptionLayer() 5 { 6 } 7 8 OptionLayer::~OptionLayer() 9 { 10 } 11 12 CCScene * OptionLayer::scene() 13 { 14 CCScene *scene = NULL; 15 16 do 17 { 18 scene = CCScene::create(); 19 CC_BREAK_IF(!scene); 20 21 OptionLayer *layer = OptionLayer::create(); 22 CC_BREAK_IF(!layer); 23 scene->addChild(layer); 24 25 }while(0); 26 27 return scene; 28 29 } 30 31 bool OptionLayer::init() 32 { 33 bool sRect = false; 34 35 do 36 { 37 CC_BREAK_IF(!BaserLayer::init()); 38 sRect = true; 39 40 setViews(); 41 42 }while(0); 43 44 return sRect; 45 } 46 47 void OptionLayer::setViews() 48 { 49 setBackGroundImage("loading.png"); 50 51 CCSprite *title = CCSprite::create("menuTitle.png",CCRectMake(0,0,135,35)); 52 title->setAnchorPoint(ccp(0.5,1)); 53 title->setPosition(ccp(getWinSize().width/2,getWinSize().height-20)); 54 55 this->addChild(title); 56 57 CCMenuItemToggle *music_trigger = CCMenuItemToggle::createWithTarget(this,menu_selector(OptionLayer::music_triggerCallback), 58 CCMenuItemFont::create("Music : On"),CCMenuItemFont::create("Music : Off"),NULL); 59 60 music_trigger->setPosition(ccp(getWinSize().width/2,getWinSize().height/2)); 61 62 63 if(SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying()) 64 { 65 music_trigger->setSelectedIndex(1); 66 } 67 else 68 { 69 music_trigger->setSelectedIndex(0); 70 } 71 72 //menu->setPosition(ccp(getWinSize().width/2,getWinSize().height/2)); 73 74 CCLabelBMFont *back = CCLabelBMFont::create("back","arial-14.fnt"); 75 76 back->setScale(1.25f); 77 CCMenuItemLabel *backLable = CCMenuItemLabel::create(back,this,menu_selector(OptionLayer::backCallback)); 78 backLable->setAnchorPoint(ccp(0.5,1)); 79 backLable->setPosition(ccp(getWinSize().width/2,50)); 80 81 CCMenu *menu = CCMenu::create(music_trigger,backLable,NULL); 82 menu->setPosition(CCPointZero); 83 84 this->addChild(menu); 85 } 86 87 void OptionLayer::backCallback(CCObject *obj) 88 { 89 CCDirector::sharedDirector()->pushScene(CCTransitionFade::create(0.5f, WelcomeLayer::scene() )); 90 } 91 92 void OptionLayer::music_triggerCallback(CCObject *obj) 93 { 94 95 if(SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying()) 96 { 97 // music_trigger->setSelectedIndex(2); 98 SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic(); 99 CCUserDefault::sharedUserDefault()->setBoolForKey("music_trigger",true); 100 } 101 else 102 { 103 SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic(); 104 CCUserDefault::sharedUserDefault()->setBoolForKey("music_trigger",false); 105 } 106 107 }
照例上一张gif图片: