lua中 cocostudio 导出lua用widgetFromJsonFile加载的UI 怎么释放内存

cocos2dx(21)
1、必须把当前的UILayer的优先级设置为1,priority的数值越大,优先级越低
2、必须把CCtableView里面的layer的优先级设置为2,。防止穿透点击tableView里面的按钮。
3、必须把Panel_top和Panel_bottom的渲染层级设置为0,而把其他需要接受点击的按钮的渲染层级设置为比Panel。这样就把屏蔽了tableview的点击穿透了。Panel_top设置为可交互。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:25897次
排名:千里之外
原创:12篇
转载:36篇
(1)(2)(4)(3)(2)(4)(8)(2)(1)(21)cocos2d-x(10)
1.cocostudio 视频教程:
将编辑好的UI界面通过以下代码加入到项目中
UILayer *layer = UILayer::create();
UIWidget *view = CCUIHELPER-&createWidgetFromJsonFile( &HSJ_Proj_1.ExportJson& );
layer-&addWidget( view );
this-&addChild( layer );
UITextButton* btn_battle = dynamic_cast&UITextButton*&(layer-&getWidgetByName(&btn_battle&));
btn_battle-&addReleaseEvent(this, coco_releaseselector(GameScene::battleEvent));
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:27024次
排名:千里之外
原创:33篇
(1)(10)(1)(7)(2)(1)(10)(2)(2)(2)&  当前版本使用的是quick cocos2dx lua 3.3。UI使用cocostudio编辑器1.6.0。我们在程序里面可以使用两种方式进行解析UI。开始的时候用的是quick的方法,
结果遇到了坑(百分比控件布局CCSUILoader.lua在解析时,没有对百分比进行处理,结果方案可以自己加上去)。
特别提醒:
  如果在quick中使用源生的解析方案(c++),可能出现触摸bug。因为在quick中自己实现了新的触摸机制(详情请参考LuaTouchEventManager.h 中具体的实现)
所有的触摸级别都是0,根据渲染层级处理事件
  建议:在项目实际开发中,应该自己封装一层,方便修改。
