原創:請注明轉載!
在Cocos2d-x中使用CocosBuilder
使用自定義類
CocosBuilder的使用方法是通過自定義類。在CocosBuilder中選中一個對象並在屬性欄中輸入自定義類的類名就可以了。記住你的自定義類必須是你選中對象的一個子類(如CCLayer,CCNode等等)
當加載ccbi文件時,你需要定義兩個自定義類(也可以是一個)。自定義的Loader類繼承自cocos2d::extension::CCLayerLoader。
自定義的Layer類繼承自
cocos2d::extension::CCBSelectorResolver
cocos2d::extension::CCBMemberVariableAssigner
cocos2d::extension::CCNodeLoaderListener
在你的自定義Loader類中你需要加入初始化代碼:
public: CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CustomLayerLoaderClass, loader); CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(CustomLayerClass)); |
使用Loader類的loader方法,CCBReader可以初始化你的自定義Layer類。
請注意CCBReader不會使用任何自定義的init方法。如果要使用自定義的init方法,你可以在自定義Layer類的構造函數中調用。
關聯成員變量
在ccbi中引用的對象可以在文件被加載時關聯為成員變量。這些成員變量可以定義在文檔的根節點中,在這種情況下它必須分配一個自定義類。
關聯成員變量很簡單,只要在頭文件中聲明它們就可以了。
如果要初始化成員變量,你可以在自定義Layer類中重載onAssignCCBMemberVariable方法並輸入代碼:
CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "sprtBurst", CCSprite *, this->mSprtBurst); |
sprtBurst是在CocosBuilder中定義的屬性名。
在CocosBuilder中選擇對象,在Code Connections面板下把Don't assign變為Doc root var或者Owner var。然后在右邊的文本框中輸入成員變量的名字。
添加CCMenuItemImage的回調函數
為CCMenuItemImage添加一個點擊事件的回調函數很簡單,在CocosBuilder中選中CCMenuItemImage,在Selector右邊的文本框中輸入方法的名稱即可,並設置target為Document root或者Owner。
回調函數將把CCMenuItemImage作為它的唯一參數(參數類型是id,名稱一般是sender)。或者你也可以忽略這個參數。
在你的自定義類中,重載onResolveCCBCCMenuItemSelector方法並添加如下代碼:
CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "pressedA:", MenuTestLayer::onMenuItemAClicked); |
在這個方法中,MenuTestLayer是你的自定義類名。
然后在你的cpp文件中,可以編寫回調方法
void MenuTestLayer::onMenuItemAClicked(cocos2d::CCObject *pSender) {
} |
添加CCControl的回調函數
為CCControl添加一個回調方法和CCMenuItemImage基本相同,只需要加一些額外的東西。
首先勾選事件類型,CCControlButton一般的事件都是Up inside。Target右邊的下拉菜單選擇Document root或者Owner,然后輸入回調方法名。這個回調方法可以有兩個參數,sender和事件類型,事件類型被定義在CCControl.h中。
在自定義類中,重載onResolveCCBCCControlSelector方法並加入如下代碼:
CCB_SELECTORRESOLVER_CCCONTROL_GLUE(this, "pressedMenus:", MenuTestLayer::onPressedMenus); |
在這個方法中,MenuTestLayer是你的自定義類名。
然后在你的cpp文件中,可以編寫回調方法
void HelloCocosBuilderLayer::onMenuTestClicked(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent) { } |
加載ccb文件的選項
在加載CocosBuilder的文件前,CocosBuilder文檔或者ccb文件需要以一種壓縮的二進制格式發布——ccbi格式,一旦被發布,只要一行代碼就可以簡單地把它們加載到你的程序中。添加CCBReader.h 和 CCBReader.m文件到你的Cocos2D項目中(Cocos2d-x不用添加這些文件),然后調用nodeGraphFromFile方法,如下所示:
CCBReader *ccbReader = new cocos2d::extension::CCBReader(ccNodeLoaderLibrary); CCNode* myNode = ccbReader->readNodeGraphFromFile("MyNodeGraph.ccbi"); |
ccNodeLoaderLibrary的初始化有兩種方法:
如果你使用的是自定義類,那么:
CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); |
在這種情況下,HelloCocosBuilderLayer是在CocosBuilder中指定的自定義類名。
如果沒有使用自定義類,你可以初始化一個默認的NodeLoader
CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); |
根據ccbi文件中根節點的對象類型你需要對返回值做一下強制類型轉換。比如,如果你加載的是一個CCParticleSystem,那么你需要如下代碼:
CCParticleSystem* myParticles = (CCParticleSystem*) ccbReader->readNodeGraphFromFile("MyParticleSystem.ccbi"); |
為了方便起見,CCBReader還可以把你的節點圖打包在一個場景中,然后調用sceneWithNodeGraphFromFile方法:
CCScene* myScene = ccbReader->sceneWithNodeGraphFromFile("MyScene.ccbi"); |
傳遞Owner變量
有時你可能需要訪問另一個對象中的成員變量或者回調函數,而不是訪問根節點中的變量和函數。這樣的話,你就需要給CCBReader傳遞一個Owner參數。記住在CocosBuilder中聲明變量或者回調函數的時候Target選擇owner選項。然后調用CCBReader類的nodeGraphFromFile(file, owner)方法或者sceneWithNodeGraphFromFile(file, owner)方法來加載你的文件。
HelloCocosBuilderLayer *pOwner = new HelloCocosBuilderLayer(); CCNode* myNode = ccbReader->readNodeGraphFromFile("MyNodeGraph.ccbi", pOwner); |
訪問子ccb文件中的變量和回調函數
如果你使用了子ccb文件,並且指定root node作為目標,那么owner target就是你要傳給CCBReader的對象。
示例
請參看HelloCocosBuilderLayer.h, HelloCocosBuilderLayer.cpp,還有cocos2d-x官方包下面的TestCPP項目中的ExtensionsTest示例。
設置縮放和設計尺寸
基於CocosBuilder的cocos2d-x項目,在AppDelegate類中對游戲尺寸的適配進行了設置,它會自動地從相應的目錄中加載相應的資源文件。它的原理是基於設備屏幕的大小。你同樣需要對縮放系數和設計分辨率這兩個參數進行設置。
豎屏模式下,在AppDelegate.cpp的AppDelegate::applicationDidFinishLaunching方法中加入代碼:
CCSize designSize = CCSizeMake(320, 480); CCSize resourceSize = CCSizeMake(320, 480); CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
std::vector<std::string> searchPaths; std::vector<std::string> resDirOrders;
TargetPlatform platform = CCApplication::sharedApplication()->getTargetPlatform(); if (platform == kTargetIphone || platform == kTargetIpad) { searchPaths.push_back("Published-iOS"); // Resources/Published-iOS CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);
if (screenSize.height > 768) { resourceSize = CCSizeMake(1536, 2048); resDirOrders.push_back("resources-ipadhd"); } else if (screenSize.height > 640) { resourceSize = CCSizeMake(768, 1536); resDirOrders.push_back("resources-ipad"); }else if (screenSize.height > 480) { resourceSize = CCSizeMake(640, 960); resDirOrders.push_back("resources-iphonehd"); } else { resDirOrders.push_back("resources-iphone"); }
CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(resDirOrders); } else if (platform == kTargetAndroid || platform == kTargetWindows) {
if (screenSize.height > 960) { resourceSize = CCSizeMake(640, 960); resDirOrders.push_back("resources-large"); } else if (screenSize.height > 480) { resourceSize = CCSizeMake(480, 720); resDirOrders.push_back("resources-medium"); } else { resourceSize = CCSizeMake(320, 568); resDirOrders.push_back("resources-small"); }
CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(resDirOrders); }
pDirector->setContentScaleFactor(resourceSize.width/designSize.width);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionShowAll); |
如果是橫屏的模式,你只需要把分辨率寬高的順序調整一下就好了。比如(320, 480)變為(480,320),(640, 960)變為(960, 640)等等。