Почему мяч в моей игре не останавливается на границе и не отскакивает назад?

#javascript #html #html5-canvas #coordinates

#javascript #HTML #html5-холст #координаты

Вопрос:

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

Код:

 if(ballY<=0){
     ballSpeedY = -ballSpeedY;   
    }

    else if(ballY>=HEIGHT-10){
     ballSpeedY = -ballSpeedY;   
    }




    if(ballX >= WIDTH-10){

        ballSpeedX = -ballSpeedX;

    }


    else if(ballX <= 0){

        ballSpeedX = -ballSpeedX;

    }
 

Здесь я изменяю скорость мяча, если он находится вблизи границ. Чтобы заставить его работать правильно, я должен изменить число в операторах if на 8 вместо 0. Почему это так? Вот это JFiddle. Я могу просто исправить проблему, изменив 0 на 8, но я хочу знать, почему это происходит.

Ответ №1:

Это происходит на всех 4 сторонах вашего холста, однако справа и внизу у вас есть ballX >= WIDTH-10 и ballY >= HEIGHT-10 соответственно.

Вам нужно сделать то же самое и с другими сторонами, например ballY <= 10 , для top и ballX <= 10 для left.

Это происходит по одной простой причине — координаты вашего мяча отсчитываются от его центра. Это 0, 0 часть вашего шара, как 0, 0 часть вашего прямоугольника — верхний левый угол.

И когда вы говорите ballX <= 0 , это означает, что мяч должен будет коснуться границы своей центральной точкой, а для этого он должен пройти внутри вашей левой границы.

Комментарии:

1. @RokoC. Buljan Я увеличил скорость x3 и добавил 10px буфер слева и сверху — кажется, здесь работает

2. О, теперь я понимаю. Я всегда думал, что координата — это верхний левый угол, как в прямоугольниках.

Ответ №2:

Как указано в Ответе, мяч вытягивается из его центра, и корректировка левого и верхнего тестов с учетом этого почти остановит попадание мяча в стену. Но это просто удача, когда мяч отскакивает от стены, не заходя внутрь. Если вы измените ширину холста на 799 и посмотрите, как отскакивает правый край, вы увидите проблему: мяч войдет в стену на 4 пикселя.

Вы перемещаете шар на 5 пикселей в направлении x, а затем проверяете его на стенку

 ballX  = ballSpeedX;
if(ballX >= width - 10){
    ballSpeedX = -ballSpeedX;
}
 

Если ширина = 100, а последняя позиция шара равна 89, вы добавляете 5, чтобы получить 94. Это приводит к изменению скорости мяча на противоположную, но мяч по-прежнему будет нарисован на 94 (4 пикселя дальше).

Когда вы делаете отскок, вам нужно позаботиться о времени между кадрами. Мяч редко попадает в стену в начале или в конце кадра, но в какой-то момент во время кадра. За это время он, возможно, отодвинулся на много пикселей от стены.

Правильный способ сделать это — определить, когда мяч ударяется о стену, а затем отодвинуть его от стены на нужную величину. Это очень просто для линейного перемещения, так как расстояние до стены совпадает с расстоянием, на которое она отодвинется..

 ballX  = ballSpeedX;
if(ballX >= width - 10){
   var dist = ballX - (width - 10); // how far into the wall
   ballX = (width - 10) - dist; // the distance into the wall is the distance 
                                // the ball has moved away from the wall
   ballSpeedX = -ballSpeedX;
}
 

То же самое для левой стороны

 if(ballX <= 10){
   var dist = 10 - ballX; // how far into the wall
   ballX = 10   dist; // the distance into the wall is the distance 
                      // the ball has moved away from the wall
   ballSpeedX = -ballSpeedX;
}
 

И сделайте то же самое для верха и низа.