‘Donkey Kong JS’ 제작기: 레트로 플랫폼 게임의 난제와 현대 웹 개발의 통찰
1981년, 아케이드 게임의 역사를 영원히 바꿔놓은 전설이 탄생했습니다. 돈키콩은 ‘점프맨’(현재 전 세계적으로 사랑받는 마리오)을 세상에 소개했을 뿐만 아니라, 스토리 기반 플랫폼 게임이라는 개념 자체를 개척했습니다. 돈키콩 이전에는 여러 독특한 스테이지를 거치며 뚜렷한 악당에게 잡힌 인물을 구출하는 명확한 주인공이 등장하는 게임이 거의 없었습니다.
처음 코드 편집기를 열어 자바스크립트와 HTML5 캔버스 API를 사용해 이 걸작을 재현하려 했을 때, 저는 진심으로 이것이 주말에 금방 끝낼 수 있는 프로젝트가 될 것이라고 생각했습니다. 하지만 제 생각은 완전히 틀렸습니다. 유니티(Unity)나 고도(Godot) 같은 현대적인 게임 엔진에 의존하지 않고 1981년 아케이드 게임의 느낌을 재현하는 작업은 수직 레벨 디자인, 복잡한 사다리 시스템, 물리 기반 장애물 메커니즘에 대한 몇 주에 걸친 매혹적인 심층 연구로 이어졌습니다. 이 글에서는 아케이드의 황금기를 정의했던 상징적인 경사진 거더, 달라붙는 사다리, 통을 피하는 액션 등을 구현하는 데 숨겨진 제 개인적인 여정과 코딩 비결을 공유하고자 합니다.
얼마나 높이 올라갈 수 있을까요?
돈키콩 라이브 실행하기
1. 경사면 물리: 경사진 거더 위에서의 캐릭터 제어
기본적인 플랫포머 게임을 만들어 본 적이 있다면, 평평한 표면은 쉽다는 것을 아실 겁니다. 단순히 player.y + player.height >= floor.y. 하지만 돈키콩은 그 경사진 거더로 유명합니다. 겉보기엔 단순해 보이는 이 디자인 선택은 기존의 충돌 감지 방식을 완전히 무력화시켜 버립니다.
초기 테스트 단계에서 제가 만든 마리오 캐릭터는 경사면을 달릴 때 끊임없이 “떨리거나” 바닥 중간에 끼어 버리는 현상이 발생했습니다. 이를 해결하기 위해 저는 고등학교 대수학으로 돌아가 선형 보간법(LERP)과 기본적인 경사 방정식을 구현해야 했습니다.
- 좌표 매핑: 바닥이 대각선이기 때문에, 캐릭터의 정확한 Y 높이는 수평 X 위치를 기반으로 실시간으로 계산되어야 합니다. 각 거더마다 기울기(
m)와 y-절편(b)를 계산하고, 고전적인y = mx + b공식을 적용해 플레이어의 발이 정확히 어디에 위치해야 하는지 구했습니다. - “공중 부양” 방지: 마리오가 경사면을 내려갈 때, 수평 속도가 중력을 앞지르는 경우가 잦아 잠시 공중에 뜬 상태가 되곤 했습니다. 물리 루프를 조정하느라 이틀 밤을 새웠습니다. 해결책은 “접지(Grounded)” 상태 로직을 강화하는 것이었습니다. 플레이어가 바닥에서 몇 픽셀 이내의 거리에서 내리막을 이동 중이라면, 코드가 플레이어를 계산된 경사선 위로 강제로 끌어당기도록 했습니다.
2. 사다리 시스템: 유한 상태 기계(FSM) 관리
사다리는 표준 중력을 무시하는 수직 이동 차원을 도입합니다. 이를 위해 견고한 유한 상태 기계(FSM)를 구축해야 했습니다. 플레이어는 반드시 다음 상태 중 하나에 있어야 합니다: WALKING, JUMPING, CLIMBING_IDLE, 또는 CLIMBING_MOVE. 이 상태들이 혼동될 때 게임 진행을 방해하는 버그가 발생합니다.
💡 개발자 인사이트: “중앙 정렬(Snap-to-Center)” 로직
초기 테스트에서 사다리 오르기 동작은 매우 어색하게 느껴졌습니다. 친구들은 사다리가 완벽하게 정렬되어 있지 않으면 잡을 수 없다고 불평했습니다. 저는 원작 아케이드 게임에 ‘중앙 정렬(Snap-to-Center)’이라는 숨겨진 메커니즘이 있다는 것을 깨달았습니다. 사다리의 히트박스 근처에서 ‘위’나 ‘아래’ 키를 누르는 순간, 캐릭터의 X좌표가 즉시 사다리의 정확한 중심을 향해 부드럽게 조정되도록 코드를 수정했습니다. 사소한 코드 변경이었지만, 게임플레이를 답답한 느낌에서 만족스럽고 깔끔한 느낌으로 바꿔놓았습니다.
3. 통 AI: 확률과 물리학의 결합
동키콩이 던지는 통들은 게임 속 진정한 ‘혼돈의 주역’입니다. 처음에는 단순히 경사면을 굴러 내려가도록 프로그래밍했는데, 너무 지루했습니다. 현실감을 살리기 위해, 예측 불가능한 AI를 구현하기 위해 리지드 바디 물리학과 난수 생성(RNG)을 결합해야 했습니다.
- 중력에 의한 구르기: 통은 플레이어와 동일한 경사면 물리 법칙을 따르지만, 수평 속도에 연동된 회전 속도 성분을 추가했습니다. 이를 통해 통의 회전 애니메이션이 이동 속도와 완벽하게 일치하도록 했습니다.
- 사다리 판단 로직: 이 부분이 코딩하면서 가장 재미있었습니다. 통이 사다리 꼭대기를 지날 때마다 AI는 "주사위를 굴립니다." 현재 스테이지의 난이도 수준에 따라, 통은 사다리를 무시할 확률이나 갑자기 아래로 떨어져 플레이어를 놀라게 할 확률을 가집니다. 이 RNG가 바로 돈키콩에 엄청난 재플레이 가치를 부여하는 요소입니다.
- 오브젝트 풀링을 통한 성능 최적화: 자바스크립트의 가비지 컬렉션은 미세한 끊김 현상을 유발할 수 있습니다. 통이 화면 밖으로 굴러나가면 이를 파괴하고 새로 생성하는 과정에서 프레임 드롭이 발생했습니다. 저는 오브젝트 풀을 구현하여 이 문제를 해결했습니다. 화면 밖으로 나간 통들은 단순히 비활성화되어 “예비 배열”로 이동되며, 돈키콩이 다음 통을 던질 때 재활용될 준비가 됩니다. 부드러운 60 FPS 달성!
4. 스프라이트 시트와 레트로 미학
1981년의 정통한 분위기를 살리기 위해서는 벡터 그래픽만으로는 부족했습니다. 저는 저해상도 픽셀 아트 스프라이트 시트를 사용했습니다. Canvas API의 drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) 메서드를 사용하는 것은 좌표 매핑에 있어 훌륭한 연습이 되었습니다.
저는 프레임 좌표 배열을 매핑하여 달리기, 등반, 그리고 상징적인 “회전하며 죽는” 시퀀스를 위한 유연한 애니메이션을 만들었습니다.
프론트엔드 개발자를 위한 팁:
최신 브라우저는 이미지를 확대할 때 앤티앨리어싱을 적용하여 픽셀 아트가 흐릿하고 번져 보이게 만듭니다. 고해상도(레티나) 모니터에서 이를 방지하려면 항상image-rendering: pixelated;를 적용하세요. 이렇게 하면 향수를 자극하는 레트로 감성에 필수적인 선명하고 각진 모서리를 유지할 수 있습니다.
5. 히트박스 정밀도: “뛰어넘기” 점수 시스템
돈키콩에서 통은 단순히 피해야 할 장애물이 아니라 기회이기도 합니다. 통 위로 점프하면 점수가 주어지므로, 이를 구현하기 위해 이중 히트박스 시스템을 설계해야 했습니다. 단일 충돌 박스만으로는 충분하지 않았습니다.
- 데스 박스: 캐릭터의 중심을 기준으로 한, 좁고 용서 없는 직사각형입니다. 통의 픽셀이 이 박스와 겹치면 게임이 중단되고 목숨을 하나 잃게 됩니다.
- 점수 박스: 캐릭터 바로 아래에 보이지 않는 수직 감지 구역을 만들었습니다. 플레이어가 안전하게
JUMPING상태에서 발밑의 이 특정 구역을 통행하는 배럴이 지나가면, “스코어 이벤트” 리스너가 트리거되어 공중에 “100”이라는 텍스트 애니메이션이 생성됩니다. 이 타이밍을 공정하게 느껴지도록 맞추는 데는 수십 번의 반복 작업이 필요했습니다.
6. 숨은 공로자: Web Audio API
소리가 없는 레트로 게임은 경험의 절반에 불과합니다. 오리지널 돈키콩은 독특하고 경쾌한 사운드스케이프를 자랑합니다. HTML5 웹 오디오 API를 통합하는 것이 마지막 단계였습니다. 상징적인 “뿅” 소리를 점프 상태에, 묵직한 “쩍” 소리를 망치 내리치기에 연결하자 프로젝트의 완성도가 단숨에 높아졌습니다. 오디오 중첩을 관리하는 것—플레이어가 움직임을 멈출 때 걷는 소리가 정확히 멈추도록 하는 것—은 상태 관리 측면에서 의외로 복잡한 과제였습니다.
결론: 완벽한 개발자 샌드박스
돌이켜보면, 순수 자바스크립트로 돈키콩 클론을 제작한 것은 제 개발 경력 중 최고의 교육적 경험 중 하나였습니다. 이 과정은 현대 게임 엔진의 마법을 걷어내고, 2D 충돌 감지, 메모리 관리, 상태 로직을 처음부터 마스터하도록 강요합니다.
이 과정은 플레이어에게 정밀함을 요구하지만, 더 중요한 것은 프로그래머에게 정교한 논리를 요구한다는 점입니다. 사다리 스냅 조정, 통나무 난수 생성(RNG) 미세 조정, requestAnimationFrame 루프 최적화 등 어떤 문제에 부딪히든, 이 “정상을 향한 등반”은 모든 웹 개발자가 적어도 한 번은 경험해야 할 기술적 여정입니다. 가상 망치를 챙기고, 통에 조심하며, 아가씨를 구해 보세요!
태그: #DonkeyKong #JavaScript #플랫포머개발 #레트로게임 #CanvasAPI #게임개발 #웹게임 #인디개발 #코딩튜토리얼 #웹오디오