简体   繁体   English

KineticJs中的非阻塞“相交”

[英]Non-blocking “intersects” in KineticJs

I am in the middle of process of making a HTML5 game. 我正在制作HTML5游戏。 Now I have a problem related to performance. 现在我有一个与性能有关的问题。

  • I have some irregular Shapes. 我有一些不规则的形状。 So detecting if {x,y} is in the Shape or not using a custom function is near impossible(At least as I think). 因此,检测{x,y}是否在Shape中或不使用自定义函数几乎是不可能的(至少在我看来)。
  • There are two big Shapes, so I need to call Shape.intersects({x,y}) twice for multiple times per second to detect if current {x,y} is in the shape or not. 有两个大的Shape.intersects({x,y}) ,因此我需要每秒两次多次调用Shape.intersects({x,y})两次,以检测当前的{x,y}是否为该形状。
  • {x,y} are variable and are not touch/mouse events. {x,y}是可变的,不是触摸/鼠标事件。 So I can not use onmousemove,etc events. 所以我不能使用onmousemove,etc事件。
  • Each twice call of Shape.intersects({x,y}) on Nexus 5 has a ~45ms overhead. Nexus 5上每两次两次调用Shape.intersects({x,y})都会产生〜45ms的开销。 ~45ms each 100ms! 每100ms约45ms! This make some hiccups in game experience. 这会打乱游戏体验。

The most straight solution is to make Shape.intersects({x,y}) non-blocking. 最直接的解决方案是使Shape.intersects({x,y})无阻塞。 But how? 但是如何? or do anyone have any idea around this problem? 还是有人对此问题有任何想法?

I am using Kinetic v5.0.1 我正在使用Kinetic v5.0.1


RESULT: 结果:

.intersects will re-generate the Shape in memory, this is why it is very costly. .intersects将在内存中重新生成Shape,这就是为什么它非常昂贵的原因。 According the to the @MarkE answer below, using native canvas function context.isPointInPath(x, y) would be very efficient. 根据下面的@MarkE答案,使用本地画布函数context.isPointInPath(x, y)将非常有效。 But: 但:

Note that this will only work for the last path (after using beginPath()). 请注意,这仅适用于最后一个路径(使用beginPath()之后)。 If you need to iterate several paths (ie. shapes) you need to re-construct the paths (no need to stroke or fill though). 如果需要迭代多个路径(即形状),则需要重新构建路径(尽管无需描边或填充)。 This is perhaps a reason why some don't use it. 这也许是某些人不使用它的原因。 Source: https://stackoverflow.com/a/17268669/172163 资料来源: https : //stackoverflow.com/a/17268669/172163

In my shapes, I had solid colors. 在形状上,我有纯色。 Also there are multiple shapes dynamically generated. 也有动态生成的多种形状。 so I ended up with context.getImageData(x, y, 1, 1) to get the color of specific pixel, and if it is the color of my Shapes are not. 所以我最终使用context.getImageData(x, y, 1, 1)来获取特定像素的颜色,如果是我的Shapes的颜色则不是。 It is more efficient than .intersects() . 它比.intersects()更有效。 It costs only ~3ms. 它仅花费〜3ms。

Why intersects gives you a performance hit (pun intended!) 为什么intersects会给您带来出色的表现(双关语意!)

Internally, KineticJS uses context.getImageData to do hit-tests in the intersects method. 在内部,KineticJS使用context.getImageDataintersects方法中进行命中测试。

getImageData provides pixel-perfect hit testing but it's slow on mobile devices (as you've discovered). getImageData提供了像素完美的点击测试,但是在移动设备上速度很慢(如您所见)。

To answer your question: 要回答您的问题:

No, you cannot run KineticJS's internal methods on a background worker thread. 不,您不能在后台工作线程上运行KineticJS的内部方法。

But... 但...

If you really need to squeeze performance out of hit-testing, you can write your own custom hit-test. 如果您确实需要从命中测试中挤出性能,则可以编写自己的自定义命中测试。

One possibility for such a custom hit test would be to maintain 2 offscreen html5 canvas elements that mirror your 2 irregular shapes. 这种自定义命中测试的一种可能性是维持2个屏幕外html5画布元素,这些元素反映您的2个不规则形状。

That way you can use canvas's context.isPointInPath(x,y) to do your hit-testing. 这样,您可以使用canvas的context.isPointInPath(x,y)进行命中测试。

The importance is that isPointInPath uses GPU acceleration and is therefore quite fast. 重要的是isPointInPath使用GPU加速,因此非常快。

If you feel ambitious you could even create an asynchronous background worker thread to execute isPointInPath while your UI thread continues. 如果您有雄心壮志,甚至可以创建一个异步后台工作线程来在UI线程继续执行的同时执行isPointInPath。

You mention the Nexus5. 您提到了Nexus5。 You can spawn a background worker thread with Android's AsyncTask. 您可以使用Android的AsyncTask生成后台工作线程。

Your background task can return the results of your hit-test using it's onPostExecute(Result) callback which invokes on the UI thread. 您的后台任务可以使用在UI线程上调用的onPostExecute(Result)回调返回命中测试的结果。

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

Good luck with your project! 祝您项目顺利!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM