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

GameMgr.ts代碼如下:
const {ccclass, property} = cc._decorator;
@ccclass
export default class GameMgr extends?cc.Component?{
@property({type:cc.Node, tooltip:"要控制的主角節(jié)點",})
player :?cc.Node?= null;
onLoad () {
// 觸摸到哪紅色塊就到哪
this.node.on(cc.Node.EventType.TOUCH_START, function(e?:?cc.Touch){
let worldPos :?cc.Vec2?= e.getLocation();
let localPos :?cc.Vec2?=?this.node.convertToNodeSpaceAR(worldPos);
this.player.setPosition(localPos);
},?this);
// 紅色塊隨著觸摸移動
this.node.on(cc.Node.EventType.TOUCH_MOVE, (e?:?cc.Touch)=>{
let pos :?cc.Vec2?=?this.player.getPosition();
this.player.setPosition(pos.add(e.getDelta()));
},?this);
this.node.on(cc.Node.EventType.TOUCH_CANCEL,?this.onTouchCancel,?this);
this.node.on(cc.Node.EventType.TOUCH_CANCEL,?this.onTouchEnd,?this);
}
private onTouchCancel() :?void{
console.log("在節(jié)點之外釋放鼠標!");
}
private onTouchEnd(e?:?cc.Touch) :?void{
console.log("在節(jié)點之內(nèi)釋放鼠標");
}
onDestroy(){
this.node.off(cc.Node.EventType.TOUCH_CANCEL,?this.onTouchCancel,?this);
this.node.off(cc.Node.EventType.TOUCH_END,?this.onTouchEnd,?this);
}
}
二、?鍵盤事件
1:cc.SystemEvent.on(type, function, target, useCapture);
type: cc.SystemEvent.EventType.KEY_DOWN 按鍵按下;
cc.SystemEvent.EventType.KEY_UP 按鍵彈起;
2: cc.SystemEvent.on(type, function, target, useCapture);
3: 監(jiān)聽的時候,我們需要一個cc.SystemEvent類的實例,我們有一個全局的實例cc.systemEvent,小寫開頭
3: 鍵盤回調(diào)函數(shù): function(event) {
event.keyCode [cc.KEY.left, ...cc.KEY.xxxx]
案例:按上下左右鍵,控制紅色塊的運動。
新建PlayerCtrl.ts,掛載到Red節(jié)點上。代碼如下:
const {ccclass, property} = cc._decorator;
@ccclass
export default class PlayerCtrl extends?cc.Component?{
start () {
// 按鍵按下時調(diào)用
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN,?this.onKeyDown,?this);
// 按鍵釋放時才調(diào)用
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP,?this.onKeyUp,?this);
}
private onKeyDown(e?:?any){
switch(e.keyCode){
case cc.macro.KEY.up :?this.node.y += 100; break;
case cc.macro.KEY.down :?this.node.y -= 100; break;
}
}
private onKeyUp(e?:?any){
switch(e.keyCode){
case cc.macro.KEY.left :?this.node.x -= 100; break;
case cc.macro.KEY.right :?this.node.x += 100; break;
}
}
}
三、?自定義事件
1: 監(jiān)聽: this.node.on(“自定義事件名稱”, function, target, useCapture);
2: 自派送: emit(“事件名稱”, [detail]); 只有自己能夠收到;
3: 冒泡派送:?dispatchEvent(new cc.Event.EventCustom(“name”, 是否冒泡傳遞));

1. 自派送emit
新建單色節(jié)點Blue,創(chuàng)建CustomEventTest.ts掛載到此節(jié)點上。
const {ccclass, property} = cc._decorator;
@ccclass
export default class CustomEventTest extends?cc.Component?{
onLoad () {
// 事件接收處理
this.node.on("SEND_EVENT", (e)=>{
console.log("emit方法派發(fā)事件SEND_EVENT", e, e.role);
},?this);
this.node.emit("SEND_EVENT", {role:?this.node.name});
}
}
運行結(jié)果如下:

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

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

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

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

然后,運行結(jié)果如下:

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


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