Cocos2d-x CocosBuilder使用教程(二)串連自訂類

來源:互聯網
上載者:User

看來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的原因。

下面我將一步一步操作,並講解其中原理,讓你不但學會怎麼做,而且還知其原理。

  1. 使用CocosBuilder 2.1版本建立一個Project,叫做“ConnectToCustomClass”(引號當然不算名稱了,:p)。

  2. 建立一個檔案,派生自CCLayer,並選擇你想要的裝置類型,我選擇ipad landscape 1024 * 768,儲存為“ConnectToCustomClass”(與項目工程一致)。
  3. 添加一個CCMenu節點到根節點(即CCLayer節點)。
  4. 添加一個CCMenuImage節點到CCMenu節點。
    選中此節點,到CocosBuilder右側的CCMenuItemImage段中,點擊Normal和Selected欄位,選擇對應圖片(Disable不用的話可以不選擇)。讀者可以下載下列資源:
    Normal:
    Selected:

  5. 添加一個CCControlButton到根節點(即CCLayer節點)。
    選擇此節點,到CocosBuilder右側的CCControlButton段更改“Font Size”欄位為15。這裡使用CCControlButton也是為了讓讀者知道CocosBuilder中能處理按鍵訊息的節點除了CCMenuItemImage以外,還有CControlButton。

  6. 添加一個CCLabelTTF到根節點(即CCLayer節點)。
    選擇此節點,到CocosBuilder右側的CCLabelTTF段更改“Font Size”欄位為15。這裡使用CCLabelTTF主要是教授如何在自訂的Layer類中聲明一個CCLabelTTF*變數指向CocosBuilder介面中的CCLabelTTF節點。

  7. 介面布局。
  8. 介面的“皮”做完了,但介面的神經還沒有接好。現在我們開始串連好介面的各個神經。
  9. 點擊根節點(即CCLayer節點),在CocosBuilder右側我們可以看到Code Connections段。我們將"XJLayer"填入其中的“Custom class”欄位中。
    XJ是本人名稱縮寫,你可以寫成自己的名稱縮寫(但後續操作中XJ要替換成你的名稱首碼了)。此操作的含義:讓CocosBuilder在儲存此節點時,將其節點標籤儲存為“XJLayer”,這樣在檔案解析的時候,當我們碰到節點標籤是"XJLayer"時,我們就知道這是我們自訂的XJLayer節點,我們需要對這個節點做特殊處理。

  10. 點擊”切換帳號“節點(CCMenuItemImage節點),在CocosBuilder右側CCMenuItem段中,將”menuSelectorChangeAccount"填入“Selector“欄位。在”Target“欄位中選擇”Document root“。如:

    看到這個,如果你編寫過Cocos2d-x的CCMenuItem相關的代碼,你應該很熟悉,這裡的”Target“欄位就是指的希望處理該訊息事件的對象,這裡是Document root,就是指的根節點,即我們的CCLayer節點(此節點Custom Class欄位已經被我們改成”XJLayer“)。”Selector“欄位就是處理訊息事件的函數名稱。

  11. 點擊”Title“節點(CCControlButton節點),在CocosBuilder右側CCControl段中,我們將”controlButtonTest“填入”Selector“欄位,在”Target“欄位中選擇”Document root“。
    兩個欄位含義想必你能猜到。這裡值得注意的是下面的9個複選框,這裡預設選中”Up inside“。這些複選框表示你感興趣的訊息。當前你只對按鍵在button中抬起事件感興趣。即:當使用者點擊此按鈕抬起時,你的”controlButtonTest“函數會被調用(controlButtonTes函數在哪呢,後面會提到)。

  12. 點擊”Sample Test“節點,在CocosBuilder右側"Code Connections"欄位,更改”Don't assign“欄位為”Doc root var“欄位,並將"m_TestLabel"填入該欄位。
    這裡是說,這個對象會被賦值給”文檔根變數“,也就是根節點對象。賦給該對象的”m_TestLabel“成員變數。這裡就是教授如何把CocosBuilder檔案裡的對象賦值給自訂類的某個成員變數,建立起Cocos2d-x和CocosBuilder的聯絡。

  13. 儲存檔案(【Command】+【s】,一定要儲存檔案哦,沒有點擊儲存檔案,更改不會被記錄),然後發布(【Command】+【Option】+【S】)。
  14. 建立一個Cocos2d-x模版工程,起名叫做”ConnectToCustomLayer“。
  15. 從CocosBuilder建立的Project路徑裡面,將ccbResources檔案夾(CCControlButton預設背景圖片是在ccbResources檔案夾下的),以及兩張我提供的圖片資源和一個”ConnectToCustomClass.ccbi“檔案(不是ccb檔案哦)拷貝到Cocos2d-x項目工程resources檔案夾下,並全部添加到xCode項目的Resources下(注意,一定要添加到項目工程,這樣載入ccbi檔案時,CCB
    SDK才能找到ccbi檔案。在添加的時候填出的提示框中,一定要選中對應目標項目即Target)。

  16. 在專案檔視圖中,點擊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訊息處理函數歸屬,以及變數複製的。也分別對應三個宏,讀者可以自己去看宏定義函數。

  17. 開啟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對象的串連。

  18. 運行程式,【Command】+【R】。如果順利的話,你將得到如下運行效果:

    點擊左側兩個按鈕,xCode調試輸出視窗內會有我們事先寫入的調試資訊輸出。斷點調試,你會發現XJLayer類對象的m_TestLabel是有值的。這就證明m_TestLabel正確串連了”Sample Test“標籤。
寫了快2個小時了好像,終於搞定,希望大家多交流,促進行業發展。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.