Cocos Creator开发中的事件响应
序言
在Cocos Creator游戏开发中,我们经常需要处理事件响应。所以,我们有必要对其中的事件响应内容熟记于心,因此,将其中重要内容归纳如下:
一、触摸事件
1: 触摸事件类型: START, MOVED, ENDED(物体内), CANCEL(物体外);
2: 监听触摸事件: node.on(类型, callback, target(回掉函数的this), [useCapture]);
3: 关闭触摸事件: node.off(类型, callback, target(回掉函数的this), [useCapture]);
4: 移除所有的注册事件:targetOff (target) ;
5: 回调函数的参数设置 function(e(cc.Touch))
6: cc.Touch: 触摸对象,
常用方法getLocation返回触摸的位置;getDelta返回距离上次的偏移;
7: cc.Event: stopPropagationImmediate/stopPropagation 停止事件的传递;
8: 事件冒泡: 触摸事件支持节点树的事件冒泡,会从当前节点往上一层一层的向父节点传送;
如下案例,物体跟随手指触摸移动实现:

GameMgr.ts代码如下:
1. `const {ccclass, property} = cc._decorator;`3. ` `4. `export default class GameMgr extends cc.Component {`5. ` ({type:cc.Node, tooltip:"要控制的主角节点",})`6. `player : cc.Node = null;`8. ` onLoad () {`9. ` // 触摸到哪红色块就到哪`10. ` this.node.on(cc.Node.EventType.TOUCH_START, function(e : cc.Touch){`11. ` let worldPos : cc.Vec2 = e.getLocation();`12. ` let localPos : cc.Vec2 = this.node.convertToNodeSpaceAR(worldPos);`13. ` this.player.setPosition(localPos);`14. ` }, this);`16. ` // 红色块随着触摸移动`17. ` this.node.on(cc.Node.EventType.TOUCH_MOVE, (e : cc.Touch)=>{`18. ` let pos : cc.Vec2 = this.player.getPosition();`19. ` this.player.setPosition(pos.add(e.getDelta()));`20. ` }, this);`22. ` this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);`23. ` this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);`24. `}`26. ` private onTouchCancel() : void{`27. ` console.log("在节点之外释放鼠标!");`28. ` }`30. ` private onTouchEnd(e : cc.Touch) : void{`31. ` console.log("在节点之内释放鼠标");`32. `}`34. ` onDestroy(){`35. ` this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);`36. ` this.node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);`37. `}`39. `}`
二、键盘事件
1:cc.SystemEvent.on(type, function, target, useCapture);
type: cc.SystemEvent.EventType.KEYDOWN 按键按下; cc.SystemEvent.EventType.KEYUP 按键弹起;
2: cc.SystemEvent.on(type, function, target, useCapture);
3: 监听的时候,我们需要一个cc.SystemEvent类的实例,我们有一个全局的实例cc.systemEvent,小写开头
4: 键盘回调函数: function(event) {
1. `event.keyCode [cc.KEY.left, ...cc.KEY.xxxx]`
案例:按上下左右键,控制红色块的运动。新建PlayerCtrl.ts,挂载到Red节点上。代码如下:
1. `const {ccclass, property} = cc._decorator;`3. ` `4. `export default class PlayerCtrl extends cc.Component {`5. ` start () {`6. ` // 按键按下时调用`7. ` cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);`8. ` // 按键释放时才调用`9. ` cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);`10. `}`12. ` private onKeyDown(e : any){`13. ` switch(e.keyCode){`14. ` case cc.macro.KEY.up : this.node.y += 100; break;`15. ` case cc.macro.KEY.down : this.node.y -= 100; break;`16. ` }`17. `}`19. ` private onKeyUp(e : any){`20. ` switch(e.keyCode){`21. ` case cc.macro.KEY.left : this.node.x -= 100; break;`22. ` case cc.macro.KEY.right : this.node.x += 100; break;`23. ` }`24. ` }`25. `}`
三、自定义事件
1: 监听: this.node.on(“自定义事件名称”, function, target, useCapture);
2: 自派送: emit(“事件名称”, [detail]); 只有自己能够收到;
3: 冒泡派送: dispatchEvent(new cc.Event.EventCustom(“name”, 是否冒泡传递));

1.自派送emit
1. `新建单色节点Blue,创建CustomEventTest.ts挂载到此节点上。`2. `const {ccclass, property} = cc._decorator;`4. ` `5. `export default class CustomEventTest extends cc.Component {`6. ` onLoad () {`7. ` // 事件接收处理`8. ` this.node.on("SEND_EVENT", (e)=>{`9. ` console.log("emit方法派发事件SEND_EVENT", e, e.role);`10. ` }, this);`11. ` this.node.emit("SEND_EVENT", {role: this.node.name});`12. ` }`13. `}`
运行结果如下:

注意:此时,如果我们要在其父节点Canvas节点下也能接收到此SEND_EVENT事件,我们会设想,在GameMgr.ts中增加如下代码,但是事实上,运行后,GameMgr.ts的如下代码没有接收到派发事件。

运行结果如下(说明依然只有Blue自己这个节点接收到了emit派发的事件SEND_EVENT):

说明:如果派送的事件不只是发给自己,需要向上传递,则需要使用dispatchEvent。
2.冒泡派送dispatchEvent
在CustomEventTest.ts中增加start方法如下:

同时将GameMgr.ts中的方法略作修改如下:

然后,运行结果如下:

注意:若将CustomEventTest.ts中的事件冒泡属性改为false,如下,表示不冒泡传递,则其父节点Canvas将收不到派发的事件。


若将CustomEventTest.ts中的将start方法注释掉,则运行结果如下:
