改进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()
   ----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)
   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"

改进cocos2dx中lua读ccb的方法

时间: 2024-11-07 15:47:53

改进cocos2dx中lua读ccb的方法的相关文章

cocos2d-x 中LUA和平台之间的函数调用理解

先看一张流程图如下: 第一步: 先把NDKHelper中的方法转成LUA中可以调用的,转得方法可参考quick中LUA的用法.这个类主要是中间桥梁的作用,它可以根据是什么平台调用IOSNDKHelper或者AndroidSNDKHelper,这些判断都是用C语言来写的.还有就是对一些回调函数的保存机制和平台要用LUA中一些方法的保存. 第二步: IOS平台需要处理的就是IOSNDKHelper,这个类主要就是接收和发送给NDKHelper数据的方法,还有一个就是加载IOS平台的BasePlatf

关于Cocos2d-x中的scheduleUpdate和update方法的使用

如果要让某类实例对象要连续执行某些语句(比如让每个Block实例从运行框最右边移动到最左边) 要在Block类中增加一些东西 1.先在其.cpp文件的init()函数中执行scheduleUpdate()方法. 2.然后在.h中声明一个虚拟的函数update,并在.cpp文件中定义update,当init中执行scheduleUpdate()时,会不断地调用update函数,里面的语句也不断地被执行,直到执行unscheduleUpdate()时停止调用update()函数,unschedule

关于Cocos2d-x中打包图集和使用方法

1.打开TextruePacker软件 2.把游戏中要使用的图片拖到TextruePacker里面,TextruePacker会自动帮我们排序,让所有小图变成一个大图 3.点击Publish-会输出两个文件 MyTexture.plist  //里面记录了所有小图在大图中的位置和属性,cocos可以根据这些信息在MyTexture.png大图中找到所需要的小图 MyTexture.png  //一张容纳了所有小图的大图 4.在GameScene.cpp的init方法里面写 //加载plist文件

cocos2dx中加载图片资源的方法,和从内存中获取已经加载的图片资源的方法

游戏中通常需要将常用的资源如:声音,图片,plist文件,提前加载进内存,以加快游戏的流畅度 1.预加载声音: SimpleAudioEngine::getInstance()->preloadBackgroundMusic("boom.mp3"); 加载之后就可以直接播放:SimpleAudioEngine::getInstance()->playBackgroundMusic("boom.mp3"); 2.预加载图片资源: 图片资源的加载分为同步加载

cocos2dx中的场景和使用方法

1.一个游戏中有且只有一个导演,但是至少有一个场景 2.场景是游戏元素节点数的根节点,也可以理解为该场景下的渲染树的根节点 3.场景是一个容器,包含了该场景下的所有游戏元素,比如层,精灵 4.场景是导演用来控制游戏流程用的,例如如何开始场景,什么时候切换场景,什么条件下结束场景等等 5.与场景有关的API操作: 运行场景:runWithScene(Scene* scene); 启动游戏,并运行scene场景.本方法在主程序第一次启动主场景的时候调用.如果已有正在运行的场景则不能调用该方法:会调用

关于Cocos2d-x中init方法和onEnter方法的区别

init()和onEnter()这两个方法都是写实例化对象的类(比如继承自Node的一些类等等)的时候用到的方法. 一般都是public类型下面的 bool init(); void onEnter(); 两个方法在实现的时候都要先执行父类方法,比如 Node::init(); Node::onEnter(); 注意: 1.init()在类的初始化时只会调用一次. 2.onEnter在该类被载入场景的时候被调用,可能会发生多次. 3.Node* nd = new Node(); 这种情况下,只会

[转]Lua中的元表与元方法

前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了“+”符号,就可以进行类的加法运算.在Lua中也有这个道理,两个table类型的变量,你是无法直接进行“+”操作的,如果你定义了一个指定的函数,就可以进行了.那这篇博文就是主要讲的如果定义这个指定的函数,这个指定的函数时什么?希望对学习Lua的朋友有帮助. Lua是怎么做的? 通常,Lua中的每个值都有一套预定义的操作集合,比如数字是可以相加的,字符串是可以连

Lua语言基础汇总(8) -- Lua中的元表与元方法

前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了“+”符号,就可以进行类的加法运算.在Lua中也有这个道理,两个table类型的变量,你是无法直接进行“+”操作的,如果你定义了一个指定的函数,就可以进行了.那本文就是主要讲的是如何定义这个指定的函数,这个指定的函数是什么?希望对学习Lua的朋友有帮助. Lua是怎么做的? 通常,Lua中的每个值都有一套预定义的操作集合,比如数字是可以相加的,字符串是可以连接

关于在Cocos2dx中注册触摸事件——Lua

关于在Cocos2dx中注册触摸事件,之前一直对此一知半解,这两天在看引擎的源码,趁此机会写下来... 以下纯属个人理解,如有不对欢迎指正... 在引擎的CCLayer类中声明了有四个方法: 1 virtual bool onTouchBegan(Touch *touch, Event *unused_event); 2 virtual void onTouchMoved(Touch *touch, Event *unused_event); 3 virtual void onTouchEnde