改进cocos2dx中lua读ccb的方法
cocos2dx自带的CCBProxy真弱,还好提供了一个CCBReaderLoader.lua,但是也不好用,
于是修改了一下CCBReaderLoader,下面直接贴代码了。
function NewCCBuilderReaderLoad(strFilePath,proxy,owner) if nil == proxy then return end --print("ccbnew") local ccbReader = proxy:createCCBReader() local node = ccbReader:load(strFilePath) local rootName = "" if nil ~= owner then --Callbacks --print("ccb new callback") local ownerCallbackNames = tolua.cast(ccbReader:getOwnerCallbackNames(),"CCArray") local ownerCallbackNodes = tolua.cast(ccbReader:getOwnerCallbackNodes(),"CCArray") local ownerCallbackControlEvents = tolua.cast(ccbReader:getOwnerCallbackControlEvents(),"CCArray") local i = 1 --print("ccb 222",ownerCallbackNames:count()) for i = 1,ownerCallbackNames:count() do local callbackName = tolua.cast(ownerCallbackNames:objectAtIndex(i - 1),"CCString") local callbackNode = tolua.cast(ownerCallbackNodes:objectAtIndex(i - 1),"CCNode") --print("ccb333",callbackName) if "function" == type(owner[callbackName]) then local integerValue = tolua.cast(ownerCallbackControlEvents:objectAtIndex(i - 1),"CCInteger") if nil ~= integerValue then proxy:setCallback(callbackNode, owner[callbackName], integerValue:getValue()) end else --print("Warning: Cannot find owner's lua function:" .. ":" .. callbackName .. " for ownerVar selector") end end --Variables local ownerOutletNames = tolua.cast(ccbReader:getOwnerOutletNames(),"CCArray") local ownerOutletNodes = tolua.cast(ccbReader:getOwnerOutletNodes(),"CCArray") for i = 1, ownerOutletNames:count() do local outletName = tolua.cast(ownerOutletNames:objectAtIndex(i - 1),"CCString") local outletNode = tolua.cast(ownerOutletNodes:objectAtIndex(i - 1),"CCNode") owner[outletName:getCString()] = outletNode end end local nodesWithAnimationManagers = tolua.cast(ccbReader:getNodesWithAnimationManagers(),"CCArray") local animationManagersForNodes = tolua.cast(ccbReader:getAnimationManagersForNodes(),"CCArray") --print("cccb 44444",nodesWithAnimationManagers:count()) for i = 1 , nodesWithAnimationManagers:count() do local innerNode = tolua.cast(nodesWithAnimationManagers:objectAtIndex(i - 1),"CCNode") local animationManager = tolua.cast(animationManagersForNodes:objectAtIndex(i - 1), "CCBAnimationManager") local documentControllerName = animationManager:getDocumentControllerName() --print("ccb 555",documentControllerName) if "" == documentControllerName then end ----print("ccbcall",owner.ccbCall[documentControllerName][]) if nil ~= documentControllerName then owner.ccbCall["mAnimationManager"] = animationManager end --Callbacks local documentCallbackNames = tolua.cast(animationManager:getDocumentCallbackNames(),"CCArray") local documentCallbackNodes = tolua.cast(animationManager:getDocumentCallbackNodes(),"CCArray") local documentCallbackControlEvents = tolua.cast(animationManager:getDocumentCallbackControlEvents(),"CCArray") for i = 1,documentCallbackNames:count() do local callbackName = tolua.cast(documentCallbackNames:objectAtIndex(i - 1),"CCString") local callbackNode = tolua.cast(documentCallbackNodes:objectAtIndex(i - 1),"CCNode") if "" ~= documentControllerName then local cbName = callbackName:getCString() --print("ccccccb",owner) if "function" == type(owner.ccbCall[cbName]) then local integerValue = tolua.cast(documentCallbackControlEvents:objectAtIndex(i - 1),"CCInteger") if nil ~= integerValue then proxy:setCallback(callbackNode, owner.ccbCall[cbName], integerValue:getValue()) end else print("Warning: Cannot found lua function [" .. documentControllerName .. ":" .. callbackName:getCString() .. "] for docRoot selector") end end end --Variables local documentOutletNames = tolua.cast(animationManager:getDocumentOutletNames(),"CCArray") local documentOutletNodes = tolua.cast(animationManager:getDocumentOutletNodes(),"CCArray") for i = 1, documentOutletNames:count() do local outletName = tolua.cast(documentOutletNames:objectAtIndex(i - 1),"CCString") local outletNode = tolua.cast(documentOutletNodes:objectAtIndex(i - 1),"CCNode") if nil ~= documentControllerName then owner.ccbCall[outletName:getCString()] = tolua.cast(outletNode, proxy:getNodeTypeName(outletNode)) end end --Setup timeline callbacks local keyframeCallbacks = animationManager:getKeyframeCallbacks() for i = 1 , keyframeCallbacks:count() do local callbackCombine = tolua.cast(keyframeCallbacks:objectAtIndex(i - 1),"CCString"):getCString() local beignIndex,endIndex = string.find(callbackCombine,":") local callbackType = tonumber(string.sub(callbackCombine,1,beignIndex - 1)) local callbackName = string.sub(callbackCombine,endIndex + 1, -1) --Document callback if 1 == callbackType and nil ~= documentControllerName then local callfunc = CCCallFunc:create(owner.ccbCall[callbackName]) animationManager:setCallFuncForLuaCallbackNamed(callfunc, callbackCombine) elseif 2 == callbackType and nil ~= owner then --Owner callback local callfunc = CCCallFunc:create(owner[callbackName]) animationManager:setCallFuncForLuaCallbackNamed(callfunc, callbackCombine) end end --start animation local autoPlaySeqId = animationManager:getAutoPlaySequenceId() if -1 ~= autoPlaySeqId then animationManager:runAnimationsForSequenceIdTweenDuration(autoPlaySeqId, 0) end end return node end ComView=class("ComView", function ( ) --print("comview class") return display.newNode(); end) ComView.ccbCall={} function ComView:ctor(args) local proxy = CCBProxy:create()
--2014.7.30 修正,如果不用元表,就会出现同名变量被覆盖的问题
self.ccbCall={}
setmetatable(self.ccbCall, {__index=ComView.ccbCall})
self.ccbNode=NewCCBuilderReaderLoad(args.f,proxy,self)
if args.add== nil or args.add==true then self:addChild(self.ccbNode) end end
用法如下:
local XxxView = class("XxxView", ComView)--必须继承ComView function XxxView:ctor() self.ccbCall["menu"]=handler(self,self.menu_click)--配置ccb里的回调函数,必须写在self.ccbCall表里,表里的key是ccb里的名字,对应的值是类里的函数,要用handler包装一下 XxxView.super.ctor(self,{f="XxxView.ccbi"}) --必须在配置回调函数后在调用父类的构造函数 --此时可以直接用self.ccbNode操作读入的ccb --ccb里的变量可以直接用self.ccbCall[变量名]访问,类型不需要tolua.cast end function XxxView:menu_click(tag,sender) end
注意XxxView实际是一个node,ccb是它的子节点
XxxView.super.ctor(self,{f="XxxView.ccbi"}),还可以传入一个add参数,如果add为nil或true则自动把ccb节点加到XxxView中,
其它不加,方便在XxxView里控制加载ccb的时机。
注意ccb工程要按如下设置:
改ccb要设置为js的
ccb里的根节点要设置一个js controller名字随意,如果没有设置,会有nodesWithAnimationManagers相关的错误。
或者直接把整个工程设为js的,这样新建的ccb都是js的了 菜单位置“File--Project settings"
作者:半山
出处:http://www.cnblogs.com/xdao/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。