在專案檔視圖中,點擊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{//staticpublic:CREATE_FUNC( XJLayer );public: ~XJLayer(){ CC_SAFE_RELEASE_NULL( m_TestLabel );}void menuSelectorChangeAccount( CCObject* node );void controlButtonTest(CCObject* pObject, CCControlEvent event);//CCBSelectorResolvervirtual SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, CCString * pSelectorName); virtual extension::SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject * pTarget, CCString * pSelectorName);//CCBMemberVariableAssignervirtual 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對象的串連。