狗屎的cocosbuilder,連個說明文檔都沒有。網上一堆超級狗屎的所謂文檔,他媽的都是你抄我,我抄你,腦都沒用的。最后,要老子我看CCBReader源碼才搞明白。
先把過程寫出來。
在cocosbuilder一個button,添加個事件:selector = appleClicked:
但是在cocos2d-x死活綁定不上去。你麻痹的,搞了我一天,最終決定看源碼。網上的資料都是放屁。
先放出cocos2d-x的代碼:
// Page1Scene.h
// demo02
//
// Created by chen zhang on 12-11-17.
//
//
#ifndef __demo02__Page1Scene__
#define __demo02__Page1Scene__
#include <iostream>
#include " cocos2d.h "
#include " cocos-ext.h "
using namespace cocos2d;
using namespace cocos2d::extension;
class Page1Scene : public cocos2d::CCScene, public CCBAnimationManagerDelegate
{
CCBAnimationManager *animationManager;
virtual bool init();
virtual void completedAnimationSequenceNamed( const char *name);
void setBlendFuncToAllChildren(CCNode *node, const ccBlendFunc &blend);
~Page1Scene();
public:
static cocos2d::CCScene* scene();
CREATE_FUNC(Page1Scene);
};
#endif /* defined(__demo02__Page1Scene__) */
// Page1Scene.cpp
// demo02
//
// Created by chen zhang on 12-11-17.
//
//
#include " Page1Scene.h "
#include " Page1Layer.h "
using namespace cocos2d;
using namespace cocos2d::extension;
CCScene* Page1Scene::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
Page1Scene *layer = Page1Scene::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
bool Page1Scene::init()
{
CCNodeLoaderLibrary *ll = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary();
ll->registerCCNodeLoader( " Page1Layer ", Page1BuilderLoader::loader());
CCBReader *ccbReader = new CCBReader(ll);
animationManager = NULL;
CCNode *node = ccbReader->readNodeGraphFromFile( " HelloCocosBuilder.ccbi ", this, &animationManager);
animationManager->setDelegate( this);
// animationManager->runAnimations("ArmPigForeground");
ccbReader->release();
ccBlendFunc normalBlend = (ccBlendFunc){ GL_ONE, GL_ONE_MINUS_CONSTANT_ALPHA};
if(node != NULL)
{
setBlendFuncToAllChildren(node, normalBlend);
this->addChild(node);
}
return true;
};
void Page1Scene::setBlendFuncToAllChildren(cocos2d::CCNode *node, const ccBlendFunc &blend)
{
CCArray* children = node->getChildren();
CCObject* current = NULL;
CCARRAY_FOREACH(children, current)
{
CCNode* child = dynamic_cast<CCNode *>(current);
if (child)
{
CCSprite* sprite = dynamic_cast<CCSprite *>(current);
if (sprite && sprite->getTag() == 50)
{
sprite->setBlendFunc(blend);
}
setBlendFuncToAllChildren(child, blend);
}
}
};
void Page1Scene::completedAnimationSequenceNamed( const char *name)
{
}
Page1Scene::~Page1Scene()
{
}
這段像屎一樣的代碼,就是初始化了一個scene場景,然后添加了一個layer。把ccbi文件讀進來,放到layer。
//
// demo02
//
// Created by chen zhang on 12-11-17.
//
//
#ifndef __demo02__Page1Layer__
#define __demo02__Page1Layer__
#include <iostream>
#include " cocos2d.h "
#include " cocos-ext.h "
using namespace cocos2d;
using namespace cocos2d::extension;
class Page1Layer : public CCLayer, public CCBSelectorResolver
{
virtual bool init();
virtual SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject *pTarget, CCString *pSelectorName);
virtual SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject *pTarget, CCString *pSelectorName);
void appleClicked(CCObject *pSender, CCControlEvent pCCControlEvent);
public:
CREATE_FUNC(Page1Layer);
};
class Page1BuilderLoader : public CCLayerLoader
{
public:
CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(Page1BuilderLoader, loader);
protected:
CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(Page1Layer);
};
#endif /* defined(__demo02__Page1Layer__) */
// Page1Layer.cpp
// demo02
//
// Created by chen zhang on 12-11-17.
//
//
#include " Page1Layer.h "
using namespace cocos2d;
using namespace extension;
bool Page1Layer::init()
{
if(!CCLayer::init())
return false;
return true;
}
SEL_MenuHandler Page1Layer::onResolveCCBCCMenuItemSelector(CCObject *pTarget, CCString *pSelectorName)
{
CCB_SELECTORRESOLVER_CCMENUITEM_GLUE( this, " appleClicked: ", Page1Layer::appleClicked);
return NULL;
};
void Page1Layer::appleClicked(CCObject *pSender, CCControlEvent pCCControlEvent)
{
CCLOG( " button clicked ");
};
SEL_CCControlHandler Page1Layer::onResolveCCBCCControlSelector(cocos2d::CCObject *pTarget, cocos2d::CCString *pSelectorName)
{
CCB_SELECTORRESOLVER_CCCONTROL_GLUE( this, " appleClicked: ", Page1Layer::appleClicked);
return NULL;
};
這段像狗屎一樣的代碼,最主要就是繼承了一個CCBSelectorREsolver,把界面的selector綁定到代碼。
但是你媽的死活幫不上去。最后看代碼,分析如下:
cocosbuilder 源碼解析
CCBReader -> readNodeGraphFromFile
讀取二進制文檔
this->readNodeGraphFromData
mActionManager 動畫控制器,控制讀取的CCNODE
boolCCBReader::initWithData(CCData *pData, CCObject *pOwner)
初始化animationManager
CCBReader -> raedFileWithlearUP
CCNode *pNodeGraph = readFileWithCleanUp(true);
判斷頭版本
獲取字符串緩存
獲取動作序列
CCNode *pNode = readNodeGraph();
這個方法是個遞歸,讀取一個className,搞完了,下一個。
有了className,就從LIbrary獲取CCNodeLoader, 這個loader就是外部設置的Page1BuilderLoader
通過loader 加載了自定義類的Page1Layer
在讀取property的時候,就會初始化綁定方法,這里會指向targetTYpeDocumentRoot / targetTypeOwner
這個就是在頁面的那個設置。
root = animationManager.rootNode = Page1Layer
owner = pccbReader.owner = 外部read的指針this = Page1Seene
分割線--------
看懂的牛逼們,應該知道問題了,就是設置button的selector的owner,要設置為document root,這樣才會調用layer作為resolver,然后才能調用對應的解析器代碼。
我草。網上一群裝逼的二貨,不是少這個,就是少那個,還說 看 TestCPP很簡單。我懷疑你到底懂不懂的。