首先,ccb文件是如何生成的,我就不多说了,大家可以搜下cocosbuilder,就能找的相关的教程,而通过cocosbuilder,我们可以省去了很多设计的麻烦,比如设计一个精灵的位置啥的,而通过cocosbuilder,我们可以把我们编码的重点放到具体的控制类上面,而不是在显示页面上下很大的功夫。闲话不多说,要想实现这些好处,首先确定你的Cocos2d-x的版本号,如果是2.0.4,那就用cocosbuilder 2.1吧(当然,cocosbuilder只有mac版的,如果是windows,那就用cocostudio吧),如果cocos2d-x是2.1以上版本,就用cocosbuilder3.0以上版本吧,比如我用的是cocos2d-x2.1.4,我的cocosbuilder为3.0.4。
首先,来看下绑定代码吧 (GameScene.h)
#ifndef __loading__GameScene__ #define __loading__GameScene__ #include <iostream> #include "cocos2d.h" #include "cocos-ext.h" USING_NS_CC; USING_NS_CC_EXT; class GameScene :public CCLayer ,public CCBMemberVariableAssigner ,public CCNodeLoaderListener ,public CCBSelectorResolver { public: virtual bool init(); void onEnter(); void onExit(); static CCScene *scene(); CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(GameScene, create); //如果此次提示GameScene有错误,要么是下面的虚函数没有重写完,要么是重写的方法中参数有误(例如:Allocating an object of abstract class type 'GameScene';) virtual bool onAssignCCBMemberVariable(CCObject* pTarget, const char* pMemberVariableName, CCNode* pNode); virtual void onNodeLoaded(CCNode * pNode, CCNodeLoader * pNodeLoader); virtual SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, const char* pSelectorName); virtual SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject * pTarget, const char* pSelectorName); void NewGame(CCObject* sender); void ContinueGame(CCObject* sender); void CloseGame(CCObject* sender); void AboutGame(CCObject* sender); void setAnimationManager(CCBAnimationManager* value); CCLabelTTF* helloLabel; }; class GameSceneLoader:public cocos2d::extension::CCLayerLoader{ //这个类也可以完全剥离成一个单独的文件 public: CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(GameSceneLoader, loader); protected: CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(GameScene);}; #endif /* defined(__loading__GameScene__) */
GameScene.cpp文件:
#include "GameScene.h" #include "AboutGameScene.h" bool GameScene::init() { if(!CCLayer::init()) { return false; } return true; } void GameScene::onEnter() { CCLayer::onEnter(); } void GameScene::onExit() { CCLayer::onExit(); } CCScene* GameScene::scene() { CCScene* scene = CCScene::create(); CCNodeLoaderLibrary* lib = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); lib->registerCCNodeLoader("GameScene", GameSceneLoader::loader());//要绑定的类名,注册文件 CCBReader* reader = new CCBReader(lib); CCNode* node = reader->readNodeGraphFromFile("TestGameScene.ccbi",scene); //要读取的文件名,当前对象 reader->release(); //记得要释放 if (NULL!=node) { scene->addChild(node); } return scene; } // 将变量名字与变量做映射 bool GameScene::onAssignCCBMemberVariable(cocos2d::CCObject *pTarget, const char *pMemberVariableName, cocos2d::CCNode *pNode){ CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "helloLabel", CCLabelTTF*, helloLabel); return true; } // 当此场景加载完成后,如果需要做一些操作,则在此方法中添加 void GameScene::onNodeLoaded(cocos2d::CCNode *pNode, cocos2d::extension::CCNodeLoader *pNodeLoader){ helloLabel->setString("hello cocosbuilder"); } //将menu与具体的函数绑定 SEL_MenuHandler GameScene::onResolveCCBCCMenuItemSelector(CCObject * pTarget, const char* pSelectorName) { CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "NewGame", GameScene::NewGame); CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "CloseGame", GameScene::CloseGame); CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "AboutGame", GameScene::AboutGame); CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "ContinueGame", GameScene::ContinueGame); return NULL; } // 将CCControl名字与响应函数做映射,也就是通过cocosbuilder中的Control(cccontrolbutton)创建的对象 SEL_CCControlHandler GameScene::onResolveCCBCCControlSelector(CCObject * pTarget, const char* pSelectorName){ //CCB_SELECTORRESOLVER_CCCONTROL_GLUE(this, "onPressButton", MainScene::onPressButton); return NULL; } void GameScene::NewGame(CCObject *sender) { helloLabel->setString("NewButton pressed."); } void GameScene::AboutGame(CCObject *sender) { CCScene *returnback=AboutGameScene::scene(); //要切换到的场景 CCDirector::sharedDirector()->setDepthTest(true); //开启深度检测 CCTransitionScene *tmpaction=CCTransitionMoveInR::create(1.2,returnback); //切换方法 CCDirector::sharedDirector()->replaceScene(tmpaction); //切换的另一个ccb文件中 } void GameScene::CloseGame(CCObject *sender) { helloLabel->setString("CloseButton pressed."); } void GameScene::ContinueGame(CCObject *sender) { helloLabel->setString("ContinueButton pressed."); } //如果ccb文件中有动画,那就在这里设置控制吧 void GameScene::setAnimationManager(cocos2d::extension::CCBAnimationManager *value){ }
另一个绑定AboutGameSceneLoader.h代码
#ifndef loading_AboutGameSceneLoader_h #define loading_AboutGameSceneLoader_h #include "AboutGameScene.h" class AboutGameSceneLoader:public cocos2d::extension::CCLayerLoader{ public: CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(AboutGameSceneLoader, loader); protected: CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(AboutGameScene);}; #endif
AboutGameScene.h代码:
#include <iostream> #include "cocos2d.h" #include "cocos-ext.h" USING_NS_CC; USING_NS_CC_EXT; class AboutGameScene :public CCLayer ,public CCBMemberVariableAssigner ,public CCNodeLoaderListener ,public CCBSelectorResolver { public: bool init(); void onEnter(); void onExit(); static CCScene *scene(); CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(AboutGameScene, create); virtual bool onAssignCCBMemberVariable(CCObject* pTarget, const char* pMemberVariableName, CCNode* pNode); virtual void onNodeLoaded(CCNode * pNode, CCNodeLoader * pNodeLoader); virtual SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, const char* pSelectorName); virtual SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject * pTarget, const char* pSelectorName); void backMenu(CCObject* sender); void setAnimationManager(CCBAnimationManager* value); CCLabelTTF* helloLabel; };
AboutGameScene.cpp代码:
#include "AboutGameScene.h" #include "GameScene.h" #include "AboutGameSceneLoader.h" bool AboutGameScene::init() { if(!CCLayer::init()) { return false; } return true; } void AboutGameScene::onEnter() { CCLayer::onEnter(); } void AboutGameScene::onExit() { CCLayer::onExit(); } CCScene* AboutGameScene::scene() { CCScene* scene = CCScene::create(); CCNodeLoaderLibrary* lib = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); lib->registerCCNodeLoader("AboutGame", AboutGameSceneLoader::loader()); CCBReader* reader = new CCBReader(lib); CCNode* node = reader->readNodeGraphFromFile("AboutGameScene.ccbi",scene); reader->release(); if (NULL!=node) { scene->addChild(node); } return scene; } bool AboutGameScene::onAssignCCBMemberVariable(cocos2d::CCObject *pTarget, const char *pMemberVariableName, cocos2d::CCNode *pNode){ return true; } void AboutGameScene::onNodeLoaded(cocos2d::CCNode *pNode, cocos2d::extension::CCNodeLoader *pNodeLoader){ CCSize size=CCDirector::sharedDirector()->getWinSize(); CCSprite *mainsprite=CCSprite::create("catBody1.png"); addChild(mainsprite,1); CCAnimation *animation=CCAnimation::create(); animation->addSpriteFrameWithFileName("catBody1.png"); animation->addSpriteFrameWithFileName("catBody2-4.png"); animation->addSpriteFrameWithFileName("catBody3.png"); animation->addSpriteFrameWithFileName("catBody2-4.png"); animation->setDelayPerUnit(0.1f);//设置动画的间隔时间 animation->setRestoreOriginalFrame(true);//是否返回第一帧 mainsprite->runAction(CCRepeatForever::create(CCAnimate::create(animation))); mainsprite->setPosition(ccp(size.width/4, size.height/3)); } SEL_MenuHandler AboutGameScene::onResolveCCBCCMenuItemSelector(CCObject * pTarget, const char* pSelectorName) { CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "backMenu", AboutGameScene::backMenu); return NULL; } SEL_CCControlHandler AboutGameScene::onResolveCCBCCControlSelector(CCObject * pTarget, const char* pSelectorName){ return NULL; } void AboutGameScene::backMenu(CCObject *sender) { CCScene *returnback=GameScene::scene(); //要切换到的场景 CCDirector::sharedDirector()->setDepthTest(true); //开启深度检测 CCTransitionScene *tmpaction=CCTransitionMoveInR::create(1.2,returnback); //切换方法 CCDirector::sharedDirector()->replaceScene(tmpaction); } void AboutGameScene::setAnimationManager(cocos2d::extension::CCBAnimationManager *value){ }
这些代码和以上的功能相同,贴出来只是让你进一步了解。
最后的实现效果: