JS Arkanoid碰撞检测(侧面vs底部和顶部)

时间:2019-01-25 18:26:14

标签: javascript collision-detection game-physics

我知道有很多线程有类似问题,并且我已经阅读并尝试了许多问题,但是仍然无法获得所需的结果。也许有人可以帮助我。

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

ball和Bricks是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

1 个答案:

答案 0 :(得分:0)

我将从

开始
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;
}