에피소드 06 (PLAY) 폭풍이 오는 날

에피소드 06 (PLAY) 폭풍이 오는 날

에피소드 06 (PLAY) — 폭풍이 오는 날

“얘들아… 하늘 색 이상하지 않아?” 리온이 모니터를 가리키자, 세이와 딕이 동시에 다가왔다. 지금까지의 하늘은 파랗고 평화로웠다. 그런데 오늘은… 마치 바람이 숨어 있는 듯, 색이 약간 흔들렸다.

딕이 몸을 뒤로 젖히며 말했다. “와… 이거 약간 무서운데? 영화에서 폭풍 오기 직전 느낌!” 세이가 안경을 만지며 냉정하게 말했다. “사실… 의도한 건 아니지?” “응. 전혀.” 리온이 웃으며 머리를 긁적였다.

“근데 말이야.” 딕이 손가락을 들어 올렸다. “구름도 만들었잖아? 그럼 이제 구름보다 더 큰 ‘뭔가’가 나와야 하는 거 아냐?” 세이는 바로 고개를 끄덕였다. “그래. 오늘은 폭풍을 만드는 날이야.”

1. MAKE — 하늘이 흔들리는 순간

세이가 낮은 목소리로 말했다. “폭풍 만들기… 생각보다 간단해. ‘흔들림’만 구현하면 돼.” 리온이 고개를 끄덕였다. “맞아. 플레이어는 비행기가 흔들릴 때 ‘아, 위험하구나!’ 하니까.”

우리는 우선 하늘 전체를 아주 약하게 흔들리는 효과부터 넣기로 했다. 그건 x나 y를 조금씩 움직이는 방식으로 충분했다.


// 바람 흔들림 값
let windShake = 0;

// 폭풍 활성화 여부
let stormActive = false;

// 폭풍 흔들림 업데이트
function updateStorm() {
  if (stormActive) {
    windShake = Math.sin(Date.now() / 80) * 3; // 좌우 흔들림
  } else {
    windShake = 0;
  }
}

코드를 확인하던 딕이 말했다. “오! 그러니까 폭풍일 때만 화면이 좌우로 살짝 흔들린다는 거네?” “응. 아주 약하게. 처음부터 세게 하면 어지러워서 게임 못 해.” 세이가 차분하게 설명했다.

리온은 약간 기대되는 표정으로 말했다. “좋아. 그럼 이제 코러호가 이 흔들림을 느끼게 해보자.”


function drawWorld() {
  ctx.save();
  ctx.translate(windShake, 0); // 화면 전체를 흔든다
  drawSky();
  drawClouds();
  drawPlane();
  ctx.restore();
}

딕이 코러호를 움직이며 외쳤다. “우와! 진짜 하늘이 출렁거리는 것 같아!” 세이가 말했다. “이제 시작이야. 폭풍은 ‘흔들림’만 있는 게 아니니까.”

2. PLAY — 바람 벡터 만들기

세이는 태블릿에 바람 화살표를 그렸다. “폭풍에는 바람 방향이 있어. 가끔은 오른쪽에서 밀고, 가끔은 왼쪽에서 당기고.”

리온이 말했다. “그럼 비행기 속도에도 영향을 주는 거네?” “맞아.” 세이가 미소 지었다.


// 바람 영향
let windX = 0;

function updateWind() {
  if (stormActive) {
    // -1 ~ 1 사이의 랜덤한 바람
    windX = (Math.random() * 2 - 1) * 0.3;
  } else {
    windX = 0;
  }
}

딕이 손을 번쩍 들었다. “그럼 이제 비행기 조종이 더 어려워지는 거야?” “살짝만.” 세이가 말했다. “너무 어렵게 하면 재미없잖아.”


// 비행기 업데이트에 바람 더하기
plane.x += plane.vx + windX;

리온이 직접 조종해 보더니 말했다. “오… 움직임이 부드럽게 살짝 밀리는 느낌 나! 이거 진짜 ‘날씨’ 같다!”

3. PLAY — 번개 효과 (시각 경고)

딕이 갑자기 말했다. “폭풍인데… 번개는 없냐?” 세이가 바로 대답했다. “있어야지.” 리온은 웃었다. “너희들, 진짜 게임 제작자 같다?”

번개는 사실 어려운 게 아니다. 전체 화면을 잠깐 하얗게 번쩍이게 하면 된다.


let lightningTimer = 0;

function triggerLightning() {
  if (stormActive && Math.random() < 0.01) {
    lightningTimer = 5; // 5프레임 번쩍
  }
}

function drawLightning() {
  if (lightningTimer > 0) {
    ctx.fillStyle = "rgba(255,255,255,0.5)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    lightningTimer--;
  }
}

딕이 게임을 테스트하며 외쳤다. “우와!!! 방금 번쩍했어!!! 뭐야 이거 완전 영화인데?!” 세이는 자랑스럽게 말했다. “사용자에게 ‘위험’을 알리는 가장 간단한 방식이지.”

4. PLAY — 번개 피해 시스템

번개가 보이기만 한다면 재미가 없다. 맞으면 아파야지.

세이가 설명했다. “번개는 구름이나 충돌처럼 위치로 맞는 게 아니야. ‘번쩍이는 순간’ 전체 영역이 위험이야.”


let planeHP = 3;

function updateDamage() {
  if (lightningTimer > 0) {
    planeHP -= 1;
  }
  if (planeHP < 0) planeHP = 0;
}

딕의 입이 벌어졌다. “헐… 이제 HP도 생겼어? 완전 RPG잖아!” 리온은 웃으며 말했다. “하늘 RPG지. 우리 세계니까.”

이제 코러호가 번개에 맞으면 HP가 줄어들고, HP가 0이 되면 ‘긴급 착륙’ 화면이 나오도록 설계했다.

5. DREAM — 폭풍 뒤의 파란 틈

한참 테스트한 뒤, 세 아이 모두 말이 없었다. 폭풍 속 코러호는 때로는 흔들리고, 때로는 번쩍임에 놀라고, 때로는 바람에 밀렸다.

딕이 말했다. “우리… 진짜 게임 만드는 사람 같다.” 세이는 조용히 고개를 끄덕였다. “폭풍 하나 만들었을 뿐인데도 이렇게 깊은 느낌이 나네.” 리온이 모니터를 보며 미소 지었다. “근데 말이야… 폭풍이 지나가면 뭐가 있을까?”

딕은 당연하다는 듯 말했다. “신대륙이지!” 세이는 태블릿에 적었다. ‘폭풍을 넘으면 새로운 지역이 열린다.’

리온이 마지막으로 말했다. “좋아. 다음은 에피소드 07 (DREAM)이겠다. 폭풍을 지나면서 보이는… 새로운 빛.”

6. English Summary (500 chars)

In Episode 06 (PLAY), Leon, Sey, and Dic create their first real storm. They add screen shake, random wind vectors, lightning flashes, and HP damage to make Corer One feel the danger of the sky. Through playful testing, they learn how weather systems create tension and meaning in gameplay. By the end, the storm becomes more than an obstacle—it's a gateway to a new land. Next stop: the bright gap beyond the clouds.

7. TAG

#에피소드06 #PLAY단계 #DIY게임 #Canvas #폭풍코딩 #리온세이딕 #코러호 #바람벡터 #번개효과 #엔딕프로젝트

Powered by Blogger.