KineticJs中的非阻塞“相交”

时间:2014-02-13 01:03:45

标签: javascript html5 performance html5-canvas kineticjs

我正处于制作HTML5游戏的过程中。现在我遇到了与性能有关的问题。

  • 我有一些不规则形状。因此,使用自定义函数检测{x,y}是否在Shape中是不可能的(至少我认为)。
  • 有两个大的形状,所以我需要每秒多次调用Shape.intersects({x,y})两次以检测当前{x,y}是否在形状中。
  • {x,y}是可变的,不是触摸/鼠标事件。所以我不能使用onmousemove等事件。
  • Nexus 5 上每次Shape.intersects({x,y})的两次调用都有~45ms的开销。每100毫秒~45毫秒!这会让游戏体验出现一些小问题。

最直接的解决方案是使Shape.intersects({x,y})无阻塞。但是怎么样?或者有人对这个问题有任何想法吗?

我正在使用Kinetic v5.0.1


结果:

.intersects将在内存中重新生成Shape,这就是为什么它非常昂贵。根据下面的@MarkE答案,使用本机画布函数context.isPointInPath(x, y)将非常有效。但是:

  

请注意,这仅适用于最后一个路径(使用beginPath()之后)。如果需要迭代多个路径(即形状),则需要重新构造路径(不需要描边或填充)。这可能是有些人不使用它的原因。   资料来源:https://stackoverflow.com/a/17268669/172163

在我的形状中,我有纯色。还有动态生成的多个形状。所以我最终得到了context.getImageData(x, y, 1, 1)以获得特定像素的颜色,如果是我的形状的颜色则没有。它比.intersects()更有效。它的成本仅为3毫秒。

1 个答案:

答案 0 :(得分:1)

为什么intersects会为您带来性能影响(双关语!)

在内部,KineticJS使用context.getImageDataintersects方法中进行命中测试。

getImageData提供像素完美的点击测试,但在移动设备上却很慢(正如您所发现的那样)。

回答您的问题:

不,你不能在后台工作线程上运行KineticJS的内部方法。

<强>可是...

如果你真的需要从性能测试中挤出性能,你可以编写自己的自定义命中测试。

这种自定义命中测试的一种可能性是维护2个屏幕外的html5画布元素,以反映您的2个不规则形状。

这样你就可以使用canvas context.isPointInPath(x,y)来进行命中测试。

重要的是isPointInPath使用GPU加速,因此非常快。

如果你有野心,甚至可以创建一个异步后台工作线程来在你的UI线程继续时执行isPointInPath。

你提到了Nexus5。您可以使用Android的AsyncTask生成后台工作线程。

您的后台任务可以使用它在UI线程上调用的onPostExecute(Result)回调返回命中测试的结果。

http://developer.android.com/reference/android/os/AsyncTask.html

祝你的项目好运!