博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2d-x的lua脚本加载CocostudioUI两种方式
阅读量:4589 次
发布时间:2019-06-09

本文共 10610 字,大约阅读时间需要 35 分钟。

前言

   当前版本使用的是quick cocos2dx lua 3.3。UI使用cocostudio编辑器1.6.0。我们在程序里面可以使用两种方式进行解析UI。开始的时候用的是quick的方法,

结果遇到了坑(百分比控件布局CCSUILoader.lua在解析时,没有对百分比进行处理,结果方案可以自己加上去)。

特别提醒:

  如果在quick中使用源生的解析方案(c++),可能出现触摸bug。因为在quick中自己实现了新的触摸机制(详情请参考LuaTouchEventManager.h 中具体的实现)

所有的触摸级别都是0,根据渲染层级处理事件

  建议:在项目实际开发中,应该自己封装一层,方便修改。

一.quick使用cocostudio

 1.加载

local uiNode = cc.uiloader:load("TestUI.json")self:addChild(uiNode)
cc.uiloader:load("XXXX.json") 后面的参数是你的cocostudio导出文件,注意路径问题

 2.读取控件

  在程序中获取控件的方法,我们可以看下 framework/cc/uiloader/uiloader.lua, (CCSUILoader.lua文件可以看下,讲具体怎么实现的)

