2010-08-31 58 views
7

所以我正在用HTML5和Javascript制作塔防游戏。我唯一的问题是检测鼠标何时与攻击者的路径接触,这是阻止玩家在路径上建造塔楼所必需的。攻击者的路径在MAP.js文件中(参见底部的链接)由一个二维数组(一个包含x和y对的数组)确定,所以我需要处理的是一系列点连接时组成一条路径。我只是想禁止玩家将塔放置在路径的50个像素内。说实话,我只是碰撞检测很糟糕,所以一些帮助将不胜感激。HTML5画布:鼠标和多边形碰撞检测

这里是链接到所有代码: http://shapeshifting.comuv.com/Tower_Defense/td/

正如你可能想象,只有.js文件都适用,但大多数相关的代码是objects.js文件中。 (请原谅杂乱)

回答

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) 
} 

这会回答你的碰撞检测问题,但我想你会想看看性能。您的路径中将有多少线段,并且您想要在每次用户移动鼠标时计算到每个线段的距离?您可以将线段放入四叉树中,以便您只需对较少数量的线段测试鼠标点碰撞。

3

碰撞检测是那些老的一个,隐藏编码游戏的问题通常人们会选择darkpenguin以某种方式预先计算你的静态地图上的哪些位置是不可放置的。下一步是想出一种方法来指定最有效的碰撞图。

你不希望你的游戏做一吨的数学响应用户移动他们的鼠标 - 它需要短而快 - 所以预先计算下来的东西快是至关重要的。

如果您的地图是一个网格,那么你有你的答案就在那里 - 碰撞地图是预先计算的二维数组 - 基本上与网格上的每一个地方一个像素很小的黑白图像。白色像素(1)可放置,黑色像素(0)不可放置。您只需使用这个真/假的二维数组作为查找。如果您想节省内存,您可以将网格上的每个32位空格分隔成单个位标志。

如果你的地图不是网格,那么你仍然想要预先计算的东西,但是这个策略有点复杂。第一种可能性是像Hitesh那样执行数学运算以生成稍微更高分辨率的碰撞图,其余部分与网格策略完全相同 - 例如,如果每个4x4像素块都是一个碰撞入口,那么塔是否可以是放置是一个测试,以确定它的坐标是否在1以上 - 你可能需要100%的测试为1,或者你可以让它们达到一点,让75%的测试为1。

如果这还不够详细,您可以做这些更复杂的多边形测试,但您希望它们尽可能简单。当不使用预先计算好的网格时,最简单的2D碰撞测试是2个圆圈 - 您只需计算它们中心之间的距离并检查它们大于还是小于它们的半径之和。如果您预先将您的怪物路径预先计算为一系列圆圈,那么下一步就是将这些圆圈分成......猜猜看......网格。这可以防止每次检查都必须测试地图上的每个圆圈。这使得您可以在碰撞图中包含大量的这些圆,因为碰撞测试首先查找塔目前正在结束的网格输入,然后检查它是否与最接近的圆相碰撞,而不是整个地图。请注意,此预先计算的圆形列表网格在多个相邻网格条目中通常会具有相同的圆形,因为包含给定圆形的任何部分的每个网格条目都必须在其碰撞检查清单中包含该圆形。

关于前两种网格方法的好处之一是它很容易进行QA测试 - 从字面上将碰撞图存储为图像并进行视觉检查,以确保它看起来适合它所基于的地图。如果您不想编写代码来生成它们,也可以手动绘制它。

圆形方法为您提供了合法的曲线,并可以导致更细微的碰撞边缘细节,但它显然更难以测试并确保没有地图具有不良碰撞贴图。编写地图生成工具也是更多的工作。

祝你好运!