카테고리 보관물: 게임개발

게임개발

누적을 통해 통합해야하는 이유 : 은의 getPosition =

나는 DIY 물리학을 배우는 방법을 배우기 시작했으며, 가장 기본적인 수준에서 통합을 구현하는 것에 대한 질문이 있습니다 (즉 , 오일러 대 RK4 질문 이 아닙니다 ).

거의 모든 예제 integrate()에는 마지막 업데이트 이후의 시간 단계를 가져오고 마지막 업데이트 이후의 가속도 및 / 또는 속도 및 / 또는 위치를 업데이트하는 기능이 있습니다.

가장 간단한 형태로 : position += velocity * deltaTime

그러나 함수 를 변경하여 쉽게 얻을 수있을 때 왜 이렇게 누적되는지 이해하지 못합니다 . 예를 들어 : 은의 getPosition = makeNewFunction()서명을 가진 것을 반환 할 수 있으며 Time -> Position해당 함수의 내부 작업은 적절한 수학 공식을 통해 생성됩니다.

그런 식으로, 축적이 없습니다 … 위치를 얻을 필요가있을 때마다 현재 시간으로 그 기능을 호출합니다.

내 초보자 이해는 이것이 누적으로 인한 오류를 피할 수 있다는 것입니다. 그래서 왜 이것이 작동하지 않습니까?

