[英]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. 现在我有一个与性能有关的问题。
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}是否为该形状。 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.getImageData
在intersects
方法中进行命中测试。
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.