【Egret】讓白鷺引擎支持鼠標(biāo)右鍵和其他鍵的點擊事件

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();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容