一.quick使用cocostudio
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
function uiloader:ctor()
-- start --
--------------------------------
-- 解析json文件
-- @function [parent=#uiloader] load
-- @param string jsonFile 要解析的json文件
-- @param table params 解析参数
-- @return node#node
解析后的布局
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)
json = self:loadFile_(jsonFile)
json = jsonFile
if not json then
print("uiloader - load file fail:" .. jsonFile)
local node
if self:isScene_(json) then
node, w, h = CCSSceneLoader:load(json, params)
node, w, h = CCSUILoader:load(json, params)
UILoaderUtilitys.clearPath()
return node, w, h
-- start --
--------------------------------
-- 按tag查找布局中的结点
-- @function [parent=#uiloader] seekNodeByTag
-- @param node parent 要查找布局的结点
-- @param number tag 要查找的tag
-- @return node#node
function uiloader:seekNodeByTag(parent, tag)
if not parent then
if tag == parent:getTag() then
return parent
local findNode
local children = parent:getChildren()
local childCount = parent:getChildrenCount()
if childCount & 1 then
for i=1, childCount do
if "table" == type(children) then
parent = children[i]
elseif "userdata" == type(children) then
parent = children:objectAtIndex(i - 1)
if parent then
findNode = self:seekNodeByTag(parent, tag)
if findNode then
return findNode
-- start --
--------------------------------
-- 按name查找布局中的结点
-- @function [parent=#uiloader] seekNodeByName
-- @param node parent 要查找布局的结点
-- @param string name 要查找的name
-- @return node#node
function uiloader:seekNodeByName(parent, name)
if not parent then
if name == parent.name then
return parent
local findNode
local children = parent:getChildren()
local childCount = parent:getChildrenCount()
if childCount & 1 then
for i=1, childCount do
if "table" == type(children) then
parent = children[i]
elseif "userdata" == type(children) then
parent = children:objectAtIndex(i - 1)
if parent then
if name == parent.name then
return parent
for i=1, childCount do
if "table" == type(children) then
parent = children[i]
elseif "userdata" == type(children) then
parent = children:objectAtIndex(i - 1)
if parent then
findNode = self:seekNodeByName(parent, name)
if findNode then
return findNode
-- start --
--------------------------------
-- 按name查找布局中的结点
-- 与seekNodeByName不同之处在于它是通过node的下子结点表来查询,效率更快
-- @function [parent=#uiloader] seekNodeByNameFast
-- @param node parent 要查找布局的结点
-- @param string name 要查找的name
-- @return node#node
function uiloader:seekNodeByNameFast(parent, name)
if not parent then
if not parent.subChildren then
if name == parent.name then
return parent
local findNode = parent.subChildren[name]
if findNode then
return findNode
for i,v in ipairs(parent.subChildren) do
findNode = self:seekNodeByName(v, name)
if findNode then
return findNode
-- start --
--------------------------------
-- 根据路径来查找布局中的结点
-- @function [parent=#uiloader] seekNodeByPath
-- @param node parent 要查找布局的结点
-- @param string path 要查找的path
-- @return node#node
function uiloader:seekNodeByPath(parent, path)
if not parent then
local names = string.split(path, '/')
for i,v in ipairs(names) do
parent = self:seekNodeByNameFast(parent, v)
if not parent then
return parent
-- start --
--------------------------------
-- 查找布局中的组件结点
-- @function [parent=#uiloader] seekComponents
-- @param node parent 要查找布局的结点
-- @param string nodeName 要查找的name
-- @param number componentIdx 在查找组件在它的直接父结点的位置
-- @return node#node
查找布局中的组件结点
-- "hero" 是结点名称
-- 1 是 "hero"这个结点下的第一个组件
local hero = cc.uiloader:seekComponents(parentNode, "hero", 1)
function uiloader:seekComponents(parent, nodeName, componentIdx)
local node = self:seekNodeByName(parent, nodeName)
if not node then
node = self:seekNodeByName(node, "Component" .. componentIdx)
return node
-- private
function 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 jsonVal
function uiloader:isScene_(json)
if ponents then
return true
return false
return 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)
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)}))
if not options.ignoreSize then
node:setButtonSize(options.width, options.height)
node:align(self:getAnchorType(options.anchorPointX or 0.5, options.anchorPointY or 0.5),
options.x or 0, options.y or 0)
return node
下面是一个读取按钮的例子:
local button = cc.uiloader:seekNodeByPath(self.uiNode, buttonName)
if button ~= nil then
button:addButtonClickedEventListener(function(...)
self:onCickSublistButton()
二.cocos2dx自带使用cocostudio
  我觉得这个还是比较好的,因为触控一直在更新完善。而quick目前是没有在维护。
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&br&
-- Sample:
std::string str = "中国中国中国";
substr = getSubStringOfUTF8String(str,0,2) will = "中国"&br&
-- param start The start position of the substring.&br&
-- param length The length of the substring in UTF8 count&br&
-- 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.&br&
-- param root
widget which will be seeked.&br&
name value.&br&
-- 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.&br&
-- param root
widget which will be seeked.&br&
tag value.&br&
-- 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:操作
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)
注意&ccui.TouchEventType.ended &这是在&cocos.ui.GuiConstants中,所以我们想用这些的话,需要&require("cocos.ui.GuiConstants")。
  我们在实际的项目开发中,肯定会遇到很多问题,当然,遇到问题我们可以在网上找,但是并不是所有的问题都能找到,所以,自己动手解决问题的能力很重要,
