관리자 인증 확인 중...
B 또는 Space 로 복귀
LUNA CODE LAB · CLASS I Week 11 — 폴리시와 다듬기 초4 · 중3 / 90분
1 / 9 📄 워크시트
WEEK 11 · 2026

게임을 게임답게
폴리시와 다듬기

움직이는 시스템은 완성됐다. 이제 "이게 진짜 게임이네"라고 느끼게 만드는 시간. 코인 드랍·상점·파티클·사운드·모바일 조이스틱까지. 한 주만 더하면 우리도 출시한다.

Duration90 minutes
ToolClaude Code
Output베타 빌드 (사운드+모바일)
Phase서바이버 (4/5)
02 / Learning Goals⏱ 5분

오늘의 학습 목표

1
코인이 떨어지고 빨려온다
적이 죽으면 코인이 톡 떨어지고, 캐릭터가 가까이 가면 자석처럼 흡수된다.
2
일시정지 상점
스페이스바로 게임을 멈추고 코인으로 업그레이드를 사는 진짜 상점 UI.
3
파티클과 효과음
폭발 파티클·획득 효과·Suno BGM. 화면이 살아 움직이고 귀로도 즐겁다.
4
아이폰에서 손가락으로
화면 왼쪽 가상 조이스틱을 만들어서 핸드폰에서도 돌아가게 만든다.
03 / Concept⏱ 10분

폴리시가 게임을 게임으로 만든다

같은 코드라도 소리·파티클·진동이 있으면 완전히 다른 게임이 됩니다. 실제 게임 회사가 6개월 만든 후 마지막 2개월은 전부 폴리시만 합니다 — 그만큼 중요한 단계.

⚙️
로직 (지난 주)
자동 공격·웨이브
레벨업·무기 진화
+
폴리시 (이번 주)
코인·상점
파티클·사운드·모바일
=
🎮
진짜 게임
친구가 30분
붙잡고 노는 게임
오늘의 비밀: 게임은 "잘 만들어진 시스템"이 아니라 "기분 좋은 피드백"으로 완성됩니다.
04 / Prompt Engineering⏱ 12분

폴리시 프롬프트 — 감각으로 설명하기

❌ 나쁜 예
"파티클 좀 화려하게 해줘"
왜 안 좋나? "화려하게"는 사람마다 다름. AI도 헷갈림. 결과: 별로 안 화려해 보임 → 또 다시 설명해야 함.
✓ 좋은 예
"적이 죽으면
그 자리에서 주황색 파티클 12개
360도로 퍼지면서 0.5초간 점점 작아지게
사라질 때 알파값도 함께 줄어들게"
왜 좋나? 개수·색·방향·시간·페이드아웃까지 명확. 결과: 정확히 그렇게 나옴. 한 번에.
💡 폴리시 5요소: 개수·색·방향·시간·끝나는 방식(페이드/스케일/이동) 다섯 개를 항상 말하기.
05 / Live Build · Step 1⏱ 6분

Step 1 — 코인 드랍과 자동 흡수

적이 죽으면 그 자리에 코인 한 개. 캐릭터가 일정 거리 안에 들어오면 자석처럼 빨려옵니다.

