1. 前言
眾所周知,白鷺引擎不支持區(qū)分玩家點擊了鼠標(biāo)左鍵或右鍵,也就是說右鍵和左鍵的效果是一樣的。但是有時候有一些特殊需求,比如右鍵點擊某個DisplayObject的時候需要在控制臺打印此對象,方便調(diào)試。那么如何實現(xiàn)這個功能呢,我們需要先看看引擎的源碼。
2. 引擎源碼
首先我們要知道網(wǎng)頁中可以通過addEventListener方法綁定鼠標(biāo)事件。如果要給某個HTML元素綁定鼠標(biāo)按下事件,可以寫成htmlElement.addEventListener("mousedown", onMouseDown)。大膽猜測白鷺引擎的鼠標(biāo)事件也是用這個方法實現(xiàn)的。
我們直接在源碼中全局搜索mousedown,能看到搜到了這個:

onmousedown
定位到這里,源碼是這樣的:

addMouseListener
我們找到
onTouchBegin方法:
onTouchBegin
如果要區(qū)分鼠標(biāo)左右鍵,是需要利用
event.button做判斷的,但是可以發(fā)現(xiàn),白鷺引擎沒有使用到event.button這個屬性。那么我們就可以在運行的時候替換掉
addMouseListener方法了,但是,怎么獲取WebTouchHandler原型的實例呢。我們搜索
WebTouchHandler,可以找到這里:
WebPlayer
可以看到
WebTouchHandler實例被添加到了WebPlayer的實例中。繼續(xù)搜索WebPlayer,能搜到這兩段差不多的代碼:
1

2
WebPlayer實例被添加到了css類為egret-player的HTML元素下面。到此,我們就算找到了所有相關(guān)的源碼.
3. 如何修改
根據(jù)源碼,我們先獲取相關(guān)的HTML元素,再拿到webTouchHandler對象
const egretPlayerElement = document.querySelector(".egret-player"); // 獲取到類為egret-player的元素
const webTouchHandler = egretPlayerElement["egret-player"]["webTouchHandler"]; // 拿到webTouchHandler實例
然后我們重新對addMouseListener方法賦值,當(dāng)然mousemove事件可以不用管它
webTouchHandler.addMouseListener = function () {
// 先移除舊的鼠標(biāo)事件
this.canvas.removeEventListener("mousedown", this.onTouchBegin);
this.canvas.removeEventListener("mouseup", this.onTouchEnd);
const _this: any = this;
// 鼠標(biāo)按下事件
this.canvas.addEventListener("mousedown", function (event: MouseEvent) {
switch (event.button) {
case 0: { // 左鍵執(zhí)行原來的onTouchBegin方法
_this.onTouchBegin(event);
break;
}
case 1: { // 中鍵在這里處理
break;
}
case 2: { // 右鍵在這里處理
break;
}
default: {
break;
}
}
});
// 鼠標(biāo)回彈事件
this.canvas.addEventListener("mouseup", function (event: MouseEvent) {
switch (event.button) {
case 0: { // 左鍵執(zhí)行原來的onTouchEnd方法
_this.onTouchEnd(event);
break;
}
case 1: { // 中鍵在這里處理
break;
}
case 2: { // 右鍵在這里處理
break;
}
default: {
break;
}
}
});
};
如果想獲取鼠標(biāo)點擊的游戲內(nèi)全局坐標(biāo)可以這么干
const location: egret.Point = _this["getLocation"](event);
getLocation方法定義在WebTouchHandler.prototype上,所以可以直接用。
有了世界坐標(biāo),我們就可以用下面的代碼獲取點擊到的顯示對象了
const stage: egret.Stage = egret.MainContext.instance.stage;
const displayObject: egret.DisplayObject = stage.$hitTest(location.x, location.y);
最后,我們需要執(zhí)行一下新的addMouseListener方法
webTouchHandler.addMouseListener();
游戲啟動的時候執(zhí)行一下上面這些代碼就可以了,下面是完整的代碼:
4. 完整代碼
/**
* 初始化webTouchHandler
* 將原來的鼠標(biāo)事件區(qū)區(qū)分開來
* 0:表示主鼠標(biāo)按鈕(通常是左鍵)被按下或釋放。
* 1:表示輔助鼠標(biāo)按鈕(通常是滾輪按鈕)被按下或釋放。
* 2:表示次要鼠標(biāo)按鈕(通常是右鍵)被按下或釋放。
* 3:表示第四個鼠標(biāo)按鈕被按下或釋放。
* 4:表示第五個鼠標(biāo)按鈕被按下或釋放。
* @private
*/
private _initWebTouchHandler() {
const egretPlayerElement = document.querySelector(".egret-player");
const webTouchHandler = egretPlayerElement["egret-player"]["webTouchHandler"];
webTouchHandler.addMouseListener = function () {
this.canvas.removeEventListener("mousedown", this.onTouchBegin);
this.canvas.removeEventListener("mouseup", this.onTouchEnd);
const _this: any = this;
this.canvas.addEventListener("mousedown", function (event: MouseEvent) {
switch (event.button) {
case 0: { // 左鍵
_this.onTouchBegin(event);
break;
}
case 1: { // 中鍵
break;
}
case 2: { // 右鍵
const location: egret.Point = _this["getLocation"](event);
const stage: egret.Stage = egret.MainContext.instance.stage;
const displayObject: egret.DisplayObject = stage.$hitTest(location.x, location.y);
// 在這里對顯示對象做處理,可以通過白鷺的事件機(jī)制處理
break;
}
case 4:
case 5: { // 鼠標(biāo)4,5先忽略
break;
}
default: {
break;
}
}
});
this.canvas.addEventListener("mouseup", function (event: MouseEvent) {
switch (event.button) {
case 0: { // 左鍵
_this.onTouchEnd(event);
break;
}
case 1: { // 中鍵
break;
}
case 2: { // 右鍵
const location: egret.Point = _this["getLocation"](event);
const stage: egret.Stage = egret.MainContext.instance.stage;
const displayObject: egret.DisplayObject = stage.$hitTest(location.x, location.y);
// 在這里對顯示對象做處理,可以通過白鷺的事件機(jī)制處理
break;
}
case 4:
case 5: { // 鼠標(biāo)4,5先忽略
break;
}
default: {
break;
}
}
});
};
webTouchHandler.addMouseListener();
}