Egret社区

[Egret Engine] 显示对象的hitTest逻辑漏洞

2018-7-12 19:06
14413
产品 Egret Engine 版本 5.2.4
复现概率 100% 平台 Android 安卓
复现步骤 创建一个复杂场景,包含大量显示对象,快速连续点击场景
问题描述 当有大量对象在场景上显示时,快速连续点击场景,会出现明显掉帧现象,即使将大多数对象的touchEnable及touchChildren关闭,依然会掉帧
错误代码 源码中DisplayObjectContainer的方法$hitTest(stageX: number, stageY: number): DisplayObject {
if (!this.$visible) {
return null;
}
let m = this.$getInvertedConcatenatedMatrix();
let localX = m.a * stageX + m.c * stageY + m.tx;
let localY = m.b * stageX + m.d * stageY + m.ty;

let rect = this.$scrollRect ? this.$scrollRect : this.$maskRect;
if (rect && !rect.contains(localX, localY)) {
return null;
}

if (this.$mask && !this.$mask.$hitTest(stageX, stageY)) {
return null
}
const children = this.$children;
let found = false;
let target: DisplayObject = null;
for (let i = children.length - 1; i >= 0; i--) {
const child = children[i];
if (child.$maskedObject) {
continue;
}

target = child.$hitTest(stageX, stageY);
if (target) {
found = true;
if (target.$touchEnabled) {
break;
}
else {
target = null;
}
}
}
if (target) {
if (this.$touchChildren) {
return target;
}
return this;
}
if (found) {
return this;
}
return super.$hitTest(stageX, stageY);
}
BUG截图
通过阅读源码,发现显示对象在进行点击检查时,会调用hitTest方法,而DisplayObjectContainer中的hitTest在遍历子对象时,没有首先判定该对象能否点击以及子对象能否点击,而是hitTest出结果后才进行的touchEnable判断,这样会导致很多不必要的计算,尝试修改了下源码,发现卡顿问题得到明显改善,希望官方能检查下,是否是这方面的问题,这样修改有没有问题
参与人数 1银子 +1 收起 理由
steven1041 + 1 很给力!

查看全部评分

分享到 :
3 人收藏

3 个回复

倒序浏览
Nasus  官方团队 | 2018-7-26 09:22:23 来自手机
好的 感谢您的提议
SkyCross  略有小成 | 2018-7-26 11:55:10
Nasus 发表于 2018-7-26 09:22
好的 感谢您的提议

终于有回复了,顺带看下这个问题呢,富文本显示错误http://bbs.egret.com/thread-49922-1-1.html
egret-Jerry  官方团队 | 2018-7-26 12:06:31
判定该对象能否点击以及子对象能否点击是不够的,还要判断该对象的父对象以及父对象的父对象,直到判断到stage,因为点击是一层层向上传递的。如果你的项目没有这种一层层传递的需求可以这么做,这么做肯定效率比较高

PS:能读源码并提出意见的同学一定是很牛的技术
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|京网文[2014]0791-191号|京ICP证150115号|Egret社区 ( 京ICP备14025619号 )

Powered by Discuz! X3.4 © 2001-2019 Comsenz Inc.

返回顶部