首页 > 代码库 > 改进cocos2dx中lua读ccb的方法

改进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 = http://www.mamicode.com/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 = http://www.mamicode.com/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 nodeendComView=class("ComView", function (  )    --print("comview class")    return display.newNode();end)ComView.ccbCall={}function ComView:ctor(args)       local  proxy = CCBProxy:create()   ----print("comview new",self.ccbCall[1][1])   self.ccbNode=NewCCBuilderReaderLoad(args.f,proxy,self)   if args.add== nil or args.add==true then        self:addChild(self.ccbNode)   endend

 

用法如下:

 

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.castend 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"