【问题标题】:Collision Detection Function碰撞检测功能
【发布时间】:2016-01-30 23:34:29
【问题描述】:

我已经构建了这个函数,以便能够检查两个对象是否在 AABB 碰撞类型模型中发生接触,但我无法完全弄清楚逻辑,或者更确切地说为什么它不起作用。

function hitTest(x1, y1, w1, h1, x2, y2, w2, h2) {
    //x1, y1 = x and y coordinates of object 1 
    for (var x = 0; x < AliLength; x++) {
        x1 = AliensArrR1[x].getX();
        y1 = AliensArrR1[x].getY();
    }
    //w1, h1 = width and height of object 1
    w1 = 50;
    h1 = 18;
    //x2, y2 = x and y coordinates of object 2 (usually midpt)
    for (var x = 0; x < bullets.length; x++) {
        x2 = bullets[x].getX();
        y2 = bullets[x].getX();
    }
    // w2, h2 = width and height of object 2
    w2 = 3;
    h2 = 13;
    if ((x1 <= x2 && x1 + w1 >= x2) &&
    (y1 <= y2 && y1 + h1 >= y2) && (x2 <= x1 && x2 + w2) && (y2 <= y2 && y2 + h2))
        alert("Hit");
    else
        return false;
};

每行有 12 张图像,每行有一个数组,我现在不担心性能,只是想确保我可以让它在一张上工作并获得正确的逻辑。

非常感谢任何建议!

编辑:我正在尝试检查宽度为 18 和 50 的对象是否与宽度为 3 和高度为 13 的另一个对象重叠,这些对象永远不会仅改变 x 和 y 轴的变化。我是做碰撞检测的新手,并且在对如何应用检查每个 x 和 y 以查看它们是否相交的逻辑进行了几次尝试之后。我想我会寻求帮助,因为我显然走错了方向。

![这就是我想要实现的目标]:http://uploads.gamedev.net/monthly_06_2011/ccs-8549-0-64600400-1307074262.gif

【问题讨论】:

  • 即使在alert() 中,您也过于慷慨地使用大写字母作为首字母。在 JS 中,只有构造函数名称应该以大写字母开头。
  • 我在从我的 IDE 粘贴后添加了警报,但同意来自不同的语言我仍然习惯正确的语法。这让我和你一样烦 :)!
  • 好吧,我不介意你刚才提到的约定,但是Alert() 会给你一个参考错误...
  • 更新了我的帖子,我的版本不一样。
  • 我不明白为什么你会收到参数并且什么都不做。另请注意,在for 循环之后,x1 和 y1 值将是 ali 数组中的最后一项,同样适用于 x2 y2 循环。

标签: javascript canvas collision


【解决方案1】:

我建议你稍微重构一下你的代码。保留八个参数,但不要在函数hitTest 中为它们分配任何内容,并且不要引用任何全局变量或常量。只需比较给定的坐标和宽度,如果重叠则返回true,否则返回false。

通过给它一些测试用例来测试这个函数。如果您无法在脑海中可视化,请绘制一个 2D 网格并标记轴,然后绘制任意矩形。选择两个不重叠的,将它们提供给您的函数,并检查它是否返回 false。选择两个重叠的,将它们提供给您的函数,并检查它是否返回 true。选择两个刚刚接触的,将它们提供给您的函数,并检查它是否返回您希望它返回的内容。重复直到你确信你的代码是正确的。

然后使用该函数实现另一个函数,该函数遍历所有外星人和所有子弹,并使用hitTest 检查它们是否发生碰撞。它应该给出18、50 等作为宽度和高度。如果坐标指的是对象的中心,您可能需要偏移它们,以便它们指的是右上角。

提示

如果您发现很难在 2D 中进行碰撞检查,请创建一个更简单的函数,该函数采用两个 1D 线段(x1, w1, x2, w2) 并确定它们是否重叠。 2D 案例可以分解为两个 1D 检查:对象应在水平和垂直方向上重叠。

最终解决方案

x1 + w1 >= x2 && x2 + w2 >= x1 && y1 + h1 >= y2 && y2 + h2 >= y1

【讨论】:

  • 这绝对是我一直在寻找的那种答案,我要在白板上画出草图然后试一试......应该早点想到!
  • 我认为为什么我发现这更困难的一个重要原因是我如何实现我希望检查碰撞的图像,通过将它们添加到数组中,我不知道如何在不使用 for 循环的情况下将 Position 值放入该算法。
  • 诀窍是使用嵌套的for循环:for (each alien) { for (each bullet) { if (hitTest(current alien and current bullet)) { ... } } }
  • 这是我目前拥有的 ((x1 &gt;= x2 + w1 &amp;&amp; x2 &lt;= x1 + w2) &amp;&amp; (y1 &gt;= y2 + w1 &amp;&amp; y2 &lt;= y1 + w2)) 似乎不起作用:/
  • 应该是x1 + w1 &gt;= x2 &amp;&amp; x2 + w2 &gt;= x1(一个段的右边缘应该比另一段的左边缘更靠右)。 y 也一样。
【解决方案2】:

大部分都完成了,buuuut...

给定w1 的宽度、h1 的高度、x1 的 X 位置、y1 对象 1 的 Y 位置,以及 x2、y2、y2、h2 的同义词在对象 2 上:

条件应该是条件之间的或,我敢打赌你的垂直部分有一些拼写错误。评论版本:

if (
    // Horizontal collision
    // Does right edge of 1 collide with left edge of 2? Only when 1 to the left of 2
    (x1 <= x2 && x1 + w1 >= x2) ||
    // Does left edge of 1 collide with right edge of 2? Only when 2 to the left of 1
    (x2 <= x1 && x2 + w2 >= x1) ||

    // Vertical collision
    // Does bottom edge of 1 collide with top edge of 2? Only when 1 above 2
    (y1 <= y2 && y1 + h1 >= y2) ||
    // Does top edge of 1 collide with bottom edge of 2? Only when 2 above 1
    (y2 <= y1 && y2 + h2 >= y1)
) {
    // hit
}

【讨论】:

  • 此代码不正确。使用(x1, y1) = (0, 0), (x2, y2) = (10, 0), w1 = h1 = w2 = h2 = 4 对其进行测试。他们不重叠,但它说他们击中了。
【解决方案3】:

没错,但就是这样:

function hitTest(x1, y1, w1, h1, x2, y2, w2, h2) {    
  if (((x1 <= x2 && x1 + w1 >= x2) || (x2 <= x1 && x2 + w2 >= x1)) && ((y1 <= y2 && y1 + h1 >= y2) || (y2 <= y1 && y2 + h2 >= y1)))
    return true; 
  else
    return false;    
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多