你是否正在寻找关于cocosbuilder的内容?让我把最内涵的东西奉献给你:

本教程基于Cocos2d-x 2.0.4版本
看来2013年2月最多只能写三篇技术博客了!今天学习使用了一下CocosBuilder的连接到自定义类的功能,确实很爽,让IOS的程序员们不必再硬编码了。通过看Cocosbuilder本身的document,以及搜索网上资料,加上自己查看CCB源码,完成连接自定义类的功能。首先需要注意一点,cocosbuilder的Document是针对Cocos2d-iPhone的而不是Cocos2d-x的,所以很多Document里面讲到的并不适用于Cocos2d-x。因为cocos2d-x是基于C++的,所以无法通过类名字符串来动态创建类(OC当然可以了),这也是为什么Cocos2d-x版本的CCB SDK在架构上添加CCNodeLoadLibrary的原因。
下面我将一步一步操作,并讲解其中原理,让你不但学会怎么做,而且还知其原理。
在项目文件视图中,点击Classes,创建一个C++类【Command】+【N】。其名称叫做”XJLayer"。代码人如下:
//
// XJLayer.h
// ConnectToCustomClass
//
// Created by jason on 13-2-28.
//
//
#ifndef __ConnectToCustomClass__XJLayer__
#define __ConnectToCustomClass__XJLayer__
#include "cocos2d.h"
#include "cocos-ext.h"
USING_NS_CC;
USING_NS_CC_EXT;
class XJLayer : public CCLayer, public CCBSelectorResolver, public CCBMemberVariableAssigner
{
//static
public:
CREATE_FUNC( XJLayer );
public:
~XJLayer()
{
CC_SAFE_RELEASE_NULL( m_TestLabel );
}
void menuSelectorChangeAccount( CCObject* node );
void controlButtonTest(CCObject* pObject, CCControlEvent event);
//CCBSelectorResolver
virtual SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName);
virtual extension::SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject * pTarget, CCString * pSelectorName);
//CCBMemberVariableAssigner
virtual bool onAssignCCBMemberVariable(CCObject * pTarget, CCString * pMemberVariableName, CCNode * pNode);
private:
CCLabelTTF* m_TestLabel;
};
class XJLayerLoader : public CCLayerLoader{
public:
//CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD( XJLayerLoader, loader );
//||(equal)
//static XJLayerLoader* loader()
//{
//XJLayerLoader * ptr = new XJLayerLoader();
//if(ptr != NULL) {
//ptr->autorelease();
//return ptr;
//}
//CC_SAFE_DELETE(ptr);
//return NULL;
//}
CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD( XJLayerLoader, loader );
//CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD( XJLayer );
//||(equal)
//virtual XJLayer * createCCNode(cocos2d::CCNode * pParent, cocos2d::extension::CCBReader * pCCBReader)
//{
//return XJLayer::create();
//}
CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD( XJLayer );
};
#endif /* defined(__ConnectToCustomClass__XJLayer__) */
代码是重点。
1.这里XJLayer除了继承自CCLayer,也继承自两个你很陌生的类(CCBSelectorResolver,CCBMemberVariableAssigner)。通过字面意思,我们大体能知道,两个类分别是:selector解析器,和成员变量赋值器。这是两个抽象类,在java也称为接口。即继承自这两个类的类,必须重写其纯虚函数。
CCBSelectorResolver有两个:
virtual SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName);
virtual extension::SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject * pTarget, CCString * pSelectorName);CCBMemberVariableAssigner有一个:
virtual bool onAssignCCBMemberVariable(CCObject * pTarget, CCString * pMemberVariableName, CCNode * pNode);
CCBSelectorResolver中分别解析MenuItem的消息处理函数和CControlButton的消息处理函数。
CCBMemberVariableAssigner就是连接ccbi文件创建的对象与cocos2d-x对象的。
另外:一定要施放与cocosbuilder绑定的对象。CC_SAFE_RELEASE_NULL( m_TestLabel );
2.我们创建了一个XJLayerLoader,其继承自CCLayerLoader(CCLayerLoader是CCBReader中的一个类,此类负责CCLayer节点的加载)。通过派生,我们让这个加载器创建我们自己的类对象,也就是通过这个宏定义完成的——CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD( XJLayer );ccbi文件解析时,创建节点就是通过createCCNode完成的。我们会声明一个XJLayerLoader对象,传给ccbi阅读器,阅读器在特定时候调用该加载器的createCCNode()来创建我们自己的Layer。
//
// XJLayer.cpp
// ConnectToCustomClass
//
// Created by jason on 13-2-28.
//
//
#include "XJLayer.h"
void XJLayer::menuSelectorChangeAccount( CCObject* pObject )
{
CCLog( "CGStartGameLayer::menuSelectorChangeAccount" );
}
void XJLayer::controlButtonTest(CCObject* pObject, CCControlEvent event)
{
CCLog( "CGStartGameLayer::controlButtonEventhandle" );
}
SEL_MenuHandler XJLayer::onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName)
{
CCB_SELECTORRESOLVER_CCMENUITEM_GLUE( this, "menuSelectorChangeAccount", XJLayer::menuSelectorChangeAccount);
return NULL;
}
extension::SEL_CCControlHandler XJLayer::onResolveCCBCCControlSelector(CCObject * pTarget, CCString * pSelectorName)
{
CCB_SELECTORRESOLVER_CCCONTROL_GLUE( this, "controlButtonMoreServers", XJLayer::controlButtonTest );
return NULL;
}
bool XJLayer::onAssignCCBMemberVariable(CCObject * pTarget, CCString * pMemberVariableName, CCNode * pNode)
{
CCB_MEMBERVARIABLEASSIGNER_GLUE( this, "m_TestLabel", CCLabelTTF*, m_TestLabel );
return false;
}这里是两个消息处理函数,输出一些调试信息,以让我们知道按钮被点击了。另外三个函数,就是上面提到的三个虚函数,分别解决MenuItem消息处理函数归属(即那个函数作为消息处理函数),CControlButton消息处理函数归属,以及变量复制的。也分别对应三个宏,读者可以自己去看宏定义函数。
打开AppDelegate.cpp文件,做如下修改:
#include "cocos-ext.h"
#include "XJLayer.h"
USING_NS_CC_EXT;
cocs-ext.h包含了读取ccbi所需类的所有头文件。
修改AppDelegate::applicationDidFinishLaunching()
bool AppDelegate::applicationDidFinishLaunching()
{
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
// turn on display FPS
pDirector->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
// CCScene *pScene = HelloWorld::scene();
CCNodeLoaderLibrary::sharedCCNodeLoaderLibrary()->registerCCNodeLoader( "XJLayer", XJLayerLoader::loader());
CCBReader* reader = new CCBReader( CCNodeLoaderLibrary::sharedCCNodeLoaderLibrary() );
reader->autorelease();
// run
pDirector->runWithScene( reader->createSceneWithNodeGraphFromFile( "ConnectToCustomClass.ccbi" ) );
return true;
}CCNodeLoaderLibrary类内包含了所有节点的加载器。CCBReader类将使用这个库内的对应加载器去创建对应的节点。因为我们要创建我们自定义的节点,所以我们往库内注册了一个新节点加载器。
CCNodeLoaderLibrary::sharedCCNodeLoaderLibrary()->registerCCNodeLoader( "XJLayer", XJLayerLoader::loader());即当遇到节点类型(或称为标签)为“XJLayer“的时候,使用XJLayerLoader::loader()创建出来的那个加载器来创建节点,。而我们知道这个加载器重写createCCNode,这样就能正确创建出我们自定义的XJLayer了。
另外当CCBReader遇到某些节点中有selector,target属性时,就会找到根节点(根节点就是我们的XJLayer节点,我们的加载器此时已经创建了一个XJLayer对象),然后调用对应的虚函数,去解决消息处理函数归属和变量复制的问题。这样就完成ccbi对象与cocos2d-x对象的连接。
运行程序,【Command】+【R】。如果顺利的话,你将得到如下运行效果:

点击左侧两个按钮,xCode调试输出窗口内会有我们事先写入的调试信息输出。断点调试,你会发现XJLayer类对象的m_TestLabel是有值的。这就证明m_TestLabel正确连接了”Sample Test“标签。写了快2个小时了好像,终于搞定,希望大家多交流,促进行业发展。
以上就是关于cocosbuilder的全部内容,相信你一定会非常满意。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shenmilingyu/article-7369-1.html
认同和学习几千年传承下来的中华文明