4-6-07. 슈퍼 마리오 브라더스 스타일의 플랫포머 게임 즐기기 (Canvas API 쇼케이스)

ADVERTISEMENT

나만의 슈퍼 마리오 브라더스 만들기: Canvas API와 게임 물리학 마스터하기

“달리고 점프하기”라는 메커니즘은 단순한 버튼 조작 그 이상입니다. 이는 게임 산업의 심장박동과도 같습니다. 1985년 이래로 횡스크롤 플랫포머 게임은 레벨 디자인과 캐릭터 물리 엔진의 황금 기준을 제시해 왔습니다. 오늘, 우리는 그 레트로의 마법을 현대적인 브라우저로 가져옵니다. HTML5 캔버스 API를 사용하여, 저는 슈퍼 마리오 브라더스를 걸작으로 만든 중력, 관성, 타일 매핑 시스템을 재현했습니다. 이것은 단순한 복제판이 아닙니다. 자바스크립트가 실시간 물리 엔진과 스프라이트 애니메이션을 어떻게 처리하는지에 대한 심층적인 기술 탐구입니다.

월드 1-1에 도전할 준비가 되셨나요?

코드를 살펴보기 전에 실시간 물리 엔진을 직접 체험해 보세요.


1. 중력 및 운동학: 점프에 “무게감”을 더하기

훌륭한 플랫포머 게임의 비결은 개발자들이 “게임 필(Game Feel)”이라고 부르는 것에 있습니다. 마리오 스타일의 게임에서 플레이어는 마치 공중에 떠 있는 좌표처럼 느껴져서는 안 되며, 무게감이 있어야 합니다. 이를 구현하기 위해 저는 매 프레임마다 속도와 가속도를 계산하는 물리 루프를 구현했습니다.

  • 중력 상수: 이는 매 프레임마다 수직 속도($dy$)에 더해지는 작은 값입니다(예: 0.8)로, 매 프레임 수직 속도($dy$)에 더해집니다. 이것이 없다면, 주인공은 점프 후 단순히 우주로 떠내려가 버릴 것입니다.
  • 점프 임펄스: ‘위’ 키가 눌리는 순간, $dy$를 음수 값(예: -15)로 설정하여 중력을 거슬러 캐릭터를 위로 발사합니다.
  • 마찰 및 관성: 캐릭터가 로봇처럼 느껴질 정도로 즉시 멈추는 것을 방지하기 위해, 수평 속도($dx$)에 마찰 계수(예: 0.9)를 적용했습니다. 이를 통해 방향을 갑자기 바꿀 때 나타나는 그 상징적인 “미끄러짐” 효과를 구현할 수 있습니다.

2. 효율적인 레벨 디자인: 타일 기반 렌더링

거대한 세계를 픽셀 단위로 렌더링하는 것은 메모리 측면에서 악몽과도 같습니다. 대신 타일 맵 시스템을 사용합니다. 레벨은 정수형 2차원 배열로 저장되며, 각 숫자는 특정 텍스처(벽돌, 파이프, 코인 블록)에 대응합니다.

// 0: Sky, 1: Brick, 2: Ground, 3: Question Block
const levelData = [
    [0, 0, 0, 0, 0, 0, 0],
    [0, 3, 1, 3, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0],
    [2, 2, 2, 2, 2, 2, 2]
];

Canvas API의 drawImage()를 사용하여 이 배열을 순회합니다. 하지만 저는 컬링 로직을 추가했습니다. 즉, 엔진은 화면 너비 내에 현재 보이는 타일만 렌더링합니다. 이를 통해 저사양 모바일 기기에서도 매끄러운 60FPS를 보장합니다.

3. 충돌 감지: “벽 클리핑” 버그 해결

충돌 처리는 2D 개발에서 가장 까다로운 부분입니다. 단순히 벽에 부딪혔는지 여부를 파악하는 것뿐만 아니라, 어떻게 반응해야 하는지도 알아야 합니다.

제 경험에서 얻은 전문가 팁: 항상 수직 충돌을 먼저 처리하고, 그 다음 수평 충돌을 처리하세요. 이렇게 하면 캐릭터가 타일의 모서리에 끼는 것을 방지할 수 있습니다.

  • 수직 스냅: 플레이어의 발이 타일에 닿으면, Y 좌표를 타일 상단으로 “스냅”시키고 $dy$를 0으로 재설정합니다.
  • 머리 부딪힘: 아래에서 블록에 부딪히면, 즉시 상향 속도를 반전시켜 반동을 시뮬레이션하고, 동전 획득이나 파괴 이벤트를 트리거합니다.

4. 스프라이트 애니메이션: 영웅에 생명을 불어넣기

화면을 가로지르는 정지된 이미지는 게임이 아니라 슬라이드쇼일 뿐입니다. 스프라이트 시트를 사용하여 유연한 움직임을 구현합니다. 타이머에 따라 단일 이미지의 서로 다른 소스 좌표를 순환시키며 걷는 듯한 착각을 만들어냅니다.

유휴 상태:
속도가 0일 때 표시되는 단일 프레임입니다.
달리기 사이클:
수평 속도에 따라 3~4개의 프레임을 빠르게 순환합니다.
공중:
지면 충돌이 감지될 때까지 트리거되는 전용 “점프” 프레임.

5. “월드 팔로우” 카메라 시스템

캔버스 자체에는 “카메라” 객체가 없기 때문에, 시각적 착시를 이용해야 합니다. 우리는 ctx.translate(-cameraX, 0). 플레이어가 앞으로 이동하면 전체 좌표계를 반대 방향으로 이동시킵니다. 이렇게 하면 세상이 지나가는 동안 캐릭터가 중앙에 고정되어 몰입감 있는 탐험의 느낌을 줍니다.

결론: 고전적인 토대 위에 미래를 구축하기

자바스크립트와 캔버스 API를 활용한 플랫포머 개발은 논리와 창의력을 발휘할 수 있는 최고의 연습입니다. 점프 궤적부터 머리 밟기의 정밀도에 이르기까지, 코드의 한 줄 한 줄이 플레이어의 즐거움으로 직접 이어집니다. 논리력을 키우고 싶은 웹 개발자라면 이보다 더 좋은 프로젝트는 없을 것입니다.

지금 바로 코드 편집기를 열고, 로컬 서버를 시작한 뒤, 나만의 전설적인 모험을 코딩해 보세요!

태그:
#GameDev #JavaScript #HTML5Canvas #RetroGaming #SuperMario #PhysicsEngine #CodingTutorial #WebDevelopment

pomiai — 듣고, 사용하고, 즐기고에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기