시작

html5 수박 게임 만들기

작성일 2026.07.02 수정일 2026.07.02 조회 27

데모

기본 정보


개요

MVP 수박 합치기 게임은 HTML Canvas를 이용하여 만든 웹 기반 과일 합치기 게임이다.

플레이어는 화면 상단에서 과일을 떨어뜨리고, 같은 과일끼리 충돌하면 더 큰 과일로 합쳐진다. 과일이 계속 쌓이다가 위험선 위로 일정 시간 올라가면 게임 오버가 된다.

이 프로젝트는 복잡한 게임 엔진 없이 HTML, CSS, JavaScript만으로 MVP 수준의 게임을 구현하는 예제로 활용할 수 있다.


MVP 목표

MVP(Minimum Viable Product)는 최소 기능 제품을 의미한다.

이 게임의 MVP 목표는 다음과 같다.

  • 브라우저에서 바로 실행 가능한 게임
  • Canvas 기반 렌더링
  • 마우스와 터치 입력 지원
  • 같은 과일 충돌 시 합치기
  • 점수 시스템 구현
  • 최고 점수 저장
  • 게임 오버 처리
  • 재시작 기능 제공
  • 모바일 화면 대응

프로젝트 구조

수박게임/

├── 수박.html
├── 수박.css
└── 수박.js

각 파일의 역할은 다음과 같다.

파일역할
수박.html게임 화면 구조, Canvas, 버튼, 오버레이 구성
수박.css전체 UI 디자인, 반응형 레이아웃, 버튼 스타일
수박.js게임 로직, 물리 처리, 충돌 처리, 점수 저장

전체 구조

사용자

↓

마우스 / 터치 입력

↓

JavaScript 게임 로직

↓

Canvas 렌더링

↓

과일 충돌 / 합치기

↓

점수 계산

↓

게임 오버 또는 재시작

HTML 구성

HTML은 게임의 기본 화면 구조를 담당한다.

주요 구성 요소는 다음과 같다.

  • 점수 표시 영역
  • 다음 과일 표시 Canvas
  • 최고 점수 표시 영역
  • 메인 게임 Canvas
  • 도움말 문구
  • 시작 오버레이
  • 게임 오버 오버레이
  • 재시작 버튼

HTML 핵심 구조 예시

<main class="game-shell">
    <div class="top-ui">
        <div class="score-box">
            <span class="score-label">점수</span>
            <span id="scoreText" class="score-value">0</span>
        </div>

        <div class="next-box">
            <canvas id="nextCanvas" width="74" height="74"></canvas>
        </div>

        <div class="score-box right">
            <span class="score-label">최고점수</span>
            <span id="bestText" class="score-value">0</span>
        </div>
    </div>

    <canvas id="gameCanvas" width="420" height="640"></canvas>
</main>

CSS 구성

CSS는 게임의 시각적 분위기와 모바일 대응을 담당한다.

이 프로젝트의 UI는 밝은 노란색 계열 배경과 둥근 카드 형태를 사용하여 캐주얼 게임 느낌을 만든다.

주요 스타일 요소는 다음과 같다.

  • 중앙 정렬된 게임 화면
  • 점수 카드 UI
  • 다음 과일 미리보기 박스
  • 둥근 Canvas 영역
  • 시작 및 게임오버 오버레이
  • 모바일 반응형 처리

CSS 핵심 예시

.game-shell {
  width: min(100%, 460px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
}

#gameCanvas {
  width: min(100%, 430px);
  aspect-ratio: 420 / 640;
  border-radius: 26px;
  background: #fff9e9;
  touch-action: none;
  cursor: pointer;
}

JavaScript 구성

JavaScript는 실제 게임 로직을 담당한다.

주요 역할은 다음과 같다.

  • Canvas 초기화
  • 과일 데이터 관리
  • 과일 생성 및 낙하
  • 물리 계산
  • 벽, 바닥 충돌 처리
  • 과일끼리 충돌 처리
  • 같은 과일 합치기
  • 점수 계산
  • 최고 점수 저장
  • 게임 오버 판정
  • 파티클 효과
  • 마우스 및 터치 입력 처리

