像素完美的2D鼠标挑选与帆布 [英] Pixel perfect 2D mouse picking with Canvas

查看:125
本文介绍了像素完美的2D鼠标挑选与帆布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Canvas编写html5中的2D游戏,需要鼠标点击和悬停事件才能被检测到。这里有3个问题:检测必须是​​像素完美的,对象不是矩形(房子,奇怪的UI按钮...),它需要快速和响应。 (显然强力不是一个选项)

I'm writing a 2D game in html5 using Canvas which requires mouse click and hover events to be detected. There are 3 problems with this: detections must be pixel-perfect, objects are not rectangular (houses, weird-shaped UI buttons...), and it is required to be fast and responsive. (Obviously brute force is not an option)

所以我想问的是我如何找出鼠标在哪个对象,什么是可能的优化。

So what I want to ask is how do I find out which object the mouse is on, and what are the possible optimizations.

PS:我做了一些调查,发现一个使用QuadTree的人这里

P.S: I did some investigation and found a guy who used QuadTree here.

推荐答案

这是一个像素完美的命中检测体面的幽灵画布的概念。本教程是此处。忽略关于较新教程的警告,较新的教程不使用ghost画布概念。

I have a (dated) tutorial that explains the concept of a ghost canvas which is decent for pixel-perfect hit detection. The tutorial is here. Ignore the warning about a newer tutorial, the newer one does not use the ghost canvas concept.

这个想法是将有问题的图像绘制到内存画布,然后使用 getImageData 获取鼠标单击的单个像素。

The idea is to draw the image in question to an in-memory canvas and then use getImageData to get the single pixel of the mouse click. Then you see if that single pixel is fully transparent or not.

如果它不是完全透明,那么你有目标。

If its not fully transparent, well, you've got your target.

如果它是完全透明的,绘制下一个对象到内存画布,然后重复。

If it is fully transparent, draw the next object to the in-memory canvas and repeat.

内存画布结束。

getImageData 很慢,但它是你唯一的选择,如果你想像素完美匹配

getImageData is slow but it is your only option if you want pixel-perfect hit detection and aren't pre-computing anything.

或者,您可以预计算路径或其他具有偏移量的像素阵列。这将是一个很大的工作,但可能会更快。例如,如果你有一个40x20的图像与一些透明度,你会计算一个数组[40] [20],它将具有true或false对应于透明或不对。然后你将测试它对鼠标位置,有一些偏移量,如果图像绘制在(25,55),你想从鼠标位置减去,然后测试新位置是否为真,当你看着array [posx] [posy]。

Alternatively you could precompute a path or else an array of pixels with an offset. This would be a lot of work but might be faster. For instance if you have a 40x20 image with some transparency you'd compute an array[40][20] that would have true or false corresponding to transparent or not. Then you'd test that against the mouse position, with some offset, if the image is drawn at (25, 55) you'd want to subtract that from the mouse position and then test if the new position is true when you look at array[posx][posy].

这是我的答案。 我的建议?

That's my answer to your question. My Suggestion? Forget pixel-perfect detection if this is a game.

请慎重。

(不是在画布中,在纯javascript代码中),它们表示对象,但不是像素完美的,例如房子可以是顶部具有三角形的正方形,其是图像的非常接近,但是在其它来击中测试。计算一个点是否在路径内部比进行像素完美检测要相对快速。在多边形缠绕数规则检测中查找点。这是你最好的选择,老实说。

Instead make paths (not in canvas, in plain javascript code) that represent the objects but are not pixel perfect, for instance a house might be a square with a triangle on the top that is a very close approximation of the image but is used in its stead when it comes to hit testing. It is comparatively extremely fast to compute if a point is inside a path than it is to do pixel-perfect detection. Look up point in polygon winding number rule detection. That's your best bet, honestly.

这篇关于像素完美的2D鼠标挑选与帆布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