我想检查HTML5画布中两个Sprite之间的碰撞。因此,为了讨论,让我们假设两个精灵都是IMG对象,并且碰撞意味着alpha通道不是0.现在这两个精灵都可以围绕对象的中心旋转,但是如果这样做则没有其他变换更容易。
现在我想出的明显解决方案是:
我看到的问题是:a)JavaScript中没有矩阵类,这意味着我必须在JavaScript中这样做,这可能非常慢,我必须测试每帧的冲突,这使得这非常昂贵。此外,我必须复制我在绘图时必须做的事情(或画布为我做的事情,设置矩阵)。
我想知道我在这里是否遗漏了什么,以及是否有更容易的碰撞检测解决方案。
答案 0 :(得分:7)
我必须复制我在绘制时必须做的事情
好吧,您可以创建一个新的渲染上下文,为其绘制一个旋转的白色背景蒙版,将合成操作设置为lighter
,并在给定偏移处绘制另一个旋转蒙版。
现在,如果剩下一个非白色像素,那就有一个点击。您仍然必须getImageData
并筛选像素才能找到它。您可以通过向下缩放生成的图像来减少该工作量(依靠抗锯齿来保持一些像素非白色),但我认为它可能仍然会很慢。
我必须测试每一帧的碰撞,这使得它非常昂贵。
是的,我认为你将会使用预先计算的碰撞表。如果你有足够的空间,你可以为精灵a,精灵b,相对旋转,相对-x-标准化 - 旋转和相对-γ-标准化 - 旋转的每个组合存储一个命中/不命中位。 。根据您拥有的精灵数量以及旋转或移动的步数,这可能会变得相当大。
折衷方案是将每个精灵的预旋转蒙版存储在JavaScript数组中(数字,为您提供32位/像素的轻松&&
能力数据,或者作为Sring中的角色,给你16位)和&&
每行相交的精灵面具。
或者,放弃像素并开始查看例如。路径。
答案 1 :(得分:6)
我不是一个javascript编码器,但我认为相同的优化技巧对于Javascript和C ++一样有效。
只需旋转精灵的角落而不是每个像素。实际上,你会做一些像软件纹理映射的事情。您可以使用各种梯度信息计算出给定像素的x,y位置。查找软件纹理映射以获取更多信息。
如果您将四胞胎分解为“命中”和“未命中”区域,那么您可以有效地检查给定的四叉树分解是否全部为“未命中”,“全部命中”或“可能命中” (即包含命中和非命中像素。前两个是很容易通过的。在最后一种情况下,然后进入下一个分解级别并重复测试。这样你只检查你需要的像素和大“非命中”和“命中”的区域你不必进行如此复杂的检查。
无论如何这只是一些想法。
答案 2 :(得分:2)
同样的问题,另一种解决方案。首先,我使用getImageData数据来查找围绕精灵的多边形。这里要小心,因为实现适用于具有透明背景且具有单个实体对象的图像。就像一艘船。下一步是Ramer Douglas Peucker Algorithm以减少多边形中的顶点数量。我终于得到了一个非常少的顶点的多边形,它很容易旋转,并且检查每个精灵与其他多边形的碰撞。
http://jsfiddle.net/rnrlabs/9dxSg/
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var img = document.getElementById("img");
context.drawImage(img, 0,0);
var dat = context.getImageData(0,0,img.width, img.height);
// see jsfiddle
var startPixel = findStartPixel(dat, 0);
var path = followPath(startPixel, dat, 0);
// 4 is RDP epsilon
map1 = properRDP(path.map, 4, path.startpixel.x, path.startpixel.y);
// draw
context.beginPath();
context.moveTo(path.startpixel.x, path.startpixel.x);
for(var i = 0; i < map.length; i++) {
var p = map[i];
context.lineTo(p.x, p.y);
}
context.strokeStyle = 'red';
context.closePath();
context.stroke();