cocos2dx 3.10 版本提供了 cocos studio 界面导出到 lua 的功能,同时内置了一套基本的 MVC 框架。在此基础上进行代码改进,实现了以下几项功能:
- 无需手动填写
RESOURCE_BINDING的内容。 - Button 自动根据 UI 名字绑定对应的函数。例如按钮命名为
btnClose,其单击事件会自动绑定到函数ui_btnCloseClicked。只需在 cocostudio 中重命名按钮,再在 lua 脚本中添加对应的ui_btnCloseClicked函数即可。 - UI 元素自动绑定到 table 成员。例如有一个名为
txtTips的元素,在 lua 脚本中可以直接使用self.ui.txtTips:setString("11"),方便快速开发。
使用示例:添加一个新按钮的流程
- 在 cocostudio 中添加一个名为
btnNew的按钮,并导出资源为 lua 格式。 - 在
MainScene.lua中添加函数ui_btnNewClicked,该函数即为按钮点击事件的回调。
重构后的代码
MainScene.lua
local t = class("MainScene", cc.load("mvc").ViewBase)
t.RESOURCE_FILENAME = "res/MainScene.lua"
t.RESOURCE_BINDING =
{
-- ["Button_1"]={["varname"]="Button_1",["events"]={{["event"]="touch",["method"]="onBtnTouch"}}},
-- ["Text_1"] = {["varname"] = "txt_info"},
-- ["Panel"] = {["varname"] = "Panel"},
};
function t:onCreate()
printf("resource node = %s", tostring(self:getResourceNode()))
end
function t:ui_btnCloseClicked()
print(" close");
end
function t:ui_btnSendClicked()
print(" send");
self.counter =(self.counter and self.counter + 1) or 0;
self.ui.txtInfo:setString("12344 " .. self.counter);
end
function t:ui_Panel_Panel2_btnShowClicked()
print(" pp show");
end
function t:ui_Panel_btnShowClicked()
print("show " .. self.counter);
end
return t
ViewBase.lua
function ViewBase:ctor(app, name)
self:enableNodeEvents()
self.app_ = app
self.name_ = name
-- check CSB resource file
local res = rawget(self.class, "RESOURCE_FILENAME")
if res then
self:createResoueceNode(res)
end
local binding = rawget(self.class, "RESOURCE_BINDING")
if res and binding then
self:createResoueceBinding(binding)
end
if self.onCreate then self:onCreate() end
self.ui = { };
self.ui.root = self.resourceNode_;
self:autoBind(self.resourceNode_);
end
function ViewBase:getFullParentName(node)
local parent = "";
if node and node ~= self.ui.root then
local tmp = node;
while tmp:getParent() ~= self.ui.root do
parent = tmp:getParent():getName() .. "_" .. parent;
tmp = tmp:getParent();
end
end
return parent;
end
function ViewBase:autoBind(node)
for _, v in pairs(node:getChildren()) do
print(v:getName());
local node_name = v:getName();
if string.find(node_name, "btn") then
-- bind button
v:onTouch( function(e)
if e.name == "ended" then
local name = self:getFullParentName(v) .. node_name .. "Clicked";
local cb = self["ui_" .. name];
if cb then
cb(self);
else
end
end
end );
end
self.ui[self:getFullParentName(v) .. node_name] = v;
-- bind var
self:autoBind(v);
-- bind child
end
end