-- @module uiloader--[[--初始化 cc.uiloader,并提供对外统一接口cc.uiloader 可以将CCS导出的json文件用quick的纯lua控件构建出UI布局]]local UILoaderUtilitys = import(".UILoaderUtilitys")local uiloader = class("uiloader")local CCSUILoader = import(".CCSUILoader")local CCSSceneLoader = import(".CCSSceneLoader")-- start ------------------------------------ 初始化 cc.uiloader,并提供对外统一接口-- @function [parent=#uiloader] new-- end --function uiloader:ctor()end-- start ------------------------------------ 解析json文件-- @function [parent=#uiloader] load-- @param string jsonFile 要解析的json文件-- @param table params 解析参数-- @return node#node  解析后的布局-- end --function uiloader:load(jsonFile, params)    local json    if not params or not params.bJsonStruct then        local pathInfo = io.pathinfo(jsonFile)        if ".csb" == pathInfo.extname then            return cc.CSLoader:getInstance():createNodeWithFlatBuffersFile(jsonFile)        else            json = self:loadFile_(jsonFile)        end    else        json = jsonFile    end    if not json then        print("uiloader - load file fail:" .. jsonFile)        return    end    local node    if self:isScene_(json) then        node, w, h = CCSSceneLoader:load(json, params)    else        node, w, h = CCSUILoader:load(json, params)    end    UILoaderUtilitys.clearPath()    return node, w, hend-- start ------------------------------------ 按tag查找布局中的结点-- @function [parent=#uiloader] seekNodeByTag-- @param node parent 要查找布局的结点-- @param number tag 要查找的tag-- @return node#node -- end --function uiloader:seekNodeByTag(parent, tag)    if not parent then        return    end    if tag == parent:getTag() then        return parent    end    local findNode    local children = parent:getChildren()    local childCount = parent:getChildrenCount()    if childCount < 1 then        return    end    for i=1, childCount do        if "table" == type(children) then            parent = children[i]        elseif "userdata" == type(children) then            parent = children:objectAtIndex(i - 1)        end        if parent then            findNode = self:seekNodeByTag(parent, tag)            if findNode then                return findNode            end        end    end    returnend-- start ------------------------------------ 按name查找布局中的结点-- @function [parent=#uiloader] seekNodeByName-- @param node parent 要查找布局的结点-- @param string name 要查找的name-- @return node#node -- end --function uiloader:seekNodeByName(parent, name)    if not parent then        return    end    if name == parent.name then        return parent    end    local findNode    local children = parent:getChildren()    local childCount = parent:getChildrenCount()    if childCount < 1 then        return    end    for i=1, childCount do        if "table" == type(children) then            parent = children[i]        elseif "userdata" == type(children) then            parent = children:objectAtIndex(i - 1)        end        if parent then            if name == parent.name then                return parent            end        end    end    for i=1, childCount do        if "table" == type(children) then            parent = children[i]        elseif "userdata" == type(children) then            parent = children:objectAtIndex(i - 1)        end        if parent then            findNode = self:seekNodeByName(parent, name)            if findNode then                return findNode            end        end    end    returnend-- start ------------------------------------ 按name查找布局中的结点-- 与seekNodeByName不同之处在于它是通过node的下子结点表来查询,效率更快-- @function [parent=#uiloader] seekNodeByNameFast-- @param node parent 要查找布局的结点-- @param string name 要查找的name-- @return node#node -- end --function uiloader:seekNodeByNameFast(parent, name)    if not parent then        return    end    if not parent.subChildren then        return    end    if name == parent.name then        return parent    end    local findNode = parent.subChildren[name]    if findNode then        -- find        return findNode    end    for i,v in ipairs(parent.subChildren) do        findNode = self:seekNodeByName(v, name)        if findNode then            return findNode        end    end    returnend-- start ------------------------------------ 根据路径来查找布局中的结点-- @function [parent=#uiloader] seekNodeByPath-- @param node parent 要查找布局的结点-- @param string path 要查找的path-- @return node#node -- end --function uiloader:seekNodeByPath(parent, path)    if not parent then        return    end    local names = string.split(path, '/')    for i,v in ipairs(names) do        parent = self:seekNodeByNameFast(parent, v)        if not parent then            return        end    end    return parentend-- start ------------------------------------ 查找布局中的组件结点-- @function [parent=#uiloader] seekComponents-- @param node parent 要查找布局的结点-- @param string nodeName 要查找的name-- @param number componentIdx 在查找组件在它的直接父结点的位置-- @return node#node --[[--查找布局中的组件结点~~~ lua-- "hero" 是结点名称-- 1 是 "hero"这个结点下的第一个组件local hero = cc.uiloader:seekComponents(parentNode, "hero", 1)~~~]]-- end --function uiloader:seekComponents(parent, nodeName, componentIdx)    local node = self:seekNodeByName(parent, nodeName)    if not node then        return    end    node = self:seekNodeByName(node, "Component" .. componentIdx)    return nodeend-- privatefunction uiloader:loadFile_(jsonFile)    local fileUtil = cc.FileUtils:getInstance()    local fullPath = fileUtil:fullPathForFilename(jsonFile)    local pathinfo  = io.pathinfo(fullPath)    UILoaderUtilitys.addSearchPathIf(pathinfo.dirname)    local jsonStr = fileUtil:getStringFromFile(fullPath)    local jsonVal = json.decode(jsonStr)    return jsonValendfunction uiloader:isScene_(json)    if json.components then        return true    else        return false    endendreturn uiloader

 

  button我们肯定会和他打交道的,这里我说下。在CCSUILoader.lua中我们可以看到,这里加载的是quick自己的button控件

如果我们没有在cocostudio中设置button的选中和禁止图片,这里点击是没有任何效果的,而使用c++时,会点击方法效果,我们可以根据自己的需求做相应修改

function CCSUILoader:createButton(options)    local node = cc.ui.UIPushButton.new(self:getButtonStateImages(options),        {scale9 = options.scale9Enable,        flipX = options.flipX,        flipY = options.flipY})    if options.opacity then        node:setCascadeOpacityEnabled(true)        node:setOpacity(options.opacity)    end    if options.text then        node:setButtonLabel(            cc.ui.UILabel.new({text = options.text,                size = options.fontSize,                color = cc.c3b(options.textColorR, options.textColorG, options.textColorB)}))    end    if not options.ignoreSize then        node:setButtonSize(options.width, options.height)    end    node:align(self:getAnchorType(options.anchorPointX or 0.5, options.anchorPointY or 0.5),        options.x or 0, options.y or 0)    return nodeend

下面是一个读取按钮的例子:

 
local button = cc.uiloader:seekNodeByPath(self.uiNode, buttonName)if button ~= nil then    button:addButtonClickedEventListener(function(...)   self:onCickSublistButton()end)
 

二.cocos2dx自带使用cocostudio

  我觉得这个还是比较好的,因为触控一直在更新完善。而quick目前是没有在维护。

1.加载

local uiNode = ccs.GUIReader:getInstance():widgetFromJsonFile("Test.json") uiNode:addTo(self)

可以参考GUIReader.lua 或者\cocos\editor-support\cocostudio CCSGUIReader.h (GUIReader.lua 是c++绑定到lua 时生成的api)

 

 2.读取控件

  这里控件的解析我们使用的是Helper ,可以参考 api Helper.lua 和具体的c++类Helper.h

---------------------------------- @module Helper-- @parent_module ccui---------------------------------- brief Get a UTF8 substring from a std::string with a given start position and length
-- Sample: std::string str = "中国中国中国"; substr = getSubStringOfUTF8String(str,0,2) will = "中国"
-- param start The start position of the substring.
-- param length The length of the substring in UTF8 count
-- return a UTF8 substring-- @function [parent=#Helper] getSubStringOfUTF8String -- @param self-- @param #string str-- @param #unsigned long start-- @param #unsigned long length-- @return string#string ret (return value: string) ---------------------------------- -- @function [parent=#Helper] changeLayoutSystemActiveState -- @param self-- @param #bool bActive ---------------------------------- -- @function [parent=#Helper] seekActionWidgetByActionTag -- @param self-- @param #ccui.Widget root-- @param #int tag-- @return Widget#Widget ret (return value: ccui.Widget) ---------------------------------- Finds a widget whose name equals to param name from root widget.
-- param root widget which will be seeked.
-- name name value.
-- return finded result.-- @function [parent=#Helper] seekWidgetByName -- @param self-- @param #ccui.Widget root-- @param #string name-- @return Widget#Widget ret (return value: ccui.Widget) ---------------------------------- Finds a widget whose tag equals to param tag from root widget.
-- param root widget which will be seeked.
-- tag tag value.
-- return finded result.-- @function [parent=#Helper] seekWidgetByTag -- @param self-- @param #ccui.Widget root-- @param #int tag-- @return Widget#Widget ret (return value: ccui.Widget) ---------------------------------- -- @function [parent=#Helper] doLayout -- @param self-- @param #cc.Node rootNode return nil

下面是button的例子:

local button = ccui.Helper:seekWidgetByName(self.uiNode, buttonName)
function CampMainlayer:initButton()    local function touchEvent(sender,event)         if event == ccui.TouchEventType.ended then            if sender ~= nil then                local tag = sender:getTag()-1000                --TODO:操作            end            end    end    for i=1,3 do        local buttonName = "Button_"..i        local button = ccui.Helper:seekWidgetByName(self.uiNode, buttonName)        if button ~= nil then             button:addTouchEventListener(touchEvent)            button:setTag(1000+i)        end    endend

注意 ccui.TouchEventType.ended  这是在 cocos.ui.GuiConstants中,所以我们想用这些的话,需要 require("cocos.ui.GuiConstants")。

  我们在实际的项目开发中,肯定会遇到很多问题,当然,遇到问题我们可以在网上找,但是并不是所有的问题都能找到,所以,自己动手解决问题的能力很重要,

对于我们来说,去看源码,看具体的实现,就能很快找到解决问题的方式。

如果有什么问题,请加我的QQ776274781,或者群:102349463 。大家一起学习。

 

转载于:https://www.cnblogs.com/zhangfeitao/p/4560165.html

你可能感兴趣的文章
html笔记6
查看>>
《Spring技术内幕》读书笔记
查看>>
日常代码优化系列:(一)获取url参数
查看>>
Java 集合和映射表
查看>>
java 多线程面试
查看>>
一段鬼畜风格的JavaScript解密
查看>>
Python 爬虫从入门到进阶之路(十)
查看>>
关于TCP/IP的三次握手和四次挥手解释
查看>>
怎样使flash的背景变成透明的?
查看>>
未能找到类型或命名空间名称DbContext
查看>>
Tensorflow学习教程集合
查看>>
Simple http post request demo
查看>>
c# 给button添加不规则的图片以及用pictureBox替代button响应点击事件
查看>>
比较排序算法时间复杂度下界为nlogn的证明
查看>>
C#图像的灰度化处理:提取像素法
查看>>
[18/11/24] 递归解决-放置苹果问题
查看>>
[转]Zend Studio GitHub 使用教程
查看>>
spring-aspect不报错但是也不运行
查看>>
c/c++面试----c工程开发之头文件
查看>>
怎么理解协同办公系统的工作流
查看>>