관리자 인증 확인 중...
B 또는 Space 로 복귀
LUNA CODE LAB · CLASS I Week 9 — 적 무리와 웨이브 시스템 초4 · 중3 / 90분
1 / 9 📄 워크시트
WEEK 09 · 2026

3마리에서
100마리로

시간이 갈수록 더 많이, 더 빠르게. 좀비·박쥐·스켈레톤 100마리가 화면을 가득 채운다. 오늘은 진짜 "무리"를 만들고, 게임 컴퓨터가 안 느려지도록 최적화하는 법까지.

Duration90 minutes
ToolClaude Code
Output웨이브 + 100마리 무리
Phase2D 뱀파이어 서바이벌 (2/5)
02 / Learning Goals⏱ 5분

오늘의 학습 목표

1
다수 적 동시 처리
적 한 마리가 아닌 배열(상자) 안에 100마리. 한 번에 모두 업데이트한다.
2
시간별 난이도 곡선
1분 후엔 적이 많아지고, 3분 후엔 더 빨라진다. 시간을 따라 게임이 어려워진다.
3
적 종류 다양화
좀비(느림+많음)·박쥐(빠름+적음)·스켈레톤(중간+튼튼). 세 종류 다른 특성.
4
HUD: 시간 + 처치 수
화면 위에 경과 시간·처치 수 표시. 자기 기록이 점점 늘어나는 재미.
03 / Concept⏱ 10분

적 배열 = 달걀판 같은 것

지난 주는 적 변수 3개를 따로 만들었다. 오늘은 "적 100마리를 담는 달걀판"을 만든다. 달걀판 한 번 흔들면 모든 달걀이 흔들리듯, 배열 한 번 돌리면 모든 적이 움직인다.

🥚
enemies[ ]
적 100마리
한 상자에
+
웨이브 타이머
시간 흐름에 따라
더 많이 등장
=
🧟
서바이벌 게임
진짜 무리가
몰려온다
"forEach" 한 줄이면 100마리든 1000마리든 한 번에 처리. 이게 배열의 마법이야.
04 / Prompt Engineering⏱ 10분

웨이브 — 시간 곡선 설계

❌ 나쁜 예
"적이 점점 많아지게 해줘"
왜 안 좋나? 얼마나 자주? 몇 마리까지? 어떻게 빨라지나? AI 마음대로 만들면 게임이 너무 쉽거나 너무 어려워짐.
✓ 좋은 예
"처음 0초: 1초마다 1마리 등장,
30초 후: 1초마다 3마리,
60초 후: 0.5초마다 5마리,
최대 100마리까지만 화면에."
왜 좋나? 시간·등장 속도·최대 수 명확. 게임 디자이너가 정한 정확한 난이도 곡선.
💡 웨이브 설계 3요소: 시간 구간 · 등장 주기 · 동시 최대 수. 이 셋이 게임의 페이스를 결정한다.
05 / Live Build · Step 1⏱ 12분

Step 1 — 적 풀(배열) 만들기

지난 주의 3마리 적을 배열(상자) 하나에 넣는다. 그리고 forEach로 한꺼번에 처리.

