所以我正在使用HTML5和Javascript制作塔防游戏。我唯一的问题是检测鼠标何时与攻击者的路径接触,这是阻止玩家在路径上建造塔的必要条件。攻击者的路径在MAP.js文件中确定(参见底部的链接),由二维数组(包含x和y对的数组)确定,所以我必须使用的是一系列点连接时组成路径。我只是想禁止玩家将塔放在路径的50个像素内。说实话,我对碰撞检测很可怕,所以非常感谢一些帮助。
以下是所有代码的链接: http://shapeshifting.comuv.com/Tower_Defense/td/
正如您可能想象的那样,只有.js文件适用,但大多数相关代码都在objects.js文件中。 (请原谅杂乱)
答案 0 :(得分:4)
碰撞检测是编码游戏的旧的隐藏问题之一。通常人们采用darkpenguin的方法以某种方式预先计算静态地图上和不可放置的地方。下一步是提出一种指定最有效的碰撞图的方法。
你不希望你的游戏在用户移动他们的鼠标时做大量的数学运算 - 它需要简短快速 - 所以预先计算到快速的东西是至关重要的。
如果您的地图是网格,那么您的答案就在那里 - 碰撞地图是一个预先计算的二维数组 - 基本上是一个非常小的黑白图像,网格上每个地方都有一个像素。白色像素(1)是可放置的而黑色像素(0)不是。您只需使用此真/假的2D数组作为查找。如果要保存内存,可以将网格上32个空格的每个条带捆绑成一个位标志。
如果您的地图不是网格,那么您仍然希望预先计算事物,但策略有点复杂。第一种可能性是像Hitesh那样执行数学生成稍高分辨率的碰撞图,然后其余的就像网格策略一样 - 例如,如果每个4x4像素块是一个碰撞条目,那么塔是否可以是放置测试是否其坐标测试是否足够1 - 你可能要求100%的测试为1,或者你可能让他们达到一点,让75%的测试为1。
如果这仍然不够详细,您可以执行这些更复杂的多边形测试,但您希望它们尽可能简单。当不使用预先计算的网格时,最简单的2D碰撞测试是2个圆圈 - 您只需计算它们的中心之间的距离,并检查它是否大于或小于它们的半径之和。如果你将你的怪物路径预先计算成一条圆圈,下一步是将这些圆圈分成......猜猜是什么......一个网格。这可以防止每个检查都必须测试地图上的每个圆圈。这允许您在碰撞图中拥有大量这些圆,因为碰撞测试首先查找塔当前所在的网格条目,然后检查它是否与它最接近的圆相撞,而不是整个地图。重要的是要注意,这个预先计算的圆形列表网格通常在多个相邻网格条目中具有相同的圆,因为包含给定圆的任何部分的每个网格条目必须在其碰撞清单中具有该圆。
前两种网格方法的一个好处是它很容易自己进行QA - 将碰撞图存储为图像并进行视觉检查以确保它看起来适合它所基于的地图。如果您不想编写代码来生成它们,也可以手动绘制它。
圆形方法为您提供合理的曲线并且可以导致更精细的碰撞边缘细节,但是显然更难以测试并确保没有地图具有坏的碰撞贴图。编写地图生成工具也是一项工作。
祝你好运!答案 1 :(得分:2)
我会逐步解决这个问题。让我们来看看你的开始。您有一个由点定义的路径 - 成对的点定义一个线段。所以你真正拥有的是由线段组成的路径。当用户移动鼠标时,您将获得当前位置的x,y坐标。您要做的是找到鼠标指向所有线段的距离。如果距离任何线段小于50像素,则您不希望允许它们在那里构建。
要查找点和线段之间的距离,伪代码看起来像这样。假设点A和B代表线段的两端,点C是鼠标点。
float distancePoint2LineSegment(Point a, Point b, Point c) {
Vector ab = b - a
Vector ac = c - a
Vector bc = c - b
float e = dotProduct(ac, ab)
if (e <= 0.0)
return sqrt(dotProduct(ac, ac))
float f = dotProduct(ab, ab)
if (e >= f)
return sqrt(dotProduct(bc, bc))
return sqrt(dotProduct(ac, ac) - e * e / f)
}
这可以回答你的碰撞检测问题,但我想你会想看看性能。您的路径中将包含多少个线段,并且您希望每次用户移动鼠标时计算每个线段的距离?您可以将线段放入四叉树中,这样您就只需要针对较少数量的线段测试鼠标点碰撞。
答案 2 :(得分:2)
可能更简单,更快速地定义用户可以在地图文件中明显放置塔的区域...将每个区域定义为凸多边形(可以包括地图边缘,分割凹多边形,更喜欢水平或垂直线条) ,然后测试鼠标在其中一个多边形中,请参阅这个实现的答案
How to test if a point is inside of a convex polygon in 2D integer coordinates?
分解为三角形使测试更简单