在cocos2d-js实现自动绑定cocostudioUI控件与事件(三)

一、为cc.Node类型节点注册触摸事件

演示常规方式为cc.Node类型注册触摸事件

ctor: function() {
   ...
   this._label = new ...
   cc.eventManager.addListener({
                event: cc.EventListener.TOUCH_ONE_BY_ONE,
                swallowTouches: true,
                onTouchBegan: this.onTouchBegan,
                onTouchMoved: this.onTouchMoved,
                onTouchEnded: this.onTouchEnded
            }, this);
   ...
  },
  onTouchBegan: function(touch, event) {
      //更新label文字
      this._label.setString(‘onTouchBegan‘);
  },
  onTouchMoved: function(touch, event) {
      //更新label文字
      this._label.setString(‘onTouchMoved‘);
  }
  onTouchEnded: function(touch, event) {
      //更新label文字
      this._label.setString(‘onTouchEnded‘);
  }

以上代码中使用cc.eventManager为当前cc.Node对象注册触摸事件,共需要7行代码。而事件处理函数中,想访问成员变量”_label”, 但使用this._label是却是常见的错误写法。要想正常访问当前成员变量,需要如下修改

onTouchBegan: function(touch, event) {
    //需要从event参数中获取当前target对象,target才正是当前layer
    var target = event.getCurrentTarget();
    target._label.setString(‘onTouchBegan‘);
}

分析理解 :

1.当前this对象为cc.eventManager.addListener的第一个参数。

2.event.getCurrentTarget()对像为cc.eventManager.addListener的第二个参数。

所以要访问当前layer上下文时不能简单的在事件处理函数中使用this.xxx。

一般做过c++的人都知道,类成员函数中使用this表示当前类实例对象,但在js中的this对象是会随函数调用的不同而不同。如何能像c++或cocos2d-x一样的思维方式来编写代码,在事件响应函数中使用this就能访问到当前类实例对象呢?

ctor: function() {
   ...
   this._label = new ...
   var self = this;
   cc.eventManager.addListener({
                event: cc.EventListener.TOUCH_ONE_BY_ONE,
                swallowTouches: true,
                //注意这里
                onTouchBegan: function(touch, event) {
                    return self.onTouchBegan(touch, event);
                }
            }, this);
   ...
  },
  onTouchBegan: function(touch, event) {
      //更新label文字
      this._label.setString(‘onTouchBegan‘);
  },

以上代码请大家自己分析,touchMoved\touchEnded事件我没有给出代码请自己补全。

总结:

1.代码较多,当需要为较多cc.Node类型控件注册事件时,代码很难看。

2. 初学者经常会遇到控件事件的this上下文混乱问题,容易出错。

3. 与ccui.Widget类型组件的触摸事件接口不太一至,初学者上手困难。

我的解决思路与方案:

  1. 减少代码量,一行代码注册事件。
  2. 尽量统一ccui.Widget与cc.Node两种类型组件的触摸事件函数。
  3. 尽量保持原始API的功能接口,减少学习使用成本。

sz.uiloader.registerTouchEvent:

代码演示:为当前this对象注册触摸事件

ctor: function() {
    ...
    //为当前this对象注册触摸事件
    sz.uiloader.registerTouchEvent(this);
},
//当前对象事件响应函数
_onTouchBegan = function(sender, touch, event) {
    ...
    return true;
}

代码演示:为某个cc.Node对象注册触摸事件

ctor: function() {
    ...
    var this._button = ...
    //需要为节点设置name
    this._button.setName(‘_button‘);
    //第一个参数为触摸节点,第二个参数为事件响应对象
    sz.uiloader.registerTouchEvent(this._button, this);
},
//button节点响应函数,注意函数命名写法:前缀+name+事件名,驼峰命名
_onButtonTouchBegan = function(sender, touch, event) {
    ...
    this._button.setPosition(...)
    return true;
}

二、sz.UILoader增加对 cocostudio2.1的支持

cocos2d-js 3.3已经发布,同时支持了cocostudio2.1 UI编辑器。我简单试玩了下cocostudio2.1很像之前的cocosbuilder编辑器,从资源窗口、动画窗口 、属性窗口等。其中感觉最有用的就是UI界面可以相互嵌套。

UILoader对cocostudio2的支持其实是很容易的,但cocostudio2中UI编辑时可以相互嵌套,嵌套节点为cc.Node类型。这是与1.x版本不一样的。

1.x版本生成的UIl界面全部为ccui.Widget类型节点构成