게임 상태 관리

게임은 상태값을 기준으로 동작한다.

menu

↓

playing

↓

over
상태설명
menu시작 화면
playing게임 진행 중
over게임 오버 상태

과일 데이터 구조

과일은 배열 데이터로 관리한다.

각 과일은 다음 정보를 가진다.

  • 이름
  • 반지름
  • 색상
  • 어두운 색상
  • 점수
  • 이모지
const FRUITS = [
  {
    name: "체리",
    radius: 16,
    color: "#ff4d6d",
    dark: "#d62b4e",
    score: 1,
    emoji: "🍒",
  },
  {
    name: "수박",
    radius: 88,
    color: "#38b000",
    dark: "#1f7a1f",
    score: 50,
    emoji: "🍉",
  },
];

과일 합치기 규칙

게임의 핵심 규칙은 단순하다.

같은 과일

+

같은 과일

↓

다음 단계 과일

예시

체리 + 체리 = 딸기

딸기 + 딸기 = 포도

포도 + 포도 = 귤

...

멜론 + 멜론 = 수박

물리 처리 구조

게임은 별도의 물리 엔진 없이 JavaScript로 간단한 원형 물리 처리를 구현한다.

중력 적용

↓

위치 갱신

↓

벽 충돌 검사

↓

바닥 충돌 검사

↓

과일끼리 충돌 검사

↓

합치기 처리

충돌 처리 핵심 개념

두 과일 사이의 거리를 계산하여 충돌 여부를 판단한다.

두 과일의 거리 < 두 과일 반지름의 합

↓

충돌 상태

공식은 다음과 같다.

distance = sqrt(dx * dx + dy * dy)

minDistance = fruitA.radius + fruitB.radius

if distance < minDistance:
    collision = true

합치기 처리 흐름

과일 A 확인

↓

과일 B 확인

↓

같은 레벨인지 검사

↓

충분히 가까운지 검사

↓

접촉 시간이 쌓였는지 검사

↓

두 과일 제거

↓

다음 단계 과일 생성

↓

점수 증가

↓

파티클 효과 생성

게임오버 처리

게임 오버는 과일이 위험선 위로 올라갔을 때 즉시 발생하지 않고, 일정 시간 유지되면 발생한다.

이 방식은 과일이 잠깐 튀어 오르거나 생성되는 순간에 게임이 끝나는 문제를 줄여준다.

과일이 위험선 위에 있음

+

충분히 오래된 과일임

+

빠르게 떨어지는 중이 아님

+

일정 시간 유지됨

↓

게임 오버

점수 저장

최고 점수와 최근 기록은 브라우저의 LocalStorage에 저장한다.

localStorage.setItem("suika_best_score", String(best));

저장되는 정보 예시는 다음과 같다.

  • 현재 점수
  • 최고 점수
  • 최고 과일 이름
  • 최고 과일 이모지
  • 생성 날짜
  • 새 최고 기록 여부

입력 처리

입력 방식은 3가지를 지원한다.

입력 방식기능
마우스 이동과일 위치 이동
클릭과일 떨어뜨리기
터치 이동모바일 위치 이동
터치 시작모바일 과일 떨어뜨리기
키보드 방향키좌우 이동
Space / Enter과일 떨어뜨리기

게임 루프

게임은 requestAnimationFrame을 사용하여 매 프레임 업데이트된다.

function loop(now) {
  const dt = Math.min(0.033, (now - lastTime) / 1000);
  lastTime = now;

  if (gameState === "playing") {
    updatePhysics(dt);
  }

  draw();
  requestAnimationFrame(loop);
}

렌더링 구조

배경 그리기

↓

위험선 그리기

↓

낙하 가이드 그리기

↓

과일 그리기

↓

파티클 그리기

↓

다음 과일 미리보기 그리기

