【问题标题】:Has anyone experienced side effects (including performance issue) of using getObjectsUnderPoint?有没有人遇到过使用 getObjectsUnderPoint 的副作用(包括性能问题)?
【发布时间】:2012-03-14 06:30:10
【问题描述】:

在我对正在进行的游戏项目进行重大更改之前,我只想听听其他人是否发现 DisplayObject 的 getObjectsUnderPoint() 函数有任何问题?

更新: 不仅是性能问题,还有使用它的任何其他限制(比如它没有检测到某些类型的 UIelements(仅作为示例))

我将在我的应用程序中包含三层(等距游戏)

  • 背景——这只是一个背景,一直在底部,与游戏无关
  • Middle Layer -- 这是可玩区域,这里我所有的游戏元素都会放在这个层上
  • 顶层——这是一个虚拟透明层,覆盖整个可播放区域,中断所有鼠标事件。这是我想使用 getObjectsUnderPoint() 的地方

所以,玩家想要点击元素,顶层会中断鼠标事件,然后检查是否有东西放置或只是一个纯背景,并采取适当的行动,例如通知下面的对象。

这真的不需要这样做,因为我可以直接为所有放置在地图上的项目添加 moues 事件,但因为无论如何我都会使用 getObjectsUnderPoint() 来检查项目下方是否有任何东西。

如果有人能解释这个功能是如何工作的,那么我就很难做出决定了。

【问题讨论】:

  • 如果您担心性能问题,为什么不直接对函数进行压力测试,并验证它是否在使用多个对象时速度很慢,比如说,是您游戏中数量的两倍.
  • 有一个遗漏的地方想最后补充,现在更新
  • 前几天写了touchlib,用这个函数来调度事件,没有发现少数对象有什么问题。这取决于你有多少对象,如果你有太多,你总是可以杀死 CPU :]。也许你应该做一些压力测试?

标签: actionscript-3 actionscript


【解决方案1】:

不过有一个烦人的问题。我不知道他们是否修复了它。至少出现了 10.1 次。

如果您有一个容器并对其进行了缩放container.getObjectsUnderPoint 将返回错误的结果。每时每刻。所以在我需要getObjectsUnderPoint 的任何地方,我都必须从stage 调用它才能获得正确的结果。

【讨论】:

  • 我怀疑它在缩放容器时返回了错误的值。文档说“点参数在舞台的坐标空间中,可能与显示对象容器的坐标空间不同(除非显示对象容器是舞台)。您可以使用 globalToLocal() 和 localToGlobal( ) 方法在这些坐标空间之间转换点。"
  • 例如,如果您的对象在比例上加倍,则容器中 (3,3) 处的点可能是舞台坐标中的 (6,6)。如果您的对象要从舞台上移除,那么它将位于假定父级的坐标空间中,例如,如果您将对象的 x 位置设置为 5 并将比例保留为 2,如上例所示,那么容器内 (3,3) 的点实际上是舞台坐标中的 (2*3+5,3) 或 (11,3)。无论如何,它现在似乎运行良好。
  • getObjectsUnderPoint 有一个更大的问题,我开始意识到这一点......它不包括有孩子的容器精灵,这可能是事件目标。这样的容器精灵没有自己的图形,因此它们不会出现在返回的列表中。尽管如此,从技术上讲,它们仍然有区域,因此如果所有子精灵都将 mouseEnabled 设置为 false,那么父精灵将收到事件……尽管此父精灵没有出现在列表中。
  • 要正确处理 getObjectsUnderPoint,您不仅需要遍历列表中每个项目的每个父项,寻找 mouseChildren = false...,而且在基于它具有 mouseEnabled 的每个孩子之后消除= false (因为下一个最高的孩子(还不是父母)将是下一个目标候选人......当您逐步浏览返回的数组时。此时,您必须将之前任何一组子代的父代视为候选者。
  • @ValentinSimonov 对缩放容器的看法是正确的。我现在正在使用最新版本的 Adob​​e Air 和 Flash CC 来体验它。我发现唯一的解决方案是在第一个非缩放容器上使用 getObjectsUnderPoint()。在我的情况下,它是舞台......
【解决方案2】:

这是一个不完整的功能。它返回鼠标下的图形对象,而不是所有用于事件或交互目的的潜在鼠标目标。它实际上需要复杂的逻辑来检查 getObjectsUnderPoint 返回的数组以确定鼠标目标,因为适当的目标(如果您实际单击该点,Flash 会选择该目标)可能不在列表中。

首先,您必须反向检查对象数组,因为这些项目是从后向前排列的。您必须检查每个对象的整个父链,寻找具有 mouseChildren = false 的父级,这会导致它拦截事件并成为目标。无论是否找到这样的对象,您到达的最终对象必须将其 mouseEnabled 属性设置为 true,否则您必须跳过它并移动到数组中的下一个对象,例如,下一个精灵或形状在您最初检查的那个后面。在浏览列表时,您必须注意父级何时更改,此时您需要假设该共同父级的所有子级都将其 mouseEnabled 属性设置为 false,在这种情况下,父级将成为下一个候选者。这实际上非常复杂,因为您正在以自下而上的方法向后工作,其中包含从自上而下生成的一组不完整的对象。

要获得实际的潜在鼠标事件目标,与默认调度逻辑一致...实际上更容易以自上而下的方式从舞台开始,并以深度优先搜索的方式向后遍历显示层次结构,检查mouseChildren 来判断是否需要进入children,如果是target,则检查mouseEnabled,否则进入容器的children,从后往前重复这个过程。这更加准确、完整和直接。唯一的问题是您必须自己编写代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    • 2011-07-28
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    相关资源
    最近更新 更多