前言:
事件处理是在节点( cc.Node )中完成的。对于组件,可以通过访问节点 this.node 来注册和监听事件,监听事件可以 通过this.node.on()
函数来注册。当我们不再关心某个事件时,我们可以使用 off 方法关闭对应的监听事件。我们可以通过两种方式发射事件:emit
和 dispatchEvent
,两者的区别在于,后者可以做事件传递。Cocos Creator 支持的系统事件包含鼠标、触摸、键盘、重力传感四种。
事件监听:
事件监听函数 on 可以传第三个参数 target
,用于绑定响应函数的调用者。以下两种调用方式, 效果上是相同的:
// 使用函数绑定
this.node.on('mousedown', function ( event ) {
this.node.color=cc.Color.RED;
}.bind(this));
// 使用第三个参数
this.node.on('mousedown', function ( event ) {
this.node.color=cc.Color.RED;
},this);
除了使用 on 监听,我们还可以使用 once 方法。 once 监听在监听函数响应后就会关闭监听事件。
事件关闭:
当我们不再关心某个事件时,我们可以使用 off 方法关闭对应的监听事件。需要注意的是, off 方法的 参数必须和 on 方法的参数一一对应,才能完成关闭。
注意: 我们要关闭事件监听,需要我们保存回调函数
。
// 保存回调函数
mySayhello: function () {
console.log('Hello World');
},
// 监听事件
onEnable: function () {
this.node.on('mousedown', this.mySayhello, this);
},
// 关闭事件
onDisable: function () {
this.node.off('mousedown', this.mySayhello, this);
},
触摸事件在移动平台和桌面平台都会触发,只需要监听触摸事件即可同时响应移动平台的触摸事件和桌面端的鼠标事件
。系统提供的触摸事件类型如下:
枚举对象定义 | 对应的事件名 | 事件触发的时机 |
---|---|---|
cc.Node.EventType.TOUCH_START |
touchstart | 当手指触点落在目标节点区域内时 |
cc.Node.EventType.TOUCH_MOVE |
touchmove | 当手指在屏幕上目标节点区域内移动时 |
cc.Node.EventType.TOUCH_END |
touchend | 当手指在目标节点区域内离开屏幕时 |
cc.Node.EventType.TOUCH_CANCEL |
touchcancel | 当手指在目标节点区域外离开屏幕时 |
触摸事件( cc.Event.EventTouch )的重要 API
如下( cc.Event 标准事件 API 之外):
API 名 | 类型 | 意义 |
---|---|---|
touch |
cc.Touch | 与当前事件关联的触点对象 |
getID |
Number | 获取触点的 ID,用于多点触摸的逻辑判断 |
getLocation |
Object | 获取触点位置对象,对象包含 x 和 y 属性 |
getLocationX |
Number | 获取触点的 X 轴位置 |
getLocationY |
Number | 获取触点的 Y 轴位置 |
getPreviousLocation |
Object | 获取触点上一次触发事件时的位置对象,对象包含 x 和 y 属性 |
getStartLocation |
Object | 获取触点初始时的位置对象,对象包含 x 和 y 属性 |
getDelta |
Object | 获取触点距离上一次事件移动的距离对象,对象包含 x 和 y 属性 |
需要注意的是,触摸事件支持多点触摸,每个触点都会发送一次事件给事件监听器。
this.node.on('touchmove', function ( event ) {
this.node.color=cc.Color.RED;
console.log(event.getLocation()); // 获得触摸位置
console.log(event.getDelta()); // 获得X Y位置与上次变化了多少
console.log(event.getID); // 在多点触控时获得ID号
event.stopPropagation(); //停止事件冒泡
}.bind(this));
触摸事件的冒泡过程与普通事件的冒泡过程并没有区别,可以调用event.stopPropagation()
可以主动停止冒泡过程。
鼠标事件在桌面平台才会触发,系统提供的事件类型如下:
枚举对象定义 | 对应的事件名 | 事件触发的时机 |
---|---|---|
cc.Node.EventType.MOUSE_DOWN |
mousedown | 当鼠标在目标节点区域按下时触发一次 |
cc.Node.EventType.MOUSE_ENTER |
mouseenter | 当鼠标移入目标节点区域时,不论是否按下 |
cc.Node.EventType.MOUSE_MOVE |
mousemove | 当鼠标在目标节点在目标节点区域中移动时,不论是否按下 |
cc.Node.EventType.MOUSE_LEAVE |
mouseleave | 当鼠标移出目标节点区域时,不论是否按下 |
cc.Node.EventType.MOUSE_UP |
mouseup | 当鼠标从按下状态松开时触发一次 |
cc.Node.EventType.MOUSE_WHEEL |
mousewheel | 当鼠标滚轮滚动时 |
鼠标事件( cc.Event.EventMouse )的重要API
如下( cc.Event 标准事件 API 之外):
函数名 | 返回值类型 | 意义 |
---|---|---|
getScrollY |
Number | 获取滚轮滚动的 Y 轴距离,只有滚动时才有效 |
getLocation |
Object | 获取鼠标位置对象,对象包含 x 和 y 属性 |
getLocationX |
Number | 获取鼠标的 X 轴位置 |
getLocationY |
Number | 获取鼠标的 Y 轴位置 |
getPreviousLocation |
Object | 获取鼠标事件上次触发时的位置对象,对象包含 x 和 y 属性 |
getDelta |
Object | 获取鼠标距离上一次事件移动的距离对象,对象包含 x 和 y 属性 |
getButton |
Number | cc.Event.EventMouse.BUTTON_LEFT 或 cc.Event.EventMouse.BUTTON_RIGHT 或 cc.Event.EventMouse.BUTTON_MIDDLE |
键盘、设备重力传感器此类全局事件是通过函数 cc.systemEvent.on(type, callback, target)
注册的。
可选的 type
类型有:
cc.SystemEvent.EventType.KEY_DOWN
(键盘按下)cc.SystemEvent.EventType.KEY_UP
(键盘释放)cc.SystemEvent.EventType.DEVICEMOTION
(设备重力传感)键盘事件:
cc.Class({
extends: cc.Component,
onLoad: function () {
// 监听键盘事件
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
// 关闭键盘监听事件
onDestroy () {
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
// 回调函数
onKeyDown: function (event) {
switch(event.keyCode) {
case cc.macro.KEY.a:
console.log('Press a key');
break;
}
},
// 回调函数
onKeyUp: function (event) {
switch(event.keyCode) {
case cc.macro.KEY.a:
console.log('release a key');
break;
}
}
});
重力传感事件:
cc.Class({
extends: cc.Component,
onLoad () {
// open Accelerometer
cc.systemEvent.setAccelerometerEnabled(true);
cc.systemEvent.on(cc.SystemEvent.EventType.DEVICEMOTION, this.onDeviceMotionEvent, this);
},
onDestroy () {
cc.systemEvent.off(cc.SystemEvent.EventType.DEVICEMOTION, this.onDeviceMotionEvent, this);
},
onDeviceMotionEvent (event) {
cc.log(event.acc.x + " " + event.acc.y);
},
});
我们可以通过两种方式发送事件:emit
和 dispatchEvent
。
注意: emit 只能传递给自己,dispatchEvent 可以向上冒泡。
emit :
这里最多只支持传递5 个
事件参数.
cc.Class({
extends: cc.Component,
onLoad () {
// 监听自定义事件
this.node.on('Say', function (arg1, arg2, arg3) {
console.log(arg1, arg2, arg3); // print 1, 2, 3
});
},
start () {
// 所要传递的参数
let arg1 = 1, arg2 = 2, arg3 = 3;
// 发送自定义事件
this.node.emit('Say', arg1, arg2, arg3);
},
});
dispatchEvent:
// dispatchEvent派送事件
// 参数true表示向上冒泡,false表示不向上冒泡
var e = new cc.Event.EventCustom('Say', true); //创建事件e
e.detail={name: "ning"}; //设置参数
this.node.dispatchEvent( e );
//this.node.dispatchEvent( new cc.Event.EventCustom('Say', true) ); // 派送事件e
// 父节点监听事件,并停止向上冒泡
this.node.on('Say', function (event) {
event.stopPropagation();
});
在事件监听回调中,开发者会接收到一个 cc.Event 类型的事件对象 event , stopPropagation 就是 cc.Event 的标准 API,其它重要的 API 包含:
API 名 | 类型 | 意义 |
---|---|---|
type | String | 事件的类型(事件名) |
target | cc.Node | 接收到事件的原始对象 |
currentTarget | cc.Node | 接收到事件的当前对象,事件在冒泡阶段当前对象可能与原始对象不同 |
getType | Function | 获取事件的类型 |
stopPropagation | Function | 停止冒泡阶段,事件将不会继续向父节点传递,当前节点的剩余监听器仍然会接收到事件 |
stopPropagationImmediate | Function | 立即停止事件的传递,事件将不会传给父节点以及当前节点的剩余监听器 |
getCurrentTarget | Function | 获取当前接收到事件的目标节点 |
detail | Function | 自定义事件的信息(属于 cc.Event.EventCustom ) |
setUserData | Function | 设置自定义事件的信息(属于 cc.Event.EventCustom ) |
getUserData | Function | 获取自定义事件的信息(属于 cc.Event.EventCustom ) |
有时候我们需要父节点的触摸或鼠标事件先于
他的任何子节点派发;
这时候事件冒泡已经不能满足我们的需求了,需要将父节点的事件注册在捕获阶段。
要实现这个需求,可以在给 node 注册触摸或鼠标事件时,传入第四个参数 true ,表示 useCapture . 例如:
this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStartCallback, this, true);
当节点触发 touchstart 事件时,会先将 touchstart 事件派发给所有注册在捕获阶段的父节点监听器,然后派发给节点自身的监听器,最后才到了事件冒泡阶段。
只有触摸或鼠标事件
可以注册在捕获阶段,其他事件不能注册在捕获阶段。
枚举对象定义 | 对应的事件名 | 事件触发的时机 |
---|---|---|
无 | position-changed | 当位置属性修改时 |
无 | rotation-changed | 当旋转属性修改时 |
无 | scale-changed | 当缩放属性修改时 |
无 | size-changed | 当宽高属性修改时 |
无 | anchor-changed | 当锚点属性修改时 |
推荐阅读:
CocosCreator 代码组件(创建销毁节点、访问节点和组件) (第四篇)