1. 前言
众所周知,白鹭引擎不支持区分玩家点击了鼠标左键或右键,也就是说右键和左键的效果是一样的。但是有时候有一些特殊需求,比如右键点击某个DisplayObject的时候需要在控制台打印此对象,方便调试。那么如何实现这个功能呢,我们需要先看看引擎的源码。
2. 引擎源码
首先我们要知道网页中可以通过addEventListener
方法绑定鼠标事件。如果要给某个HTML元素绑定鼠标按下事件,可以写成htmlElement.addEventListener("mousedown", onMouseDown)
。大胆猜测白鹭引擎的鼠标事件也是用这个方法实现的。
我们直接在源码中全局搜索mousedown
,能看到搜到了这个:
![](https://img.haomeiwen.com/i28752965/1b648d2b7b288cee.png)
定位到这里,源码是这样的:
![](https://img.haomeiwen.com/i28752965/7d676273a9488c8a.png)
我们找到
onTouchBegin
方法:![](https://img.haomeiwen.com/i28752965/ee0c7424ba995a17.png)
如果要区分鼠标左右键,是需要利用
event.button
做判断的,但是可以发现,白鹭引擎没有使用到event.button
这个属性。那么我们就可以在运行的时候替换掉
addMouseListener
方法了,但是,怎么获取WebTouchHandler
原型的实例呢。我们搜索
WebTouchHandler
,可以找到这里:![](https://img.haomeiwen.com/i28752965/9d1dabad47ad47a7.png)
可以看到
WebTouchHandler
实例被添加到了WebPlayer
的实例中。继续搜索WebPlayer
,能搜到这两段差不多的代码:![](https://img.haomeiwen.com/i28752965/4951c1e70a1e93c2.png)
![](https://img.haomeiwen.com/i28752965/5345e2db6486c1c7.png)
WebPlayer
实例被添加到了css类为egret-player
的HTML元素下面。到此,我们就算找到了所有相关的源码.
3. 如何修改
根据源码,我们先获取相关的HTML元素,再拿到webTouchHandler
对象
const egretPlayerElement = document.querySelector(".egret-player"); // 获取到类为egret-player的元素
const webTouchHandler = egretPlayerElement["egret-player"]["webTouchHandler"]; // 拿到webTouchHandler实例
然后我们重新对addMouseListener方法赋值,当然mousemove
事件可以不用管它
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: { // 左键执行原来的onTouchBegin方法
_this.onTouchBegin(event);
break;
}
case 1: { // 中键在这里处理
break;
}
case 2: { // 右键在这里处理
break;
}
default: {
break;
}
}
});
// 鼠标回弹事件
this.canvas.addEventListener("mouseup", function (event: MouseEvent) {
switch (event.button) {
case 0: { // 左键执行原来的onTouchEnd方法
_this.onTouchEnd(event);
break;
}
case 1: { // 中键在这里处理
break;
}
case 2: { // 右键在这里处理
break;
}
default: {
break;
}
}
});
};
如果想获取鼠标点击的游戏内全局坐标可以这么干
const location: egret.Point = _this["getLocation"](event);
getLocation
方法定义在WebTouchHandler.prototype
上,所以可以直接用。
有了世界坐标,我们就可以用下面的代码获取点击到的显示对象了
const stage: egret.Stage = egret.MainContext.instance.stage;
const displayObject: egret.DisplayObject = stage.$hitTest(location.x, location.y);
最后,我们需要执行一下新的addMouseListener
方法
webTouchHandler.addMouseListener();
游戏的时候执行一下上面这些代码就可以了,下面的完整的代码,。
4. 完整代码
/**
* 初始化webTouchHandler
* 将原来的鼠标事件区区分开来
* 0:表示主鼠标按钮(通常是左键)被按下或释放。
* 1:表示辅助鼠标按钮(通常是滚轮按钮)被按下或释放。
* 2:表示次要鼠标按钮(通常是右键)被按下或释放。
* 3:表示第四个鼠标按钮被按下或释放。
* 4:表示第五个鼠标按钮被按下或释放。
* @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);
// 在这里对显示对象做处理,可以通过白鹭的事件机制处理
break;
}
case 4:
case 5: { // 鼠标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);
// 在这里对显示对象做处理,可以通过白鹭的事件机制处理
break;
}
case 4:
case 5: { // 鼠标4,5先忽略
break;
}
default: {
break;
}
}
});
};
webTouchHandler.addMouseListener();
}
网友评论