(fwiw 나는 아이디어의 기본 개념 증명을 작성했지만 동시에 몇 가지 다른 것들을 테스트하므로 가장 깨끗한 예는 아닙니다 : https://github.com/dakom/ball-bounce-frp )

편집 1 : 의견에서 언급했듯이 아직 가속을 변경하거나 저크 및 일정한 가속보다 고차 통합이 필요한 다른 것들을 다루는 것에 대해 배우지 않았다는 것을 지적하는 것이 중요합니다 .

편집 2 : 여기에 아이디어의 기본적인 샘플 코드, 그리고 의사 자바 스크립트 구문 – 참고 getKinematicPosition한다 부분적으로 적용 단지 시간의 새로운 기능 반환되도록 -> 위치를 :

나는 여기에 위치를 고집하고 있지만 그것은 다른 getVelocity것 같아요.

getKinematicPosition = initialVelocity => acceleration => time =>
  ((.5 *acceleration) * (time * time)) + (initialVelocity * time);

getPosition = getKinematicPosition ([0,0,0]) (GRAVITY);

onTick = totalTime => {
   position = getPosition (totalTime);
   onCollision = () => {
     getPosition = changeTheFunction(totalTime);
     //changeTheFunction uses totalTime to base updates from 0
     //it could use getKinematicPosition or something else entirely
   }
}



답변

…이 함수의 내부 동작은 적절한 수학 공식을 통해 생성됩니다 …

이것은 특정 클래스의 문제에서 작동하며 검색해야 할 핵심 문구는 폐쇄 형 솔루션입니다. 예를 들어, Kerbal Space Program에서 궤도에서 우주선의 움직임은 이런 식으로 계산됩니다. 불행히도, 대부분의 사소한 문제 (예 : 우주선의 대기 재진입)에는 알려진 폐쇄 형 솔루션이 없습니다. 따라서 수학적으로 더 간단한 수치 근사치가 필요합니다 (즉 integrate(), 시간이 지남에 따라).


답변

당신의 접근 방식의 문제는 당신 이 당신의 물건 의 역사가 없다는 것 입니다. 방향으로 이동하면 위치를 계산할 수 있지만 무언가를 치고 튀면 어떻게 되나요?
마지막으로 알려진 위치에서 누적되면 영향을 처리하고 그 위치에서 진행할 수 있습니다. 시작부터 계산하려고하면 매번 영향을 다시 계산하거나 새로운 시작 위치로 설정해야합니다.

당신의 예는 레이싱 게임을 생각 나게했습니다. (물리 엔진이 위치를 제어 할 수 있을지는 모르겠지만 설명이 잘되어 있다고 생각합니다.)
자동차로 운전하면 가속 및 감속 할 수 있습니다. 자동차의 속도 프로파일이 처음부터 지금까지 어떻게 보이는지 모른 채 위치를 계산할 수 없습니다. 거리는 처음부터 지금까지 모든 프레임에 저장 한 속도를 저장하는 것보다 훨씬 쉽습니다.

면책 조항 : 나는 지금까지 게임 물리학을 작성하지 않았습니다. 그게 내가 문제를 보는 방법입니다.

편집 :
이 다이어그램에서 시간이 지남에 따라 값이 어떻게 변하는 지 확인할 수 있습니다.
빨간색 = 가속 (시작 가속에서 썰기까지)
녹색 = 속도 (시작에서 중지까지)
파란색 =갔습니다.

총 속도는 시작점에서 실제 로그까지 가속의 필수 요소입니다. (선과 축 사이의 영역)
길이는 속도의 필수 요소입니다.
가속도 값을 알고 있으면 다른 값을 계산할 수 있습니다. 그러나 내가 실수하지 않으면 적분도 PC에 축적되어 계산됩니다. 그리고 모든 가속도 값을 저장하는 것이 더 많은 오버 헤드입니다.
또한 매 프레임마다 계산하기에는 너무 많은 것 같습니다.

가속도 / 속도 / 시간 다이어그램

나는 페인트 기술이 훌륭하다는 것을 알고 있습니다. 😉

편집 2 :
이 예제는 선형 이동입니다. 통조림 방향은 이것을 더욱 어렵게 만듭니다.


답변

그러나 함수를 변경하여 쉽게 얻을 수있을 때 왜 이렇게 누적되는지 이해하지 못합니다. 예를 들어, getPosition = makeNewFunction ()은 Time-> Position의 시그니처가있는 것을 반환 할 수 있으며 해당 함수의 내부 작업은 적절한 수학 공식을 통해 생성됩니다.

당신은 할 수 있습니다!

분석 또는 폐쇄 양식 솔루션을 사용하여 호출됩니다 . 시간이 지남에 따라 누적되는 반올림 오류가 없기 때문에 더 정확하다는 이점이 있습니다.

그러나 이것은 닫힌 양식을 미리 알고있는 경우에만 작동 합니다. 게임의 경우에는 종종 그렇지 않습니다.

플레이어의 움직임이 불규칙하며 단순히 미리 계산 된 기능에 넣을 수 없습니다. 플레이어는 자신의 속도와 방향을 매우 자주 변경할 수 있습니다.

NPC는 폐쇄 형 솔루션을 활용할 수 있으며 실제로는 그렇지 않습니다. 그러나 이것은 다른 단점이 있습니다. 간단한 레이싱 게임을 생각해보십시오. 차량이 다른 차량과 충돌 할 때마다 기능을 변경해야합니다. 지하에 따라 차가 더 빨리 움직일 수 있습니다. 그런 다음 폐쇄 형 솔루션을 찾는 것은 매우 어렵습니다. 실제로, 닫힌 양식을 찾는 것이 불가능하거나 너무 복잡하여 단순히 실현 가능하지 않은 경우가 더 많습니다.

폐쇄 형 솔루션을 사용하는 좋은 예는 Kerbal Space Program입니다. 로켓이 추력을받지 않고 궤도에 오르 자마자 KSP는 “레일”에 놓을 수 있습니다. 궤도는 양체 시스템에서 미리 결정되며 주기적입니다. 로켓이 추력을 더 이상 적용하지 않는 한, 로켓의 위치를 ​​이미 알고 있으며 간단히 호출 할 수 있습니다 getPositionAtTime(t)(정확히 이름이 지정되지는 않았지만 아이디어를 얻음).

그러나 실제로는 단계별 통합 만 사용하는 것이 훨씬 더 실용적입니다. 그러나 폐쇄 형 솔루션이 존재하고 계산하기 쉬운 상황이 나타나면 해결하십시오! 사용 하지 않을 이유가 없습니다 .

예를 들어, 캐릭터가 대포를 목표로하는 경우 폐쇄 형 솔루션을 사용하여 대포 볼의 예상 충격 점을 쉽게 표시 할 수 있습니다. 또한 게임에서 대포 공 코스를 변경할 수없는 경우 (예 : 바람 없음) 대포 공을 이동하는 데 사용할 수도 있습니다. 그렇다면 캐논 볼의 경로로 이동하는 장애물에 특별한주의를 기울여야합니다.

비슷한 상황이 많이 있습니다. 라운드 기반 게임을 제작하는 경우 RTS 게임을 제작할 때 사용할 수있는 폐쇄 형 솔루션이 훨씬 많을 것입니다. 모든 매개 변수를 미리 알고 있으며 변경되지 않는다는 것을 확실하게 말할 수 있기 때문입니다. 예를 들어)

