在cocos2d-js实现自动绑定cocostudioUI控件与事件
一.起因
在客户端游戏开发中最让人恶心的工作就是UI相关的东西,虽然有了像cocostudio这样的可视化工具,但界面中有大量需要由代码访问的控件的时候,需要写太多重复的代码例如:
//加载UI配置文件 var root = ccs.uiReader.widgetFromJsonFile("res/cocosui/UIEditorTest/UIButton_Editor/UIButton_Editor_1.json"); this._mainNode.addChild(root); //查询back控件,并添事件响应 var back_label = ccui.helper.seekWidgetByName(root, "back"); back_label.addTouchEventListener(this.backEvent,this); //查询Button_123控件,并添事件响应 var button = root.getChildByName(root, "Button_123"); button.addTouchEventListener(this.touchEvent,this);</span>
void on_控件名_信号名(参数);
ccui.Widget.TOUCH_CANCELED 触摸取消 (一般没用)
ctor: function() { this._super(); ... button.addTouchEventListener(this._onButtonEvent, this); }, _onButtonEvent: function(sender, type) { switch(type) { case ccui.Widget.TOUCH_BEGAN: ...; return true; case ccui.Widget.TOUCH_MOVED: ...; break; case ccui.Widget.TOUCH_ENDED: ...; break; } }
这个"_onButtonEvent"就是我们为事件函数取的名字,如果我们按:【前缀+控件名(取掉下划线)+事件名】给控件事件函数取名
//触摸事件 sz.UILoader.touchEvents = ["TouchBegan", "TouchMoved", "TouchEnded"]; //控件事件列表 sz.UILoader.widgetEvents = [ //Button {widgetType: ccui.Button, events: sz.UILoader.touchEvents}, //ImageView {widgetType: ccui.ImageView, events: sz.UILoader.touchEvents}, //TextFiled {widgetType: ccui.TextField, events: ["AttachWithIME", "DetachWithIME", "InsertText", "DeleteBackward"]}, //CheckBox {widgetType: ccui.CheckBox, events: ["Selected", "Unselected"]}, //ListView {widgetType: ccui.ListView, events:["SelectedItem"]}, //Panel {widgetType: ccui.Layout, events: sz.UILoader.touchEvents}, //BMFont {widgetType: ccui.TextBMFont, events: sz.UILoader.touchEvents}, //last must null null ];
3). 将childNode绑定到target上。
4). 提取childNode事件函数名,检查target是否有这些函数存在。
5). 为widgetNode注册事件响应。
sz.UILoader = cc.Class.extend({ _eventPrefix: null, _memberPrefix: null, /** * 加载UI文件 * @param target将 jsonFile加载出的节点绑定到的目标 * @param jsonFile cocostudio UI编辑器生成的json文件 */ widgetFromJsonFile: function(target, jsonFile, options) { cc.assert(target && jsonFile); if (!options) { options = {}; } this._eventPrefix = options.eventPrefix || sz.UILoader.DEFAULT_EVENT_PREFIX; this._memberPrefix = options.memberPrefix || sz.UILoader.DEFAULT_MEMBER_PREFIX; var rootNode = ccs.uiReader.widgetFromJsonFile(jsonFile); if (!rootNode) { cc.log("Load json file failed"); } target.rootNode = rootNode; target.addChild(rootNode); this._bindMenbers(rootNode, target); }, /** * 递归对rootWidget下的子节点进行成员绑定 * @param rootWidget * @param target * @private */ _bindMenbers: function(rootWidget, target) { var widgetName, children = rootWidget.getChildren(); var self = this; children.forEach(function(widget) { widgetName = widget.getName(); //控件名存在,绑定到target上 var prefix = widgetName.substr(0, self._memberPrefix.length); if (prefix === self._memberPrefix) { target[widgetName] = widget; self._registerWidgetEvent(target, widget); } //绑定子控件,可以实现: a._b._c._d 访问子控件 if (!rootWidget[widgetName]) { rootWidget[widgetName] = widget; } //如果还有子节点,递归进去 if (widget.getChildrenCount()) { self._bindMenbers(widget, target); } }); }, /** * 获取控件事件 * @param widget * @returns {*} */ _getWidgetEvent: function(widget) { var bindWidgetEvent = null; var events = sz.UILoader.widgetEvents; for (var i = 0; i < events.length; i++) { bindWidgetEvent = events[i]; if (widget instanceof bindWidgetEvent.widgetType) { break; } } return bindWidgetEvent; }, /** * 注册控件事件 * @param target * @param widget * @private */ _registerWidgetEvent: function(target, widget) { var name = widget.getName(); //截取前缀,首字母大写 var newName = name[this._memberPrefix.length].toUpperCase() + name.slice(this._memberPrefix.length + 1); var eventName = this._eventPrefix + newName + "Event"; var isBindEvent = false; if (target[eventName]) { isBindEvent = true; } else { //取事控件件名 var widgetEvent = this._getWidgetEvent(widget); if (!widgetEvent) { return; } //检查事函数,生成事件名数组 var eventNameArray = []; for (var i = 0; i < widgetEvent.events.length; i++) { eventName = this._eventPrefix + newName + widgetEvent.events[i]; eventNameArray.push(eventName); if (cc.isFunction(target[eventName])) { isBindEvent = true; } } } //事件响应函数 var self = this; var eventFunc = function(sender, type) { var callBack; if (eventNameArray) { var funcName = eventNameArray[type]; callBack = target[funcName]; } else { callBack = target[eventName]; } if (self._onWidgetEvent) { self._onWidgetEvent(sender, type); } if (callBack) { return callBack.call(target, sender, type); } }; //注册事件监听 if (isBindEvent) { widget.setTouchEnabled(true); if (widget.addEventListener) { widget.addEventListener(eventFunc, target); } else { widget.addTouchEventListener(eventFunc, target); } } } }); sz.uiloader = new sz.UILoader();
GameLayer = cc.Layer.extend({ ctor: function() { this._super(); //加载UI文件,绑定控件和事件到this sz.uiloader.widgetFromJsonFile(this, "res/DemoLogin.ExportJson"); //立即可以访问控件的属性方法了 cc.log(this._closeButton.getName()); }, /* * _closeButton的TouchBegan事件处理函数 */ _onCloseButtonTouchBegan: function(sender) { cc.log("_onCloseButtonTouchBegan"); }, });
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。