MVP의 장점

  • 별도 프레임워크 없이 실행 가능
  • HTML, CSS, JavaScript만으로 구성
  • Canvas 기반이라 배포가 간단함
  • 모바일에서도 플레이 가능
  • 게임 로직이 한 파일에 모여 있어 학습하기 좋음
  • LocalStorage를 활용해 기록 저장 가능
  • 간단한 물리 처리와 충돌 처리 학습 가능

MVP의 한계

  • 실제 물리 엔진 수준의 정밀도는 아님
  • 복잡한 충돌 상황에서는 떨림이 발생할 수 있음
  • 과일 이미지 대신 Canvas 도형으로 표현됨
  • 사운드 효과가 없음
  • 난이도 조절 옵션이 없음
  • 랭킹 서버가 없음
  • 멀티플레이 기능은 없음

개선 방향

다음 기능을 추가하면 완성도를 더 높일 수 있다.

  • 효과음 추가
  • 배경 음악 추가
  • 실제 과일 이미지 사용
  • 난이도 선택
  • 스킨 변경
  • 일시정지 기능
  • 서버 랭킹 기능
  • PWA 설치 기능
  • 모바일 진동 피드백
  • 공유하기 기능
  • 광고 영역 추가
  • 튜토리얼 화면 추가

콘텐츠 제작 포인트

이 프로젝트는 개발 콘텐츠로 만들기 좋다.

추천 콘텐츠 방향은 다음과 같다.

1. HTML Canvas 게임 만들기

Canvas를 이용해 게임 화면을 그리는 과정을 설명한다.

2. JavaScript 물리 처리

중력, 충돌, 반발, 마찰을 직접 구현하는 과정을 설명한다.

3. 수박게임 MVP 만들기

처음부터 완성형 게임이 아니라, 최소 기능부터 구현하는 과정을 보여준다.

4. 모바일 대응 웹 게임 만들기

터치 입력과 반응형 UI를 다룬다.

5. LocalStorage 점수 저장

서버 없이 브라우저에 최고 점수를 저장하는 방식을 설명한다.


개발 순서 추천

1. HTML 화면 구조 작성

↓

2. CSS로 게임 UI 구성

↓

3. Canvas 초기화

↓

4. 과일 데이터 생성

↓

5. 과일 낙하 구현

↓

6. 벽과 바닥 충돌 처리

↓

7. 과일끼리 충돌 처리

↓

8. 같은 과일 합치기

↓

9. 점수 및 최고 기록 저장

↓

10. 게임 오버와 재시작 구현

실무 메모

  • Canvas 게임은 requestAnimationFrame 기반으로 구현하는 것이 좋다.
  • 모바일 대응을 위해 touch-action: none 처리가 필요하다.
  • 고해상도 화면에서는 devicePixelRatio를 고려해야 한다.
  • 충돌 처리는 한 번에 계산하기보다 여러 sub step으로 나누면 안정적이다.
  • 생성 직후 과일이 바로 합쳐지지 않도록 대기 시간이 필요하다.
  • 게임 오버는 즉시 판정보다 일정 시간 유지 판정이 자연스럽다.
  • 점수 저장은 MVP 단계에서는 LocalStorage로 충분하다.
  • 실제 서비스에서는 서버 랭킹 API를 추가할 수 있다.
  • 과일 데이터는 배열로 관리하면 확장하기 쉽다.
  • 렌더링 코드와 물리 코드는 가능하면 분리하는 것이 좋다.

함께 사용하는 기술


대표 활용 사례

  • 개인 포트폴리오 게임
  • JavaScript 강의 예제
  • Canvas 입문 예제
  • MVP 개발 콘텐츠
  • 모바일 웹 게임
  • 광고형 미니게임
  • 이벤트 페이지 게임
  • PWA 게임 앱

관련 문서


출처

  • 소스코드
  • MDN Web Docs - Canvas API
  • MDN Web Docs - requestAnimationFrame
  • MDN Web Docs - Web Storage API