对于我们来说,去看源码,看具体的实现,就能很快找到解决问题的方式。
如果有什么问题,请加我的QQ,或者群: 。大家一起学习。
阅读(...) 评论()1500人阅读
cocos2dx(20)
& 最近试用了下cocos ide,然后引擎用的cocos2dx js 3 final,需要build runtime一下,下面是cocos studio相关的一些事件:
& 添加事件侦听:
var root = ccs.uiReader.widgetFromJsonFile(&res/UIButton_Editor/UIButton_Editor_1.json&);
this.addChild(root);
var back_label = ccui.helper.seekWidgetByName(root, &back&);
back_label.addTouchEventListener(this.backEvent,this);
var button = ccui.helper.seekWidgetByName(root, &Button_123&);
button.addTouchEventListener(this.touchEvent,this);
var title_button = ccui.helper.seekWidgetByName(root, &Button_126&);
title_button.addTouchEventListener(this.touchEvent,this);
var scale9_button = ccui.helper.seekWidgetByName(root, &Button_129&);
scale9_button.addTouchEventListener(this.touchEvent,this);
// check box
var root = ccs.uiReader.widgetFromJsonFile(&res/UICheckBox_Editor/ui_checkbox_editor_1.json&);
this.addChild(root);
var checkbox = ccui.helper.seekWidgetByName(root, &CheckBox_540&);
cc.log(checkbox.addEventListener);
checkbox.addEventListener(this.selectedStateEvent,this);
// list view
var LISTVIEW_RES = [
&res/UIListView_Editor/UIListView_Vertical_Editor/ui_listview_editor_1.json&,
&res/UIListView_Editor/UIListView_Horizontal_Editor/ui_listview_horizontal_editor_1.json&
var root = ccs.uiReader.widgetFromJsonFile(LISTVIEW_RES[0]);
this.addChild(root);
var listView = ccui.helper.seekWidgetByName(root, &ListView_1214&);
listView.addEventListener(this.selectedItemEvent,this);
// page view
var root = ccs.uiReader.widgetFromJsonFile(&res/UIPageView_Editor/ui_pageview_editor_1.json&);
this.addChild(root);
var pageView =ccui.helper.seekWidgetByName(root, &PageView_1269&);
pageView.addEventListener(this.pageViewEvent, this);
// RichText
var richText = ccui.RichText.create();
richText.ignoreContentAdaptWithSize(false);
richText.setContentSize(cc.size(120, 100));
var re1 = ccui.RichElementText.create(1, cc.color.WHITE, 255, &This color is white. &, &Helvetica&, 10);
var re2 = ccui.RichElementText.create(2, cc.color.YELLOW, 255, &And this is yellow. &, &Helvetica&, 10);
var re3 = ccui.RichElementText.create(3, cc.color.BLUE, 255, &This one is blue. &, &Helvetica&, 10);
var re4 = ccui.RichElementText.create(4, cc.color.GREEN, 255, &And green. &, &Helvetica&, 10);
var re5 = ccui.RichElementText.create(5, cc.color.RED, 255, &Last one is red &, &Helvetica&, 10);
var re6 = ccui.RichElementText.create(7, cc.color.ORANGE, 255, &Have fun!! &, &Helvetica&, 10);
richText.pushBackElement(re1);
richText.insertElement(re2, 1);
richText.pushBackElement(re3);
richText.pushBackElement(re4);
richText.pushBackElement(re5);
richText.pushBackElement(re6);
richText.setPosition(cc.p(1280 / 2, 720 / 2));
this.addChild(richText);
var root = ccs.uiReader.widgetFromJsonFile(&res/UISlider_Editor/ui_slider_editor_1.json&);
this.addChild(root);
var slider = ccui.helper.seekWidgetByName(root, &Slider_738&);
slider.addEventListener(this.sliderEvent,this);
var scale9_slider = ccui.helper.seekWidgetByName(root, &Slider_740&);
scale9_slider.addEventListener(this.sliderEvent,this);
// text field
var root = ccs.uiReader.widgetFromJsonFile(&res/UITextField_Editor/ui_textfield_editor_1.json&);
this.addChild(root);
var textField_normal = ccui.helper.seekWidgetByName(root, &TextField_1109&);
textField_normal.addEventListener(this.textFieldEvent,this);
var textField_max_character = ccui.helper.seekWidgetByName(root, &TextField_1110&);
textField_max_character.addEventListener(this.textFieldEvent,this);
var textField_password = ccui.helper.seekWidgetByName(root, &TextField_1107&);
textField_password.addEventListener(this.textFieldEvent,this);
& 各个事件回调:
touchEvent: function (sender, type) {
switch (type) {
case ccui.Widget.TOUCH_BEGAN:
cc.log(&Touch Down&);
case ccui.Widget.TOUCH_MOVED:
cc.log(&Touch Move&);
case ccui.Widget.TOUCH_ENDED:
cc.log(&Touch Up&);
case ccui.Widget.TOUCH_CANCELED:
cc.log(&Touch Cancelled&);
// check box
selectedStateEvent: function (sender, type) {
switch (type) {
case ccui.CheckBox.EVENT_SELECTED:
cc.log(&Selected&);
case ccui.CheckBox.EVENT_UNSELECTED:
cc.log(&Unselected&);
// list view
selectedItemEvent: function (sender, type) {
switch (type) {
case ccui.ListView.EVENT_SELECTED_ITEM:
var listViewEx =
cc.log(&select child index = & + listViewEx.getCurSelectedIndex());
// page view
pageViewEvent: function (sender, type) {
switch (type) {
case ccui.PageView.EVENT_TURNING:
var pageView =
cc.log(&page = & + (pageView.getCurPageIndex() + 1));
sliderEvent: function (sender, type) {
switch (type) {
case ccui.Slider.EVENT_PERCENT_CHANGED:
var slider =
var percent = slider.getPercent();
cc.log(&Percent & + percent.toFixed(0));
// text field
textFieldEvent: function (sender, type) {
switch (type) {
case ccui.TextField. EVENT_ATTACH_WITH_IME:
cc.log(&attach with IME&);
case ccui.TextField. EVENT_DETACH_WITH_IME:
cc.log(&detach with IME&);
case ccui.TextField. EVENT_INSERT_TEXT:
cc.log(&insert words&);
case ccui.TextField. EVENT_DELETE_BACKWARD:
cc.log(&delete word&);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:69674次
积分:1455
积分:1455
排名:千里之外
原创:73篇
评论:17条
(1)(5)(1)(1)(5)(2)(3)(7)(2)(3)(4)(5)(1)(1)(1)(2)(3)(4)(1)(2)(2)(2)(3)(8)(4)(1)(4)(4)}

我要回帖

更多关于 cocostudio lua 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信