使用 Canvas 进行像素完美的 2D 鼠标拾取

Eth*_*han 3 html javascript canvas

我正在使用 Canvas 在 html5 中编写 2D 游戏,这需要检测鼠标单击和悬停事件。这有 3 个问题:检测必须是​​像素完美的,对象不是矩形的(房子,形状怪异的 UI 按钮......),并且需要快速响应。(显然蛮力不是一种选择)

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

PS:我做了一些调查,找到了一个在这里使用 QuadTree 的人。

Sim*_*ris 5

我有一个(过时的)教程解释了幽灵画布的概念,它适合像素完美的命中检测。教程在这里。忽略关于较新教程的警告,较新的教程不使用幽灵画布概念。

这个想法是将有问题的图像绘制到内存画布上,然后用于getImageData获取鼠标单击的单个像素。然后您会看到该单个像素是否完全透明。

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

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

您只需要在最后清除内存中的画布。

getImageData 速度很慢,但如果您想要像素完美的命中检测并且不预先计算任何内容,这是您唯一的选择。

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

这就是我对你的问题的回答。我的建议?如果这是一个游戏,请忘记像素完美检测。

严重地。

而是创建表示对象但不是像素完美的路径(不是在画布中,在纯 javascript 代码中),例如房子可能是一个正方形,顶部有一个三角形,它非常接近图像,但用于它在命中测试方面取而代之。它是相对非常快的计算,如果一个点是路径内比它做的像素完善的检测。多边形绕数规则检测中的查找点。老实说,这是你最好的选择。