Cocos Creator開發(fā)中的事件響應
序言
在Cocos Creator游戲開發(fā)中,我們經(jīng)常需要處理事件響應。所以,我們有必要對其中的事件響應內容熟記于心,因此,將其中重要內容歸納如下:
一、觸摸事件
1: 觸摸事件類型: START, MOVED, ENDED(物體內), CANCEL(物體外);
2: 監(jiān)聽觸摸事件: node.on(類型, callback, target(回掉函數(shù)的this), [useCapture]);
3: 關閉觸摸事件: node.off(類型, callback, target(回掉函數(shù)的this), [useCapture]);
4: 移除所有的注冊事件:targetOff (target) ;
5: 回調函數(shù)的參數(shù)設置 function(e(cc.Touch))
6: cc.Touch: 觸摸對象,
常用方法getLocation返回觸摸的位置;getDelta返回距離上次的偏移;
7: cc.Event: stopPropagationImmediate/stopPropagation 停止事件的傳遞;
8: 事件冒泡: 觸摸事件支持節(jié)點樹的事件冒泡,會從當前節(jié)點往上一層一層的向父節(jié)點傳送;
如下案例,物體跟隨手指觸摸移動實現(xiàn):

GameMgr.ts代碼如下:
1. ?`const {ccclass, property} = cc._decorator;`3. ?` `4. ?`export default class GameMgr extends cc.Component {`5. ?` ? ? ({type:cc.Node, tooltip:"要控制的主角節(jié)點",})`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("在節(jié)點之外釋放鼠標!");`28. ?` ? ?}`30. ?` ? ?private onTouchEnd(e : cc.Touch) : void{`31. ?` ? ? ? ?console.log("在節(jié)點之內釋放鼠標");`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: 監(jiān)聽的時候,我們需要一個cc.SystemEvent類的實例,我們有一個全局的實例cc.systemEvent,小寫開頭
4: 鍵盤回調函數(shù): function(event) {
1. ?`event.keyCode [cc.KEY.left, ...cc.KEY.xxxx]`
案例:按上下左右鍵,控制紅色塊的運動。新建PlayerCtrl.ts,掛載到Red節(jié)點上。代碼如下:
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: 監(jiān)聽: this.node.on(“自定義事件名稱”, function, target, useCapture);
2: 自派送: emit(“事件名稱”, [detail]); 只有自己能夠收到;
3: 冒泡派送: dispatchEvent(new cc.Event.EventCustom(“name”, 是否冒泡傳遞));

1.自派送emit
1. ?`新建單色節(jié)點Blue,創(chuàng)建CustomEventTest.ts掛載到此節(jié)點上。`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方法派發(fā)事件SEND_EVENT", e, e.role);`10. ?` ? ? ? ?}, this);`11. ?` ? ? ? ?this.node.emit("SEND_EVENT", {role: this.node.name});`12. ?` ? ?}`13. ?`}`
運行結果如下:

注意:此時,如果我們要在其父節(jié)點Canvas節(jié)點下也能接收到此SEND_EVENT事件,我們會設想,在GameMgr.ts中增加如下代碼,但是事實上,運行后,GameMgr.ts的如下代碼沒有接收到派發(fā)事件。

運行結果如下(說明依然只有Blue自己這個節(jié)點接收到了emit派發(fā)的事件SEND_EVENT):

說明:如果派送的事件不只是發(fā)給自己,需要向上傳遞,則需要使用dispatchEvent。
2.冒泡派送dispatchEvent
在CustomEventTest.ts中增加start方法如下:

同時將GameMgr.ts中的方法略作修改如下:

然后,運行結果如下:

注意:若將CustomEventTest.ts中的事件冒泡屬性改為false,如下,表示不冒泡傳遞,則其父節(jié)點Canvas將收不到派發(fā)的事件。


若將CustomEventTest.ts中的將start方法注釋掉,則運行結果如下:
