
무슨 이야기인가요?
2D 게임을 만들다 보면 한 번쯤 자동차를 넣고 싶어지죠. 위에서 내려다보는 탑뷰 레이싱이나 초창기 GTA 같은 화면을 떠올리면 돼요. 그런데 막상 구현해 보면 차가 얼음 위 하키 퍽처럼 미끄러지거나, 반대로 레일 위 장난감처럼 뻣뻣하게 꺾여요. 어느 쪽이든 운전하는 맛이 없죠.
이번에 소개할 “2D Vehicles”는 바로 이 주제, 그러니까 2D 게임 속 탈것을 그럴듯하게 움직이게 만드는 방법을 다룬 글이에요. 원문도 꼭 읽어보시길 추천해요. 여기서는 이 분야를 처음 접하는 분도 따라올 수 있도록 핵심 개념을 단계별로 풀어볼게요.
1단계: 가장 순진한 구현과 그 함정
처음엔 보통 이렇게 만들어요. 차에 각도와 속력을 두고, 매 프레임 바라보는 방향으로 속력만큼 이동시키는 거죠. 그런데 이러면 핸들을 꺾는 순간 진행 방향이 바로 바뀌어요. 관성이 하나도 없으니 자동차가 아니라 레일 위 모형 기차 같은 느낌이 나요.
그래서 다음 단계로 ‘진짜 물리’를 넣어요. 속도를 벡터로 들고, 엔진 힘은 차가 바라보는 방향으로만 더하는 거예요. 이제 관성은 생겼는데 새로운 문제가 생겨요. 옆으로 미끄러지는 걸 막아주는 게 아무것도 없어서, 차가 호버크래프트처럼 둥둥 떠다니거든요.
2단계: 타이어가 하는 일을 흉내 내기
진짜 타이어는 앞뒤로는 잘 구르고, 옆으로는 끈질기게 버텨요. 이 성질만 흉내 내도 느낌이 확 달라져요. 방법은 속도를 차 기준의 ‘앞 방향 성분’과 ‘옆 방향 성분’으로 쪼갠 다음, 옆 방향 성분만 강하게 줄이는 거예요.
forward = (cos(angle), sin(angle))
right = (-sin(angle), cos(angle))
forwardSpeed = dot(velocity, forward)
lateralSpeed = dot(velocity, right)
lateralSpeed *= sideSlip // 0이면 완전 접지, 1에 가까울수록 빙판
velocity = forward forwardSpeed + right lateralSpeed
여기서 dot은 벡터 내적인데요, 이게 뭐냐면 속도라는 화살표에 손전등을 비춰서 차의 앞쪽 축과 옆쪽 축에 생기는 그림자 길이를 재는 거예요. 그림자로 쪼갠 뒤 옆쪽 그림자만 줄였다가 다시 합치는 거죠. sideSlip 값을 0보다 살짝 크게 두면 고속 코너에서 차 뒤쪽이 살짝 밀리는 아케이드식 드리프트가 덤으로 생겨요.
한 가지 함정이 있어요. 위 코드처럼 매 프레임 곱하기를 하면 60fps와 144fps에서 미끄러지는 정도가 달라져요. 물리는 고정된 시간 간격(fixed timestep)으로 돌리거나, 감쇠 계수를 지나간 시간에 맞게 보정해 주는 게 좋아요.
3단계: 앞바퀴와 뒷바퀴를 따로, 자전거 모델
더 사실적으로 가고 싶다면 자전거 모델을 써요. 자동차의 왼쪽·오른쪽 바퀴를 하나로 합쳐서, 앞바퀴 하나와 뒷바퀴 하나만 있는 자전거처럼 단순하게 보는 거예요. 2D에서는 이것만으로도 충분히 그럴듯해요.
각 바퀴는 슬립 앵글이라는 값을 계산해요. 바퀴가 바라보는 방향과 바퀴가 실제로 움직이는 방향 사이의 각도예요. 이 각이 작을 때는 각도에 비례해서 옆으로 버티는 힘이 커지다가, 한계를 넘으면 힘이 더 늘지 않고 타이어가 미끄러지기 시작해요. 실제 레이싱 시뮬레이터는 ‘파세이카 매직 포뮬러’ 같은 복잡한 타이어 공식을 쓰지만, 게임에서는 “비례하다가 최댓값에서 자르기” 정도로도 충분한 경우가 많아요.
이 구조가 재밌는 건 운전하는 손맛이 저절로 생긴다는 점이에요. 앞바퀴가 먼저 한계에 닿으면 핸들을 꺾어도 차가 바깥으로 밀려나는 언더스티어가 생겨요. 반대로 뒷바퀴가 먼저 한계에 닿으면 꽁무니가 돌아가는 오버스티어가 생기고요. 여기에 브레이크를 밟을 때 무게가 앞으로 쏠려서 앞바퀴 접지력은 늘고 뒷바퀴 접지력은 주는 하중 이동까지 넣어 보세요. 그러면 브레이크를 살짝 밟으면서 코너에 들어가 뒤를 흘리는 드리프트를 플레이어가 직접 만들어낼 수 있게 돼요.
업계 맥락: 정확한 물리 vs 재미있는 물리
이 분야에는 오랫동안 회자되는 고전 자료들이 있어요. Marco Monster의 “Car Physics for Games”는 게임 개발자들이 차량 물리를 공부할 때 단골로 언급되는 문서고, Box2D로 탑뷰 자동차를 만드는 iforce2d의 튜토리얼도 유명해요. 유니티나 고도 엔진은 3D 쪽에는 차량 전용 컴포넌트를 제공하지만, 2D에서는 대부분 직접 구현해야 해서 이런 자료가 더 소중해요.
중요한 건 정확한 물리가 곧 재미있는 물리는 아니라는 것이에요. 카트라이더를 떠올려 보세요. 실제 자동차라면 말도 안 되는 드리프트지만, 그 과장된 손맛이 게임의 정체성이 됐잖아요. 많은 게임이 저속에서 접지력을 높여주거나 조향을 보조해 주는 식으로 물리를 일부러 ‘속여요’. 시뮬레이션과 아케이드 사이 어디쯤에 설지 정하는 게 설계의 출발점이에요.
한국 개발자에게 주는 시사점
인디 게임이나 게임잼을 준비 중이라면 2단계의 ‘옆 방향 속도 줄이기’만 넣어도 체감이 확 달라지니 꼭 해보세요. 프론트엔드 개발자라면 캔버스 하나로 주말에 실험해 볼 만한 주제이기도 해요. 벡터 내적과 좌표계 변환을 손으로 익히기에 이만한 예제가 없거든요.
게임 밖에서도 쓸모가 있어요. 자율주행이나 물류 로봇의 경로 계획에서도 운동학적 자전거 모델이 기본 모델로 널리 쓰이거든요. 게임 차량 물리를 이해해 두면 그쪽 논문이나 오픈소스를 읽을 때 진입 장벽이 꽤 낮아져요.
마무리
한 줄 정리: 그럴듯한 2D 탈것의 비밀은 앞으로는 잘 구르고 옆으로는 버티는 타이어를 흉내 내는 데 있어요.
여러분이 해본 게임 중에 운전 손맛이 가장 좋았던 건 뭐였나요? 직접 만든다면 리얼함과 재미 중 어느 쪽에 더 무게를 두시겠어요?
🔗 출처: Hacker News