【问题标题】:JS Arkanoid collision detection (sides vs bottom and top)JS Arkanoid 碰撞检测(侧面与底部和顶部)
【发布时间】:2019-06-19 14:56:21
【问题描述】:

我知道有很多类似问题的主题,我已经阅读并尝试了很多,但我仍然无法得到我正在寻找的结果。也许有人可以帮助我。

我正在编写一个 JS Arkanoid (Breakout) 类型的游戏来提高我的 JS 技能,但我在碰撞检测方面遇到了一些问题。与桨或墙壁的碰撞正在起作用,但与砖块没有碰撞。

球和砖是类 Ball 和 Brick 的实例,每个都有自己的

pos: {
    x: ...
    y: ...
}

球从中心(using ball.pos.xball.pos.y)拉出,半径为ball.r。球还具有 x 和 y 速度(ball.vel.xball.vel.y)。

积木从左上角绘制(brick.pos.xbrick.pos.y),它们有高度(brick.h)和宽度(brick.w)。我还在砖块上添加了一个中心点(brick.center.xbrick.center.y)。

在球的更新功能中,我检查与每个砖块的碰撞,如下所示:

for (let i = 0; i < bricks.length; i++) {
    let collision = detectCollision(this, bricks[i]);
}

detectCollisions 是

function detectCollision(ball, brick) {
    let xDist = calculateDistance(ball.pos.x, brick.center.x);
    let yDist = calculateDistance(ball.pos.y, brick.center.y);

if (xDist < (ball.r + brick.w / 2) && yDist < (ball.r + brick.h / 2)) {
    return true;
} else {
    return false;
}

function calculateDistance(pointA, pointB) {
    return Math.abs(pointA - pointB);
}

我现在知道这样的代码实际上并没有做任何事情。我只是将它存储在collision 变量中。这只是向您展示我的想法。我可以用这个功能检测球和砖是否碰撞,但无法检测到球碰撞到哪一侧。

我现在缺少并且似乎无法理解的是如何检测碰撞是与顶部、底部还是侧面之一。如果碰撞发生在顶部或底部,我必须翻转ball.vel.y,如果它与其中一侧发生碰撞,我必须翻转ball.vel.x

【问题讨论】:

  • 检查在if 语句中失败的是第一个(X 方向)还是第二个(Y 方向)条件,然后返回不同的值而不是布尔值。
  • @Bergi 你能详细说明一下吗?这两个条件都必须为真才能成为碰撞。是的,你是对的,我想返回“top”或“right”之类的东西......

标签: javascript collision-detection game-physics


【解决方案1】:

我会开始

function detectCollision(ball, brick) {
    let xDist = calculateDistance(ball.pos.x, brick.center.x) - brick.w / 2;
    let yDist = calculateDistance(ball.pos.y, brick.center.y) - brick.h / 2;

    if (xDist < ball.r && yDist < ball.r) {
        return true;
    } else {
        return false;
    }
}

其中xDistyDist 现在是球与砖最近边缘之间的绝对距离(在砖的最近角处相交)。您现在不仅可以使等式适用于圆球:

xDist < ball.r && yDist < 0 || yDist < ball.r && xDist < 0 || xDist**2 + yDist**2 < ball.r**2

还要通过xDistyDist之间的比例来区分边:

if (/* collides */) {
    if (xDist < yDist)
        return "vertical"; // from top or bottom
//  else if (xDist == yDist)
//      return "45°";
    else
        return "horizontal"; // from left or right
} else {
    return null;
}

【讨论】:

  • 哦,现在我明白你的意思了。谢谢,这看起来是个好主意。我试试看! =)
猜你喜欢
  • 2015-12-02
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
相关资源
最近更新 更多