2.x版本生成的UI界面大部分为ccui.Widget类型,在嵌套时会包裹一个cc.Node节点。

这就是为什么要在sz.UILoader中先实现cc.Node节点的事件响应的原因。

github代码已经更新,增加了cocostudio2的加载演示与事件处理。

目前没有经常严格测试,有兴趣的朋友可以看看,欢迎指正。

源码地址: https://github.com/ShawnZhang2015/UILoader

时间: 2024-08-26 12:39:55

在cocos2d-js实现自动绑定cocostudioUI控件与事件(三)的相关文章

在cocos2d-js实现自动绑定cocostudioUI控件与事件(二)

前两天有个刚学习使用cocos2d-js的同事问我,怎么实现一个功能:点击一个按钮UI显示计数加1,按住不放UI计数就不停的加. 这个功能不就是个长按事件吗?我给他描述了下实现长按事件的思路: 1. 在控件touchBegan时,使用 一次性定时器scheduleOnce传入touchLong函数,设定1秒后执行. 2.  touchLong触发时,开启schedule传入addOnce函数(ui显示计数加1),设定每0.1秒执行一次. 3.  在touchEnded时执行unschedule函

在cocos2d-js实现自动绑定cocostudioUI控件与事件

一.起因 在客户端游戏开发中最让人恶心的工作就是UI相关的东西,虽然有了像cocostudio这样的可视化工具,但界面中有大量需要由代码访问的控件的时候,需要写太多重复的代码例如: //加载UI配置文件 var root = ccs.uiReader.widgetFromJsonFile("res/cocosui/UIEditorTest/UIButton_Editor/UIButton_Editor_1.json"); this._mainNode.addChild(root); /

纯js模拟 radio和checkbox控件

代码待优化,功能实现了,不兼容ie8以上, 相同name的radio可以实现切换的操作, 分享代码,共同学习进步 <!doctype html> <html> <head> <meta charset="utf-8"> <title></title> <style> .radiobox, .checkbox { width: 10px; height: 10px; padding: 2px; borde

java android布局里的控件值 反射绑定给实体类,实体类绑定给控件,表单提交绑定很有用

注意了:根据实际情况,添加实体里字段的类型,控件类型的判断才可使用.这里控件只有TextView EditText 实体类字段只有String int类型,带值的控件添加tag ,值和实体类的字段值一致 package ice.ui.service; import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import jav

Js获取file上传控件的文件路径总结

总结一个获取file上传控件文件路径的方法 firefox由于保护机制只有文件名,不能获取完整路径. document.getElementById('file').onchange = function(){ alert(getFullPath(this)) } function getFullPath(obj){ if(!obj){return;} if(!-[1,]){obj.select();return document.selection.createRange().text;} r

winfrom中DataGridView绑定数据控件中DataGridViewCheckBoxColumn怎么选中

for (int i = 0; i < this.dataGridView1.Rows.Count; i++) { this.dataGridView1.Rows[i].Cells["CheckBoxCulums"].Value = this.checkBox1.Checked; } winfrom中DataGridView绑定数据控件中DataGridViewCheckBoxColumn怎么选中,布布扣,bubuko.com

pb自动注册ole控件

方法一:  1.手工注册OCX控件 将该控件随程序一起发布,然后,将此文件拷到windows\system,或者直接放在本运行目录,然后执行dos命令,run( "regsvr32   *.ocx ") *表示具体的文件.然后写注册表,将控件注册标志置为1,在程序开始运行时,先检查该标志,是否需要进行注册 2.自动注册OCX控件 在OCX控件中一般都包含一个DLLRegisterServer函数,可以用此函数来实现OCX控件自动注册. 例如:我们要在应用中自动注册ActiveMovie

WPFS数据绑定(要是后台类对象的属性值发生改变,通知在“client界面与之绑定的控件值”也发生改变须要实现INotitypropertyChanged接口)

WPFS数据绑定(要是后台类对象的属性值发生改变,通知在"client界面与之绑定的控件值"也发生改变须要实现INotitypropertyChanged接口) MainWindow.xaml <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="

【Javascript】JS获取ASP.NET CheckBoxList控件的Text和Value

由于在客户端用js是无法直接获取到ASP.NET的控件CheckboxList的值的,所以采用以下解解方案: 服务器端代码: public void LoadAllTags() { var tagList = tagBO.GetAllTags(); cbTagList.DataSource = tagList; cbTagList.DataTextField = "TagName"; cbTagList.DataValueField = "Id"; cbTagLis