改進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"

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM