作者: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类
Menu.cpp文件
#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;
}