作者:loagong5i0
本实例基于 CocosBuilder 2.1 以及 cocos2d-2.0-x-2.0.4,因为cocosbuilder3.0+的版目前还不是很稳定!如果不是要做html5的项目,还是建议使用2.1的版本为佳。
虽然网上已经有很多cocosBuilder的教程,但大多数都是基于cocos2d里的test实例来讲的,每当我照着他们的做法去学习时总是会碰到很多问题,所以决定写下我学习的经历,以及会碰到什么样的错误!希望碰到跟一样问题的同学可以不用走太多的弯路!
一开始我是使用的是最新版的CocosBuilder-3.0-alpha2 和 cocos2d-2.1beta3-x-2.1.0,官方说这两版本是兼容的!在cocos2d是里test项目里也确实是没问题可以运行的!但每当我自己在cocosBuilder里自己新建一个Layer,并保存和publish后,在cocos2d里加载总是会报一些错误!实在是不想去找那些bug,跟何况自己对cocosBuilder还不了解,太过于转牛角尖只会浪费时间,搞不好还会打击自己的自信心,所以还是建议初学者使用比较稳定的版本!
-----------------------------------------------------------------------------------------------------------------------------------------
那么现在开始我们的第一篇! 加载一个Layer并连接到类
新建一个project,并保存到指定文件夹!完成后你会看到一个HelloCocosBuilder.ccb文件,我们不管他(如果你想删除它,可以在文件夹里直接删除即可)
选择
然后逐一加入我们需要的背景等等,完成后如下图,我们选择timeline上最上的CCLayer,并在Custom class选项里填入自己类名(这里我把它叫做MenuLayer)
然后保存,因为cocos2d加载是读取的是.ccbi文件,我们现在为止完成的是.ccb文件,所以我们还需把它publish,并把它加入到我们的项目里的resources file里去,或者加到Build Phases里去。
这样我,我们就准备好.ccbi文件了。
记住每当我们在builder 里做了修改后,一定要保存,然后再publish,这样才能确保我们的.ccbi文件是最新的!我就在这个环节上吃了几次亏,明明已经改了某些连接名,但加载的时候还是提示找不到对应的连接名。
接下来是代表部分。
MenuLayer.h文件
#ifndef __bug__Menue__ #define __bug__Menue__ #include <iostream> #include "cocos2d.h" #include "cocos-ext.h" class MenuLayer : public cocos2d::CCLayer , public cocos2d::extension::CCBSelectorResolver //解析选择器接口 , public cocos2d::extension::CCBMemberVariableAssigner //分配成员变量接口 , public cocos2d::extension::CCNodeLoaderListener //监听加载节点接口 { public: CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(MenuLayer, create); static cocos2d::CCScene * scene(); MenuLayer(); virtual ~MenuLayer(); virtual void onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader); //实现CCNodeLoaderListener接口,当每个节点被加载时调用。 virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, cocos2d::CCString * pMemberVariableName, cocos2d::CCNode * pNode); //实现CCBMemberVariableAssigner接口, 连接变量 virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); //实现CCBSelectorResolver接口, 用于连接菜单项。 virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName); //实现CCBSelectorResolver接口, 用于连接CCControl。 void startBtnClick(cocos2d::CCObject * object); virtual void ccTouchesBegan(cocos2d::CCSet * pTouch, cocos2d::CCEvent * pEvent); virtual bool ccTouchBegan(cocos2d::CCTouch * pTouch, cocos2d::CCEvent * pEvent); virtual void update(float deita); private: cocos2d::CCMenuItemImage * startBtn; cocos2d::CCLabelTTF * labelTxt; }; #endif /* defined(__bug__Menue__) */将我们刚刚做好的menu.ccbi连接到类MenuLayer类
#include "MenuLayer.h" #include "MenuLayerLoader.h" #include "GameMainSceneScene.h" USING_NS_CC; USING_NS_CC_EXT; MenuLayer::MenuLayer(): startBtn(NULL), labelTxt(NULL){ } MenuLayer::~MenuLayer(){} CCScene * MenuLayer::scene(){ CCScene * scene = CCScene::create(); CCLayer * layer = MenuLayer::create(); scene->addChild(layer); return scene; } void MenuLayer::onNodeLoaded(CCNode *pNode, CCNodeLoader *pNodeLoader){ labelTxt->setString("hah, you will start game!"); labelTxt->setPositionY(100); this->scheduleUpdate(); startBtn->setPositionY(100); this->setTouchEnabled(true); //设为支持触摸 this->setTouchMode(cocos2d::kCCTouchesAllAtOnce);//设置是否支持多点触摸 } void MenuLayer::update(float deita){ } bool MenuLayer::onAssignCCBMemberVariable(CCObject *pTarget, CCString *pMemberVariableName, CCNode *pNode){ CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "startBtn", CCMenuItemImage *, this->startBtn); //连接startBtn按钮 CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "labelTxt", CCLabelTTF *, this->labelTxt); // 连接CCLabel return false; } SEL_MenuHandler MenuLayer::onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName){ CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "startBtnClick", MenuLayer::startBtnClick); //连接菜单选择器 return NULL; } void MenuLayer::startBtnClick(CCObject * object){ CCScene * ccScene = GameMainSceneScene::create(); CCDirector::sharedDirector()->replaceScene(ccScene); } SEL_CCControlHandler MenuLayer::onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName){ return NULL; } void MenuLayer::ccTouchesBegan(cocos2d::CCSet *pTouch, cocos2d::CCEvent *pEvent){ } bool MenuLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){ return true; }
因为我们加载的是一个Layer,所以我们的loader 类要继承CCLayerLoader类
MenuLayerLoader.h 文件
#ifndef __bug__MenuLayerLoader__ #define __bug__MenuLayerLoader__ #include <iostream> #include "MenuLayer.h" class CCBReader; class MenuLayerLoader : public cocos2d::extension::CCLayerLoader{ public: CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(MenuLayerLoader, loader); //使用loader创建MenuLayerLoader类。 protected: CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(MenuLayer); //调用create方法创建MenuLayer。 }; #endif /* defined(__bug__MenuLayerLoader__) */
使用MenuSceen加载MenuLayer类
MenuScene.cpp
#include "MenuScene.h" MenuScene::MenuScene(){ init(); } bool MenuScene::init(){ cocos2d::extension::CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); ccNodeLoaderLibrary->registerCCNodeLoader("MenuLayer", MenuLayerLoader::loader()); /* Create an autorelease CCBReader. */ cocos2d::extension::CCBReader * ccbReader = new cocos2d::extension::CCBReader(ccNodeLoaderLibrary); /* Read a ccbi file. */ CCNode * node = ccbReader->readNodeGraphFromFile("menus.ccbi", this); ccbReader->release(); if(node != NULL) { this->addChild(node); } return true; }