1
Claude에게 보낼 요청
"지난 주 survivor.html에서 적을 배열로 바꿔줘. - enemies = [] 로 시작 - spawnEnemy() 함수로 적을 만들어 배열에 추가 - 매 프레임마다 enemies.forEach로 모든 적 이동 - 1초마다 1마리 자동 등장 (화면 가장자리에서)"
예상 결과 — 배열 + 자동 스폰
const enemies = []; let spawnTimer = 0; function spawnEnemy(){ // 화면 가장자리 4면 중 랜덤 const side = Math.floor(Math.random()*4); let x, y; if(side===0){ x = Math.random()*800; y = -20; } else if(side===1){ x = 820; y = Math.random()*600; } else if(side===2){ x = Math.random()*800; y = 620; } else { x = -20; y = Math.random()*600; } enemies.push({ x, y, r:14, hp:30, speed:1, color:'#B84A4A' }); } function update(){ spawnTimer--; if(spawnTimer <= 0){ spawnEnemy(); spawnTimer = 60; } // 1초 enemies.forEach(e => { /* 추적 */ }); }
🎙
멘토 멘트 "적을 화면 안에서 만들면 갑자기 튀어나와서 부자연스러워요. 화면 밖 가장자리에서 등장시키면 진짜로 '몰려오는 느낌'이 살아나요."
05 / Live Build · Step 2⏱ 15분

Step 2 — 3종류의 적

모든 적이 똑같으면 지루하다. 좀비·박쥐·스켈레톤 — 셋은 다르게 움직이고 다르게 강하다.

2
Claude에게 보낼 요청
"적 종류를 3가지로 만들어줘. - 좀비(녹색, hp 30, speed 0.8, 가장 흔함) - 박쥐(보라, hp 15, speed 2.5, 가끔) - 스켈레톤(흰색, hp 80, speed 1.2, 드묾) spawnEnemy()에서 확률로 종류 결정: 좀비 70%, 박쥐 20%, 스켈레톤 10%."
예상 결과 — 적 타입 사전
const ENEMY_TYPES = { zombie: { r:14, hp:30, speed:0.8, color:'#4A7A68' }, bat: { r:10, hp:15, speed:2.5, color:'#7B5BA8' }, skeleton: { r:16, hp:80, speed:1.2, color:'#E8E3D6' } }; function pickType(){ const r = Math.random(); if(r < 0.7) return 'zombie'; if(r < 0.9) return 'bat'; return 'skeleton'; } function spawnEnemy(){ const type = pickType(); const tpl = ENEMY_TYPES[type]; enemies.push({ x, y, type, ...tpl }); }
🎙
핵심 개념 — 객체 펼치기 "...tpl 이게 핵심이에요. ENEMY_TYPES의 모든 속성을 복사해서 새 객체에 붙여 넣어요. 한 줄로 3가지 적을 다 다르게 만들 수 있는 비밀."
🎨
학생 액션 본인만의 4번째 적 추가해 보기 — 이름·색·hp·speed 정해서 spawnEnemy에 추가.
05 / Live Build · Step 3⏱ 15분

Step 3 — 시간 흐를수록 더 어렵게

처음엔 천천히, 1분 후엔 빡빡하게. 웨이브 시스템이 게임의 페이스를 만든다.

3
Claude에게 보낼 요청
"시간(elapsed)을 변수로 추적해줘. spawnTimer를 시간에 따라 줄여줘: - 0~30초: 60프레임마다 1마리(1초당 1마리) - 30~60초: 20프레임마다(1초당 3마리) - 60초 이후: 12프레임마다(1초당 5마리) 그리고 60초 이후엔 박쥐 비율도 30%로 올려."
예상 결과 — 웨이브 로직
let elapsedFrames = 0; // 매 프레임 +1 let spawnInterval = 60; function updateWave(){ elapsedFrames++; const sec = elapsedFrames / 60; if(sec < 30) spawnInterval = 60; // 보통 else if(sec < 60) spawnInterval = 20; // 빠르게 else spawnInterval = 12; // 위험 } function pickType(sec){ const r = Math.random(); const batRate = sec < 60 ? 0.2 : 0.5; // 박쥐 비율 증가 if(r < 0.6) return 'zombie'; if(r < 0.6 + batRate) return 'bat'; return 'skeleton'; }
🎙
게임 디자인 핵심 "좋은 게임은 '학습 곡선' 위에 있어요. 처음엔 쉬워야 떨어지지 않고, 점점 어려워야 도전이 돼요. 30초·60초 같은 구간 나누기가 진짜 기술."
05 / Live Build · Step 4⏱ 13분

Step 4 — 100마리 처리 (최적화)

적이 100마리면 컴퓨터가 느려진다. 몇 가지 비법으로 부드럽게 돌게 만든다.

4
Claude에게 보낼 요청
"한 화면에 적이 100마리 있어도 끊기지 않게 최적화해줘. 1. 동시 최대 100마리 제한 (그 이상은 스폰 안 함) 2. 화면 멀리 있는 적은 그리지 않음 (off-screen culling) 3. 죽은 적은 splice 말고 빠른 방법으로 제거 4. 충돌 체크는 화면 안 적만"
예상 결과 — 3가지 최적화
// 1) 최대 수 제한 const MAX_ENEMIES = 100; function spawnEnemy(){ if(enemies.length >= MAX_ENEMIES) return; // ...스폰 } // 2) 화면 밖 안 그리기 function draw(){ enemies.forEach(e => { if(e.x < -50 || e.x > 850 || e.y < -50 || e.y > 650) return; ctx.beginPath(); ctx.arc(e.x, e.y, e.r, 0, Math.PI*2); ctx.fillStyle = e.color; ctx.fill(); }); } // 3) 빠른 제거 (filter 1번) function cleanup(){ for(let i = enemies.length-1; i >= 0; i--){ if(enemies[i].hp <= 0) enemies.splice(i, 1); } }
🎙
최적화의 진실 "100마리까지는 보통 노트북에서 돌아가요. 1000마리는 무리. 게임 디자이너는 '얼마까지 돌아가는지'를 알고 그 안에서 디자인해요."
📊
학생 액션 (FPS 측정) MAX_ENEMIES를 50·100·200으로 바꿔 보고 게임이 끊기는지 확인. 자기 노트북 한계 찾기.
05 / Live Build · Step 5⏱ 10분

Step 5 — 시간 + 처치 수 HUD

"내가 얼마나 살아남았지?" — 화면 위에 숫자가 떠 있으면 게임이 진짜처럼 느껴진다.

5a
처치 수 변수
적이 죽을 때마다 killCount++. 단순하지만 게임의 점수.
let killCount = 0; // 적 사망 처리부에서 if(e.hp <= 0){ enemies.splice(j, 1); killCount++; }
5b
화면 위 텍스트 그리기
canvas에 흰 글씨로 시간·처치 수를 좌상단에 그림.
ctx.fillStyle = '#fff'; ctx.font = 'bold 20px monospace'; const sec = (elapsedFrames / 60).toFixed(1); ctx.fillText(`Time: ${sec}s`, 16, 30); ctx.fillText(`Kills: ${killCount}`, 16, 56);
5c
테스트 플레이 (3분)
1분 동안 살아남기. 30초 지났을 때 적 등장 속도가 빨라지는 게 진짜 느껴지는지. 60초 후 박쥐가 늘어나는지.
🎙
오늘의 마무리 "오늘 만든 게임은 진짜 뱀파이어 서바이벌처럼 느껴져요. 다음 주에 '레벨업·무기 선택' 추가하면 진짜 게임이 됩니다. 기대해도 좋아요."
10 / Checkpoint⏱ 5분

여기까지 됐나? 확인하기

잘 됐다면
  • 적이 화면 가장자리에서 등장
  • 좀비·박쥐·스켈레톤 3종류 색깔로 구분
  • 30초 지나면 등장 속도 체감으로 빨라짐
  • 화면에 적 50마리 넘게 있어도 안 끊김
  • 시간·Kills 숫자가 좌상단에 표시
⚠️자주 막히는 부분
  • 적이 한 곳에서만 나옴 → side 랜덤 변수 확인
  • 적 종류가 다 똑같음 → pickType 함수 호출 확인
  • 게임이 끊김 → MAX_ENEMIES 100 이하로 제한
  • 웨이브가 안 바뀜 → elapsedFrames가 증가하는지 확인
  • HUD 글씨가 검은 배경에 안 보임 → fillStyle '#fff' 흰색
11 / Challenge⏱ 5분

더 해보고 싶다면 도전

👹
2분마다 보스 한 마리가 등장 (hp 500, 큰 빨간 동그라미). 죽이면 Kills +50.
난이도 ★
🧟
좀비 무리가 뭉쳐서 등장. 한 번 스폰될 때 5마리가 같은 위치에서.
난이도 ★★
💀
플레이어 체력을 만들고, 적에게 닿으면 hp 감소. 0이 되면 "Game Over".
난이도 ★★★
12 / Student Gallery⏱ 5분

작년 친구들 서바이벌

13 / Next Week⏱ 5분

다음 시간 예고

WEEK 10 · COMING UP

레벨업과 무기 진화 —
3장 카드 중 하나

적을 잡으면 경험치를 얻고, 레벨업할 때 3장 카드가 떠요. 새 무기 OR 기존 무기 강화 — 선택은 너의 몫. 칼+창=양날검 같은 진화 트리도 등장.

PREPARE · 준비물
  • 오늘 만든 게임 (100마리 처리되는 버전)
  • 좋아하는 게임의 '레벨업 카드' 화면 스크린샷 한 장
  • 본인이 만들고 싶은 무기 5종 아이디어 (이름·이펙트)