Hacker News

2D Vehicles

2D 차량 물리 시뮬레이션 — GTA 차량 시스템의 출발점

1996년 Atari ST에서 만든 2D 물리 시뮬레이션이 Grand Theft Auto 차량 시스템의 토대가 됐습니다. 저자는 이를 JavaScript로 재현하고, 강체 물리와 단순화한 타이어 힘 모델이 차량 움직임을 만드는 과정을 설명합니다.

AI 요약

저자 Pat Kerr는 1996년 8월 주말에 Atari ST에서 GFA BASIC으로 만든 2D 물리 시뮬레이션을 Grand Theft Auto(GTA)의 차량 시스템에 활용했습니다. 당시 와이어프레임으로 만든 프로토타입을 30주년에 맞춰 JavaScript로 다시 구현해 공개했습니다. 브라우저에서 자동차(Car), 우주선(Ship), 벽돌(Brick) 모드를 바꿔가며 조작할 수 있습니다.

강체 물리와 차량 동작

시뮬레이션은 두 층으로 나뉩니다. 바탕에는 위치와 속도, 각도와 각속도를 추적하는 2D 강체(rigid body) 물리가 있습니다. 물체 중심에 힘을 가하면 이동하고, 중심에서 벗어난 곳에 힘을 주면 회전도 생깁니다. 힘과 토크를 합산해 속도를 갱신한 뒤 위치와 각도를 진행합니다. 회전하는 물체 위 한 지점의 속도는 몸체 전체의 이동과 중심 주위 회전을 합쳐 계산합니다.

그 위에 모드별 동작을 얹습니다. Brick은 포인터로 끌어 힘을 주고, Ship은 부착 지점에 추진력을 가합니다. Car는 엔진 힘과 조향을 적용하며, 네 타이어 위치에서 저항력을 계산합니다. 모드를 바꾸면 차체 모양과 동작 방식은 바뀌지만 위치와 운동 상태는 유지됩니다.

타이어 저항으로 조향 구현

자동차는 각 타이어 위치의 속도를 바퀴 진행 방향과 옆 방향으로 나눕니다. 굴러가는 방향에는 약한 저항을, 옆으로 미끄러지는 방향에는 더 강한 저항을 줍니다. 앞바퀴 방향을 조향으로 바꾸면 타이어 힘이 차체를 회전시킵니다. 핸드브레이크를 당기면 뒷바퀴의 진행 방향 저항이 커지고 옆 방향 접지력은 줄어듭니다.

저자는 이 타이어 모델이 물리적으로 정확하지 않다고 설명합니다. 힘은 속도에 비례하며 상한이 없습니다. 실제 타이어의 마찰이나 슬립, 한계 접지력을 그대로 구현하기보다 점성 저항에 가까운 감쇠 모델입니다. 단순한 계산으로 바퀴가 옆으로 밀리는 움직임을 억제해 조작감을 만들었습니다. 저자는 당시에도 이 근사가 정확하지 않다는 점을 알았지만, 원하는 플레이 감각을 내기에 충분했다고 말합니다.

경계 충돌과 조작

화면 가장자리에는 간단한 충돌 장벽을 설정할 수 있습니다. 차체가 경계를 넘어가면 안쪽으로 되돌리고, 장벽 방향으로 움직이던 경우 접촉 충격량을 적용합니다. 충돌 지점이 중심에서 벗어나면 속도뿐 아니라 회전도 바뀝니다. 다만 마찰이 없는 가장자리용 간단한 해결기이며, 일반적인 충돌 시스템은 아닙니다. 차체 면이 장벽에 닿을 때는 접촉점 하나 대신 접촉점들의 중간을 사용해 불필요한 회전을 줄입니다.

재현판에서는 숫자 키 1~3으로 모드를 고릅니다. B 키는 가장자리 장벽을 켜고 끄며, G 키는 수직 중력을 전환합니다. Z 키는 카메라가 차량을 따라가기 시작하는 범위를 바꾸고, X 키는 속도가 빨라질수록 카메라가 뒤로 물러나는 줌을 전환합니다. 후자의 카메라 동작은 GTA에서도 사용한 방식입니다.

Hacker News 반응

  • @slowin — 여전히 조작하는 재미가 있습니다. 역사도 흥미롭고, 프로토타입 장난감이 제품 개발에서 왜 중요한지 잘 보여주는 사례입니다. 프로토타입에서는 개별 개념을 다른 부담이나 제품 수준의 완성도를 신경 쓰지 않고 시험할 수 있습니다.
  • @matsemann — 좋아하고 이해하고 싶지만, 다이어그램은 쓸모없고 대부분 이해하기 어렵습니다. 왜 이런 방식으로 작동하는지, 어떻게 적절한 감각을 만들었는지 알고 싶었는데 코드가 하는 일을 되풀이하는 내용뿐입니다.
    • @PatKerr — 구체적으로 무엇을 더 알고 싶은지 묻고 싶습니다. 핵심은 교과서 수준의 2D 강체 시뮬레이션이고, 자동차는 타이어에 어떤 힘을 줄지 정하는 문제입니다. 타이어는 앞뒤로 가려 하고 바퀴 방향에 비해 옆으로 움직이는 것을 거부합니다. 타이어 힘은 마찰과 대략 비슷하지만 정확히 같지는 않습니다. 단순한 방식으로 조작 가능한 움직임을 만들려고 의식적으로 택한 근사였습니다.
  • @PatKerr — 다이어그램은 AI가 코드에서 생성했습니다. 예전 Doxygen 같은 도구와 비슷한 용도였고, 시간이 빠듯해 직접 그릴 마음은 들지 않았습니다. 처음 나온 결과보다 유용하게 만들려고 조금씩 고쳤습니다.
  • @fxtentacle — 이 글에는 물리적으로 올바른 충돌 엔진 안에서 설계된 자동차 같은 느낌을 만드는 방법에 관한 진지한 구조적 통찰이 있습니다. 균형을 잡기 매우 어려운데 저자가 설명하고 있습니다. 이런 구조를 AI가 만들지는 못했을 것이고, 오랜 작업에 LLM을 얇게 덧댄 결과라고 봅니다.
  • @andremendes — 자동차를 가속한 뒤 Brick 모드로 바꾸면 벽돌이 감속하지 않습니다. 의도된 동작인지 모르겠지만 이상하게 느껴집니다.
    • @PatKerr — 공기 저항이나 일반적인 속도 감쇠가 거의 없고, 차체 모양을 바꿔도 속도는 유지됩니다. 의도된 동작에 가깝지만 큰 차이는 아닙니다.
  • @baw-bag — 저속으로 주차 공간에 후진할 때 차량이 바퀴 방향과 다르게 옆으로 움직이는 문제를 몇 년 동안 해결하려 했습니다. 그 현상 없이 좋은 조작감을 만들려고 복잡한 차량 동역학 책까지 봤지만, 결국 작업을 접었습니다. 언젠가는 LLM이나 이 글 도움 없이 해결하고 싶습니다.
    • @PatKerr — 흥미로운 문제네요. 그런 부작용이 계속 생기는 이유가 바로 떠오르지는 않습니다. 해결을 바랍니다.
  • @NewsaHackO — 이런 시뮬레이션을 만들 재능이 있다면 왜 재현 작업은 직접 코딩하지 않았는지 궁금합니다.
    • @GaryBluto — 이미 만든 것을 현대화하기가 더 쉬워졌는데 굳이 더 많은 일을 할 이유가 있나요? 왜 손수 코딩의 선봉에 서야 하나요?

원문: Pat Kerr / 번역·요약: Trawling