cocos2dx(3.17)中csb文件使用方法
2023-06-13 09:16:26 时间
开发环境:xcode 、vscode 开发语言:lua
一、手写代码加载csb文件,并获取控件
--加载csb场景文件,并将场景添加到节点中。
local node = cc.CSLoader:createNode("MenuScene.csb")
self:addChild(node)
--获取场景中的根节点(场景的跟节点一般是容器)
local rootLayout = node:getChildByName("Panel_2")
--强制转换,目前还没搞懂为啥要强制转换,可有可无,测试不写这串代码,一样可以获取到它的子节点。
-- local rootNode = tolua.cast(root, "ccui.Widget")
--获取控件(按钮 复选框 图片 文本 进度条 滑动条 出入框等)
local button =rootLayout:getChildByName("Button_2")
--给控件添加事件(不同控件,他的事件类型不同,使用的方法也就不同,),下面是给按钮添加点击事件
button:addClickEventListener(function(sender,eventType)
print("点击了开始按钮")
end)
控件的通用事件
一般想封装控件的通用事件的话,可以通过addTouchEventListener(sender,eventType)
来添加事件,下面示例:
--[[
btn 控件本身对象
ended 事件类型(放开)对应的回调函数
began 事件类型(按下)对应的回调函数
moved 事件类型(移动)对应的回调函数
canceled 事件类型(取消)对应的回调函数
]]
function cc.exports.setButtonFunction(btn, ended, began, moved, canceled)
btn:addTouchEventListener(function(sender, eventType)
if eventType == ccui.TouchEventType.began then
if began then began(sender) end
elseif eventType == ccui.TouchEventType.ended then
if ended then ended(sender) end
elseif eventType == ccui.TouchEventType.moved then
if moved then moved(sender) end
elseif eventType == ccui.TouchEventType.canceled then
if canceled then canceled(sender) end
end
end)
end
二、通过mvc ViewBase加载csb文件
博主一般都采用这种方法
local MainScene = class("MainScene",cc.load("mvc").ViewBase)
MainScene.RESOURCE_FILENAME="MenuScene.csb" --自己在cocos studio上建立的csb文件导入工程文件res文件夹下面
MainScene.RESOURCE_BINDING = {
["Button_2"] = {
["varname"] = "bn_StartGame",
["events"] = {
{
event = "touch" ,
method ="onBack"
}
}
}
}
funcation MainScene:ctor()
self.bn_StartGame:addClickEventListener(function(sender,eventType)
print("点击了开始按钮")
end)
end
funcation MainScene:onBack()
print("触摸了")
end
return MainScene
1、MainScene.RESOURCE_FILENAME=”MenuScene.csb”
这个变量是设置场景的csb文件名称,读取时在ViewBase类中读取的 下面会讲一下ViewBase类怎么读取的。
2、MainScene.RESOURCE_FILENAME
这个变量是设置绑定控件,获取控件的实例
MainScene.RESOURCE_BINDING = {
["Button_2"] = {
["varname"] = "bn_StartGame",
["events"] = {
{
event = "touch" ,
method ="onBack"
}
}
}
}
使用方式模板(两种方式):
MainScene.RESOURCE_BINDING =
{
--不添加事件
["cocos控件名"] = {["varname"] = "引用变量名" }
--添加事件
["cocos控件名"] = {["varname"] = "引用变量名",["events"]={{["event"]="事件类型(原生现在支持一种)",["method"]="回调函数"},...}}
}
获取子控件
self.root = self:getResourceNode()
local Button = self.root:getChildByName("Button_1")
三、ViewBase类源码讲解 源码示例:
local ViewBase = class("ViewBase", cc.Node)
function ViewBase:ctor(app, name)
self:enableNodeEvents()
self.app_ = app
self.name_ = name
-- 检查子类中是否设置RESOURCE_FILENAME属性,并得到他的value值
local res = rawget(self.class, "RESOURCE_FILENAME")
if res then
--加载csb文件
self:createResourceNode(res)
end
--检查子类中是否设置RESOURCE_BINDING属性,并得到他的value值
local binding = rawget(self.class, "RESOURCE_BINDING")
if res and binding then
--获取控件的实例
self:createResourceBinding(binding)
end
--判断子类有没有重写onCreate方法,有,调用子类的onCreate方法
if self.onCreate then self:onCreate() end
end
function ViewBase:getApp()
return self.app_
end
function ViewBase:getName()
return self.name_
end
function ViewBase:getResourceNode()
return self.resourceNode_
end
--[[
*加载csb文件的方法
*resourceFilename 文件名称(带后缀名)
]]
function ViewBase:createResourceNode(resourceFilename)
--判断是否已经加载过csb文件
if self.resourceNode_ then
--移除自己
self.resourceNode_:removeSelf()
--设置为nil
self.resourceNode_ = nil
end
--通过CSLoader加载csb文件,得到一个节点
self.resourceNode_ = cc.CSLoader:createNode(resourceFilename)
assert(self.resourceNode_, string.format("ViewBase:createResourceNode() - load resouce node from file \"%s\" failed", resourceFilename))
--将节点添加到该父节点(场景,层)中
self:addChild(self.resourceNode_)
end
--[[
*绑定控件
*binding 在ViewBase子类中设置的RESOURCE_BINDING(规则模板(表))
]]
function ViewBase:createResourceBinding(binding)
assert(self.resourceNode_, "ViewBase:createResourceBinding() - not load resource node")
--遍历规则表
for nodeName, nodeBinding in pairs(binding) do
--节点通过名称直接获取子控件实例
--这里就是我上面说的问题所在了,这里是直接通过根节点获取控件,往往,根节点的子节点是容器,而不是控件,所以这里会得不到控件
local node = self.resourceNode_:getChildByName(nodeName)
--如果设置变量名不为nil
if nodeBinding.varname then
--则将node赋值类nodeBinding.varname变量
self[nodeBinding.varname] = node
end
--遍历规则表中的事件
--nodeBinding.events or {}这个表达式相当于三目运算 nodeBinding.events~=nil?nodeBinding.events:{}
for _, event in ipairs(nodeBinding.events or {}) do
--原生这里只支持touch事件,如果有别的需求可自行添加
if event.event == "touch" then
--给控件设置onTouch事件并设置回调函数。
node:onTouch(handler(self, self[event.method]))
end
end
end
end
--[[
*跳转场景(翻译:展示场景)
*transition 衔接动画
*time 衔接动画播放时间
*more 动画类型
]]
function ViewBase:showWithScene(transition, time, more)
self:setVisible(true)
local scene = display.newScene(self.name_)
scene:addChild(self)
display.runScene(scene, transition, time, more)
return self
end
return ViewBase
修改
createResourceBinding
方法,达到可以使用RESOURCE_BINDING
来绑定控件事件的目的(修复原生方法不能绑定使用容器包裹的控件的问题。)
--新增一个dom树表,用于存储dom树各个节点
ViewBase.dom = {}
--[[
*递归遍历整个场景树中的容器和控件,将容器和控件存入dom表中
*rootNode 节点类型
]]
local function recursionChlidNOde(rootNode)
local children = rootNode:getChildren()
for _,childNOde in ipairs(children or {}) do
local name =childNOde:getName()
print("name ",name)
ViewBase.dom[name]=childNOde
recursionChlidNOde(childNOde)
end
end
function ViewBase:createResourceBinding(binding)
assert(self.resourceNode_, "ViewBase:createResourceBinding() - not load resource node")
recursionChlidNOde(self.resourceNode_)
for bindWidgetName, ruleTable in pairs(binding) do
for widgetName,node in pairs(ViewBase.dom) do
print(widgetName,tolua.type(node))
if ruleTable.varname and widgetName==bindWidgetName then
self[ruleTable.varname] = node
for _, event in ipairs(ruleTable.events or {}) do
if event.event == "touch" then
node:onTouch(handler(self, self[event.method]))
end
end
end
end
end
end
相关文章
- python判断linux中文件是否存在_Python判断文件是否存在的三种方法
- dos下拷贝服务器文件命令行,win7在DOS环境下怎么使用copy命令?使用copy命令复制文件的方法…[通俗易懂]
- 关于MATLAB读取txt文件的方法[通俗易懂]
- Linux下文件修改立即生效的方法(linux修改文件生效)
- 编译使用Linux C编译多个文件的方法(linuxc多文件)
- 快速运行Linux下sh文件的方法(linux运行sh文件)
- Linux中快速复制与重命名文件的方法(linux复制重命名)
- 用开源软件保护你的文件的 5 种方法
- Linux批量打开文件的简单方法(linux同时打开文件)
- Linux系统中文件打包的方法(文件打包linux)
- 量 Linux查看文件数量的实现方法(linux查看文件数)
- MySQL快速导入txt文件的简单方法(mysql导入txt文件)
- Linux下快捷编辑大文件的方法(linux编辑大文件)
- 解决方法MySQL无法读取INI文件的问题(mysql不加载ini)
- MySQL上传文件指令的使用方法(mysql上传文件指令)
- Oracle7.X回滚表空间数据文件误删除处理方法
- php上传文件中文文件名乱码的解决方法
- js加载之使用DOM方法动态加载Javascript文件
- c#实现数据同步的方法(使用文件监控对象filesystemwatcher)
- phonegap教程使用jspdf库在应用中生成pdf文件(pdf生成方法)
- android开发教程之系统资源的使用方法android资源文件
- PHP使用feof()函数读文件的方法
- php使用file_get_contents读取大文件的方法