Cocos builder这个巨坑,为什么onResolveCCBCCMenuItemSelector不被调用?

class MainScene : public cocos2d::CCLayer, cocos2d::extension::CCBSelectorResolver

继承了CCBSelectorResolver,重写onResolveCCBCCMenuItemSelector方法,可是不会进去

导致绑定的按钮事件无反应,会提示Cocos2d: Skipping selector ‘onPressButton’ since no CCBSelectorResolver is present.

问题就是不知道为啥不进去呢,在里面第一句打log也不会显示出来

我fuck,折腾一整天了也不知道啥原因,为啥tmd的就不进去呢???

一路跟到CCBReader/CCNodeLoader.cpp里面
BlockData * CCNodeLoader::parsePropTypeBlock(CCNode * pNode, CCNode * pParent, CCBReader * pCCBReader)

这里CCBSelectorResolver * targetAsCCBSelectorResolver = dynamic_cast<CCBSelectorResolver *>(target);

targetAsCCBSelectorResolver是NULL

为什么会是NULL呢,MainScene明明继承自CCBSelectorResolver, dynamic_cast为什么会变成NULL呢?

target的来源是
target = pCCBReader->getAnimationManager()->getRootNode();

因为这个方法第一句std::string selectorName = pCCBReader->readCachedString();
能正常显示selectorName,所以应该pCCBReader不会有问题

先去看getAnimationManager的这个animationManager来源

在CCBreader的init方法里面
bool CCBReader::init()
{
mOwnerOutletNodes = new CCArray();
mOwnerCallbackNodes = new CCArray();
mOwnerOwnerCallbackControlEvents = new CCArray();
// Setup action manager
CCBAnimationManager *pActionManager = new CCBAnimationManager();
setAnimationManager(pActionManager);
pActionManager->release();

// Setup resolution scale and container size
mActionManager->setRootContainerSize(CCDirector::sharedDirector()->getWinSize());

return true;

}
临时new的一个AnimationManager,那这个animationManager应该也不会有问题,系统生成的

然后找AnimationManager里面的root

void CCBAnimationManager::setRootNode(CCNode pRootNode)
{
CCLog(“fuck me in ccbreader %d”, (int)pRootNode);
mRootNode = pRootNode;
}
这里把设置root的指针打印出来,同时,在MainScene的create方法里面把自己打印出来
MainScene
MainScene::create() {
MainScene * ptr = new MainScene();
if(ptr != NULL && ptr->init()) {
ptr->autorelease();
CCLog(“fuck you %d”, (int)ptr);
return ptr;
}
CC_SAFE_DELETE(ptr);
return NULL;
}

Cocos2d: fuck you 137848480
Cocos2d: fuck me in ccbreader 137848480

可以看到animationManager里面设置的root确实是MainScene::create()出来的对象,而这个对象确实继承了CCBSelectorResolver
为什么dynamic_cast的时候会返回null呢?

现在问题很简单了
首先MainScene通过create方法构造出来,然后传给AnimationManager,然后传来传去,在CCNodeLoader里面拿来dynamic_cast<CCBSelectorResolver *>(target);

却没有成功,通过log可以清楚的看到确实是一个对象
Cocos2d: create main scene 136621376
Cocos2d: target in ccNodeLoader 136621376

那么会是什么原因导致的呢?

问题找到了,呵呵,是因为继承的时候
class MainScene : public cocos2d::CCLayer, public cocos2d::extension::CCBSelectorResolver

第二个继承没有写public,所以默认是private继承,自然就不能dynamic_cast了

网上的cocosBuilder攻略太破了!

尼玛,google了一天,没看到有这个说法,最后靠跟源代码解决了问题

知道cocosbuilder是天坑了?

好的项目需要大家的参与,楼主可以向开发团队反馈,帮助这个工具更好的发展。

其实我发现是我自己2……

粗心大意,看代码不仔细,有的代码确实没写public继承,有的其实写了,我没注意……

可能是一段时间没写c++了吧,c++实在是规范太严格了

比如这里一不小心漏写了个public继承,结果花了这么多时间找原因

用c++要小心啊同志们

我收回cocos builder是坑的说法,其实我才是坑//shy

cocosbuilder的加载比较麻烦,借鉴cocostudio,在项目cocosbuilder里面把各个子节点的tag设好,在程序里面先用个node读了整体的,再用getChildByTag,这样就可以不去集成那一大堆函数了。。。

这东西难度级别是html可视编辑器
或者xcode interfacebuilder
目前感觉少用 不能为了mvc而mvc

用cocostudio把ccb都导进去。