Я пытаюсь создать функцию, которая распознает, попадает ли мяч в кирпич в моей игре, и регулирует скорость мяча по оси x или y в зависимости от того, где он попадает в кирпич.
Я собираюсь столкнуться Функция проверить, какая ближайшая сторона кирпича в зависимости от местоположения шара. Если мяч попадает в левую или правую часть кирпича, он меняет скорость по оси x, а если он попадает в верх или низ, он меняет скорость по оси y.
В настоящее время он проверяет только левую или правую сторону. , но вот где моя проблема.
Ниже приведен файл, содержащий функцию:
let collision = false;
let bottomOfBall = ball.position.y + ball.height;
let topOfBall = ball.position.y;
let leftSideBall = ball.position.x;
let rightSideBall = ball.position.x + ball.width;
let topOfObject = gameObject.position.y;
let bottomOfObject = gameObject.position.y + gameObject.height;
let leftSideObject = gameObject.position.x
let rightSideObject = gameObject.position.x + gameObject.width;
let ballXMidPoint = rightSideBall - (rightSideBall - leftSideBall / 2);
let ballYMidPoint = bottomOfBall - (bottomOfBall - topOfBall / 2);
let ballXRadius = ball.width / 2;
let vertex = 0;
let nearestBrickSide;
if (topOfObject >= bottomOfBall && leftSideBall >= rightSideObject) {
let x = (leftSideBall - rightSideObject)^2;
let y = (topOfObject - bottomOfBall)^2;
let z1 = Math.sqrt((x- .01) + y);
let z2 = Math.sqrt(x + (y + .01));
if (z1 < z2) nearestBrickSide = topOfObject;
else if (z1 > z2) nearestBrickSide = rightSideObject;
else nearestBrickSide = vertex;
}
else if (topOfObject >= bottomOfBall && leftSideObject >= rightSideBall) {
let x = (leftSideObject - rightSideBall)^2;
let y = (topOfObject - bottomOfBall)^2;
let z1 = Math.sqrt((x+ .01) + y);
let z2 = Math.sqrt(x + (y + .01));
if (z1 < z2) nearestBrickSide = topOfObject;
else if (z1 > z2) nearestBrickSide = leftSideObject;
else nearestBrickSide = vertex;
}
else if (topOfBall >= bottomOfObject && leftSideBall >= rightSideObject) {
let x = (leftSideBall - rightSideObject)^2;
let y = (topOfBall - bottomOfObject)^2;
let z1 = Math.sqrt(x + (y - .01));
let z2 = Math.sqrt((x - .01) + y);
if (z1 < z2) nearestBrickSide = rightSideObject;
else if (z1 > z2) nearestBrickSide = bottomOfObject;
else nearestBrickSide = vertex;
}
else if (topOfBall >= bottomOfObject && leftSideObject >= rightSideBall) {
let x = (leftSideObject - rightSideBall)^2;
let y = (topOfBall - bottomOfObject)^2;
let z1 = Math.sqrt(x + (y - .01));
let z2 = Math.sqrt((x + .01) + y);
if (z1 < z2) nearestBrickSide = leftSideObject;
else if (z1 > z2) nearestBrickSide = bottomOfObject;
else nearestBrickSide = vertex;
}
else if (topOfBall >= bottomOfObject && rightSideBall >= leftSideObject && leftSideBall <= rightSideObject) {
nearestBrickSide = bottomOfObject;
}
else if (topOfObject >= bottomOfBall && rightSideBall >= leftSideObject && leftSideBall <= rightSideObject) {
nearestBrickSide = topOfObject;
}
else if (leftSideObject >= rightSideBall && bottomOfBall >= topOfObject && topOfBall <= bottomOfObject) {
nearestBrickSide = leftSideObject;
}
else if (leftSideBall >= rightSideObject && bottomOfBall >= topOfObject && topOfBall <= bottomOfObject) {
nearestBrickSide = rightSideObject;
}
if (collision === false) {
if (nearestBrickSide === rightSideObject && ballXMidPoint - rightSideObject < ballXRadius) {
collision = true;
return true;
}
else if (nearestBrickSide === leftSideObject && rightSideObject - ballXMidPoint < ballXRadius) {
collision = true;
return true;
}
else return false;
} else return false;
}
Функция кажется слишком широкой, потому что когда я играю в игру, мяч будет переключайте направление х много раз, даже если оно не обязательно близко к кирпичу. Я попытался добавить ограничения в оператор if в конце функции, чтобы функция возвращала true только тогда, когда ballXMidPoint - rightSideObject <= ballXRadius || rightSideObject - ballXMidPoint <ballXRadius. Но это не очень помогает. Я все еще получаю дрожащий шар. </p>
Как мне исправить функцию? Кроме того, как я могу сделать так, чтобы функция не повторялась так быстро? (т.е. я думаю, что с каждым обновлением шар все еще может соответствовать истинным требованиям для функции, и это заставляет шар снова и снова переключать направления. Я устанавливаю переменную, называемую коллизией, так что, когда функция возвращает истину, коллизия true. в моей игре. js, я установил функцию timeOut для сброса столкновения на false после 100 мс. Таким образом, мяч может попадать в кирпич только каждые 100 мс. Есть ли лучший способ настроить эту задержку?
Решено
Мне удалось заставить функцию столкновения работать должным образом, изменив несколько вещей.
1: Я изменил условие, оценивающее функцию на true .
if (nearestBrickSide === rightSideObject &&
leftSideBall - rightSideObject < ballRadius &&
bottomOfBall >= topOfObject &&
topOfBall <= bottomOfObject &&
ball.speed.x <= 0 )
{ return true }
else if (nearestBrickSide === leftSideObject &&
leftSideObject - rightSideBall < ballRadius &&
bottomOfBall >= topOfObject &&
topOfBall <= bottomOfObject &&
ball.speed.x >= 0)
{ return true }
Я изменил свой кирпич. js файл
if (!this.game.ball.collision){
if(detectYCollision(this.game.ball, this )) {
this.game.ball.collision = true;
this.game.ball.speed.y = - this.game.ball.speed.y;
if (this.hitBrick) this.markedForDeletion = true;
this.hitBrick = true;
}
if(detectXCollision(this.game.ball, this )) {
this.game.ball.collision = true;
this.game.ball.speed.x = - this.game.ball.speed.x;
if (this.hitBrick) this.markedForDeletion = true;
this.hitBrick = true;
}
}
//Prevents multiple hits to same brick if ball has not left brick bounds
if (this.game.ball.collision) {
if (this.game.ball.position.x > this.position.x + this.width + this.game.ball.width / 2 ||
this.game.ball.position.x < this.position.x ||
this.game.ball.position.y > this.position.y + this.height + this.game.ball.height / 2 ||
this.game.ball.position.y < this.position.y) {
this.game.ball.collision = false;
}
}