단계별 적분의 수치 부정확성을 방지하는 기술이 있습니다. 예를 들어 누적 오차를 추적하고 수정 항을 적용하여 오차를 확인할 수 있습니다 (예 : Kahan Summation).


답변

단순한 튀는 공의 경우 폐쇄 형 솔루션을 쉽게 찾을 수 있습니다. 그러나,보다 복잡한 시스템은 정규 미분 방정식 (ODE) 해결이 필요한 경향이 있습니다. 가장 간단한 경우를 제외한 모든 것을 처리하기 위해 수치 솔버 가 필요합니다.

숫자 형 ODE 솔버에는 명시 적 및 암시 적이라는 두 가지 클래스가 있습니다. 명시 적 솔버는 다음 상태에 대해 닫힌 형태의 근사값을 제공하지만 암시 적 솔버에서는 방정식을 풀어야합니다. 튀는 공에 대해 설명하는 것은 실제로 알든 모르 든 암시 적 ODE 솔버입니다!

암시 적 솔버는 훨씬 더 큰 시간 단계를 사용할 수 있다는 이점이 있습니다. 튀는 공 알고리즘의 경우, 시간 간격은 다음 충돌까지의 시간 (기능이 변경됨)까지 지속될 수 있습니다. 이렇게하면 프로그램이 훨씬 빠르게 실행될 수 있습니다. 그러나 일반적으로 관심있는 ODE에 대한 올바른 암시 적 솔루션을 항상 찾을 수있는 것은 아닙니다. 할 수없는 경우 명시 적 통합으로 넘어갑니다.

명시 적 통합으로 볼 수있는 가장 큰 장점은 문제가 잘 알려져 있다는 것입니다. 60 년대의 교과서를 열고 특정 통합 기술에서 발생하는 작은 문제에 대해 알아야 할 모든 것을 읽을 수 있습니다. 따라서 개발자는 이러한 기술을 한 번 학습하므로 다시 배울 필요가 없습니다. 암시 적 통합을 수행하는 경우 각 유스 케이스는 약간 씩 다르며 약간의 차이가 있습니다. 한 작업에서 다음 작업에 배운 내용을 적용하기가 조금 더 어렵습니다.


답변

위치 (t) = v (t) * t

pos (0) = 0 및 v (t) = k 인 경우에만 작동

초기 조건과 전체 속도 함수에 대한 지식없이 위치와 시간을 연관시킬 수 없으므로 방정식은 적분의 근사치입니다.

pos (t) = 0에서 t까지의 v (t) dt의 적분

편집하다 _________

의견마다 약간의 증거가 있습니다 (pos (0) = 0이라고 가정)

v (t) = 4라고하자

등식 1 : 위치 (t) = 4 * t (올바름)

등식 2 : pos (t) = c + 4 * t ~ 0 ~ t = 4 * t (올바름)

v (t) = 2 * t라고하자

등식 1 : 위치 (t) = 2 * t ^ 2 (잘못된)

등식 2 : pos (t) = c + t ^ 2 ~ 0 ~ t = t ^ 2 (올바른)

방정식이 이미 일정한 가속도를 고려한다는 점을 추가해야합니다 (즉, 방정식은 v (t) = v0 + a * t이고 적분 한계는 t0 및 t입니다). 초기 위치, 초기 속도 및 가속도는 일정하게 유지됩니다.

EDIT2 ________

또한 초기 위치, 초기 속도, 초기 가속 및 일정한 저크로 위치를 계산할 수도 있다고 덧붙여 야합니다. 다시 말해, 방정식 대 속도, 저크, 다음에 오는 것 등으로 분리하여 위치 대 시간을 나타내는 eqn 2를 기반으로 함수를 만들 수 있지만, 방정식의 경우에만 정확합니다. v (t)는 그런 식으로 모델링 할 수 있습니다. 속도, 가속도, 일정한 저크 등으로 v (t)를 모델링 할 수없는 경우, 튀는 것, 공기 저항, 바람 등이있을 때 발생하는 등식 2의 근사치로 돌아 가야합니다. .


답변