Обнаружение столкновения арканоида JS (стороны против дна и вершины) - PullRequest
0 голосов
/ 25 января 2019

Я знаю, что есть много тем с похожими вопросами, и я прочитал и попробовал многие из них, но все же я не могу получить результат, который ищу. Может быть, кто-то может мне помочь.

Я пишу игру типа JS Arkanoid (Breakout), чтобы улучшить свои навыки JS, и у меня возникли некоторые проблемы с обнаружением столкновений. Столкновение с веслом или стенами работает, но не с кирпичами.

Мяч и кирпичи являются экземплярами классов Ball и Brick, каждый из которых имеет свои

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

Мяч вытянут из центра (using ball.pos.x и ball.pos.y) и имеет радиус ball.r. Мяч также имеет скорость x и y (ball.vel.x и ball.vel.y).

Кирпичи взяты из верхнего левого угла (brick.pos.x и brick.pos.y) и имеют высоту (brick.h) и ширину (brick.w). я также добавил центральную точку в кирпичи (brick.center.x и brick.center.y).

В функции обновления мяча я проверяю наличие столкновений с каждым кирпичом следующим образом:

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

, а обнаружение коллизий

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 голосов
/ 26 января 2019

Я бы начал с

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

где xDist и yDist - теперь абсолютные расстояния между мячом и ближайшими краями кирпича (пересекающиеся в ближайшем углу кирпича). Теперь вы можете не только заставить уравнение работать с круглыми шарами:

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

, но также различают стороны по соотношению xDist и yDist:

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;
}
...