1
Claude에게 보낼 요청
// 코인 드랍 + 자동 흡수 "적이 죽었을 때 coins 배열에 {x, y, value:1} 객체를 추가해줘. 코인은 노란색 작은 원 (반지름 6px)으로 그려. 플레이어와 코인 거리가 100px 안이면 코인이 플레이어 쪽으로 속도 4로 빨려와. 거리가 16px 미만이면 획득(코인 +1)."
핵심 자석 로직 (벡터 정규화)
const dx = player.x - coin.x; const dy = player.y - coin.y; const dist = Math.sqrt(dx*dx + dy*dy); if (dist < 100) { coin.x += (dx / dist) * 4; // 정규화 × 속도 coin.y += (dy / dist) * 4; } if (dist < 16) { player.coins++; coins.splice(i,1); }
🎙
멘토 멘트 "이거 한 줄이 그렇게 중요해요. 코인이 알아서 따라오면 게임이 갑자기 '맛있어'져요. 뱀파이어 서바이버가 5000만 명 팔린 이유 절반이 이거예요."
학생 액션 흡수 반경(100px)·속도(4)를 본인 게임에 맞게 조정 → 옆 친구 게임이랑 비교해서 어느 쪽이 더 재밌는지 토론.
05 / Live Build · Step 2⏱ 7분

Step 2 — 일시정지 상점 UI

스페이스바로 게임을 멈추고 모은 코인으로 업그레이드를 사는 진짜 상점. UI는 캔버스 위에 떠 있는 카드 4장.

2
Claude에게 보낼 요청
"스페이스 키를 누르면 isPaused = true로 바꾸고 화면 위에 반투명 검은 오버레이를 깔아줘. 가운데에 상점 카드 4개를 가로로 정렬: 1) 무기 속도 +10% — 5코인 2) 무기 데미지 +1 — 8코인 3) 이동 속도 +5% — 4코인 4) 체력 회복 (풀피) — 10코인 각 카드 클릭 → 코인 차감 → 효과 적용 → 게임 재개."
🎙
멘토 강조 포인트 "상점이 있으면 코인이 의미가 생겨요. 코인을 모은 보상이 즉시 강해지는 거. '한 판만 더!'를 만드는 핵심 장치예요."
🛒
학생 자유 디자인 본인이 가장 사고 싶은 업그레이드 1개를 추가 (예: "2번 공격", "투명망토 3초", "반사 데미지") → AI에게 요청해서 5번째 카드로 붙이기.
05 / Live Build · Step 3⏱ 6분

Step 3 — 파티클 (폭발·획득)

화면이 살아 움직이는 이유는 파티클. 적 폭발·코인 획득 두 가지에 같은 파티클 시스템을 재활용한다.

3
Claude에게 보낼 요청
"particles 배열을 하나 만들어줘. 적이 죽을 때: 그 자리에 주황 파티클 12개 - 랜덤 방향, 속도 3~6, 수명 30프레임 - 매 프레임 위치 += 속도, 알파 -= 1/30 코인 획득할 때: 플레이어 위치에 노란 파티클 6개 - 위로 솟구치는 방향(-90도 ±30도) - 수명 20프레임, 같은 페이드아웃."
파티클 한 개 짜리 객체
function spawn(x,y,color,count) { for (let i=0; i<count; i++) { const a = Math.random()*Math.PI*2; const s = 3 + Math.random()*3; particles.push({ x, y, vx:Math.cos(a)*s, vy:Math.sin(a)*s, life:30, color }); } }
🎙
핵심 가르침 "하나의 파티클 시스템으로 폭발·획득·레벨업·피격까지 다 만들 수 있어요. 색·개수·방향만 바꾸면 돼요. 게임 회사도 이렇게 해요."
05 / Live Build · Step 4⏱ 6분

Step 4 — 효과음 + Suno BGM

눈은 채웠으니 이제 . 효과음 4종 + Suno로 만든 자작 BGM을 깔면 갑자기 진짜 게임이 됩니다.

4a
효과음 4종 준비 (Freesound.org)
shoot.mp3 / hit.mp3 / coin.mp3 / levelup.mp3 — 짧은(0.3초 이내) 무료 효과음 골라서 sounds 폴더에 저장.
const sfx = { shoot: new Audio('sounds/shoot.mp3'), hit: new Audio('sounds/hit.mp3'), coin: new Audio('sounds/coin.mp3'), up: new Audio('sounds/levelup.mp3') }; // 발사할 때: sfx.shoot.cloneNode().play();
4b
Suno로 BGM 만들기 (suno.com)
프롬프트 예: "chiptune action loop, fast tempo, retro 8-bit, 90 BPM, no vocals, energetic" → 30초 mp3 다운로드 → bgm.mp3로 저장.
const bgm = new Audio('sounds/bgm.mp3'); bgm.loop = true; bgm.volume = 0.3; // 첫 클릭 후 play() — 브라우저 정책 canvas.onclick = () => bgm.play();
🎙
멘토 멘트 "Suno는 진짜 무료고 30초면 BGM 한 곡이 나와요. 본인 게임 분위기에 맞춰서 가사 없이 'chiptune', 'lo-fi', 'epic orchestra' 같은 키워드만 넣어보세요."
05 / Live Build · Step 5⏱ 5분

Step 5 — 모바일 가상 조이스틱

화면 왼쪽에 손가락으로 미는 둥근 조이스틱을 띄우면, 핸드폰에서도 동일하게 돌아갑니다.

5
Claude에게 보낼 요청
"화면 왼쪽 아래에 반투명 흰 원 (반지름 60px)을 띄워줘. 그 원 안에 작은 노란 원 (반지름 28px) — 손가락 위치. touchstart/touchmove로 손가락이 움직이면 노란 원도 따라 움직이게 (단, 큰 원 안에서만). 손가락 위치 - 중심 = player.dx, player.dy로 사용. touchend면 노란 원을 중앙으로 복귀, dx/dy = 0."
조이스틱 핵심 (정규화로 속도 일정 유지)
const mag = Math.sqrt(dx*dx + dy*dy); if (mag > 0) { player.x += (dx / mag) * speed; // 방향만 사용 player.y += (dy / mag) * speed; }
🎙
오늘의 마무리 "이걸 해야 친구한테 '카톡으로 게임 링크' 보내줄 수 있어요. PC에서만 되는 게임은 친구들이 안 해봐요. 모바일이 되면 1주일 동안 친구·가족이 다 해줘요."
📱
학생 액션 본인 핸드폰으로 로컬 서버 접속 → 조이스틱 작동 확인 → 가족에게 카톡으로 링크 공유.
10 / Checkpoint⏱ 5분

베타 빌드 완성 체크

잘 됐다면
  • 코인이 톡 떨어지고 빨려옴 — 자석 흡수
  • 스페이스로 일시정지 → 상점 → 업그레이드 구매
  • 적 폭발에 주황 파티클 12개 360도 퍼짐
  • 효과음 4종(shoot/hit/coin/levelup) + BGM 루프 재생
  • 핸드폰에서 가상 조이스틱으로 캐릭터 조작 가능
⚠️자주 막히는 부분
  • 코인이 안 빨려옴 → 거리 계산 dx/dy 부호 확인
  • 상점이 안 멈춤 → update 함수 안에서 isPaused 체크 누락
  • 효과음이 안 남 → cloneNode() 안 쓰면 동시 발사 안 됨
  • BGM이 안 재생 → 브라우저 자동재생 차단 → 첫 클릭 후 play()
  • 조이스틱이 안 움직임 → touch-action: none CSS 추가
11 / Challenge⏱ 10분

더 해보고 싶다면 도전

💎
희귀 코인(보라, 5점)을 10% 확률로 드랍. 보라 코인 획득 시 큰 파티클 + 다른 효과음.
난이도 ★
🎰
랜덤 상점 — 상점을 열 때마다 4장의 업그레이드 카드가 8종 중 랜덤. 마음에 안 들면 2코인 내고 새로고침.
난이도 ★★
📳
화면 흔들림(Screen Shake) — 보스 타격 시 0.2초 동안 화면이 살짝 흔들리는 카메라 효과 추가.
난이도 ★★★
12 / Student Gallery⏱ 7분

작년 친구들의 베타 빌드

13 / Next Week⏱ 5분

드디어 다음 시간 — 출시 데이

WEEK 12 · FINAL · COMING UP

출시 데이! —
Runway 트레일러와 정식 공개

12주의 마지막 주. Runway로 30초 트레일러 영상을 만들고, 게임 소개 페이지를 띄우고, 놀이터에 정식 게시합니다. 친구·가족·SNS로 공유 — 진짜 게임 출시.

PREPARE · 준비물
  • 이번 주 베타 빌드 노트북에 저장해 와
  • 본인 게임 플레이 영상 30초 녹화 (화면 녹화로)
  • 트레일러 음악 분위기 한 줄 (예: "비장한", "신나는", "코믹")
  • 게임 이름 3개 후보 + 한 줄 소개 (작가 노트)