zoukankan      html  css  js  c++  java
  • 改进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"

     

  • 相关阅读:
    (转)数据库中索引的策略和设计
    (转)冷备份与热备份、双机热备与容错
    (转)Mysql数据库存储引擎
    (转)B-树和B+树的应用:数据搜索和数据库索引
    mock实例方法
    mockito模拟静态方法
    mock测试类的时候,添加@InjectMocks
    已经mock类中引用的其它service类,但是在invoke私有方法的时候,该service类是空值
    inside when() you don't call method on mock but on some other object
    org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'
  • 原文地址:https://www.cnblogs.com/xdao/p/cocos2dx_lua_ccb.html
Copyright © 2011-2022 走看看