내 홈페이지 의 탁구에서 사용한 관련 논리 는 다음과 같습니다.
본질적으로 볼이 패들과 충돌 할 때 방향은 완전히 무시됩니다. 패들 중심에서 얼마나 멀리 떨어져 있는지에 따라 새로운 방향이 부여됩니다. 공이 중앙의 패들에 맞으면 정확히 수평으로 보내집니다. 가장자리에 맞으면 극단적 인 각도 (75도)로 날아갑니다. 그리고 항상 일정한 속도로 움직입니다.
var relativeIntersectY = (paddle1Y+(PADDLEHEIGHT/2)) - intersectY;
패들의 중간 Y 값을 취하고 공의 Y 교차점을 뺍니다. 패들이 높이가 10 픽셀 인 경우이 숫자는 -5와 5 사이입니다. 이제이 패들이 "패들 공간"에 있기 때문에 "상대적 교차"라고 부릅니다.
var normalizedRelativeIntersectionY = (relativeIntersectY/(PADDLEHEIGHT/2));
var bounceAngle = normalizedRelativeIntersectionY * MAXBOUNCEANGLE;
상대 교차점을 취해 패들 높이의 반으로 나눕니다. 이제 -5에서 5까지의 숫자는 -1에서 1까지의 10 진수입니다. 그것은 것 정규화 . 그런 다음 공을 튕길 수있는 최대 각도로 곱하십시오. 5 * Pi / 12 라디안 (75도)으로 설정했습니다.
ballVx = BALLSPEED*Math.cos(bounceAngle);
ballVy = BALLSPEED*-Math.sin(bounceAngle);
마지막으로 간단한 삼각법을 사용하여 새로운 공 속도를 계산하십시오.
이것은 효과가 아닐 수도 있고, 정규화 된 상대 교차점에 최대 속도를 곱하여 속도를 결정할 수도 있습니다. 이것은 공이 패들의 가장자리 근처에 닿으면 빨라지거나 중앙 가까이에 닿으면 느려집니다.
벡터의 모양이나 볼의 벡터 변수 (속도 및 방향)를 저장하는 방법에 대한 코드가 필요할 수 있습니다.
벡터는 속도와 방향을 모두 암시 적으로 포함합니다. 내 벡터를 "vx"및 "vy"로 저장합니다. 즉, x 방향의 속도와 y 방향의 속도입니다. 물리학 입문 과정을 수강하지 않았다면 다소 이질적인 것처럼 보일 수 있습니다.
내가 이렇게하는 이유는 프레임 당 계산이 줄어들 기 때문입니다. 모든 프레임에서 방금 수행 한 시간 x += vx * time;
과 y += vy * time;
마지막 프레임 이후 시간이 밀리 초 단위이므로 속도는 밀리 초당 픽셀로 표시됩니다.
공을 구부리는 능력을 구현하는 것과 관련하여 :
우선, 공을 쳤을 때 패들의 속도를 알아야합니다. 즉, 패들의 이력을 추적해야 패들의 과거 위치를 하나 이상 알 수 있으므로 현재 위치와 비교하여 움직일 수 있는지 확인할 수 있습니다. (위치 변경 / 시간 변경 = 속도; 두 개 이상의 위치와 해당 위치의 시간이 필요합니다)
이제 공 의 각속도 를 추적해야 합니다. 공의 이동 속도 를 실제로 나타내지 만 공의 실제 회전과 같습니다. 패들과 충돌 할 때 볼의 상대 위치에서 바운스 각도를 보간하는 방법과 유사하게 충돌시 패들 속도에서이 각속도 (또는 스핀)를 보간해야합니다. 바운스 각도로 단순히 스핀을 설정하는 대신 게임에서 잘 작동하는 경향이 있기 때문에 공의 기존 스핀에 더하거나 빼기를 원할 수 있습니다 (플레이어가 볼이 회전하는 것을 볼 수 있고 회전하게 함). 더 강하게 회전하거나 똑바로 움직 이도록 스핀에 대응하십시오).
그러나 이것이 가장 상식적이고 아마도 그것을 구현하는 가장 쉬운 방법이지만 바운스의 실제 물리는 물체에 부딪 치는 속도에만 의존하지는 않습니다. 표면에 비스듬히 치는 각속도 (스핀 없음)가없는 물체에는 스핀이 가해집니다. 이것은 더 나은 게임 메카닉으로 이어질 수 있습니다. 그래서 당신은 이것을 조사하고 싶을 것입니다. 그러나 나는 그 뒤에 물리가 확실하지 않기 때문에 그것을 설명하려고하지 않을 것입니다.