크레센도 Phaser + TypeScript TIL 6
한 판 하고 타이틀에서 다시 START하면 시작이 안 됐다
한 판 끝내고 타이틀로 돌아가 START를 누르면 게임이 시작되지 않았다. 증상만으로는 원인이 안 잡혔는데, 브라우저 콘솔(F12로 여는 개발자 도구의 오류 출력)을 보니 오류 한 줄이 원인을 그대로 가리켰다.
Phaser는 씬을 다시 시작해도 씬 객체를 새로 만들지 않고 재사용한다. 이전 판에서 배경 이미지를 “없으면 만든다”는 방식으로 한 번만 만들어 뒀는데, 판이 끝나며 이미지는 파괴됐어도 “있다”는 표시가 남아 두 번째 판에서 파괴된 이미지를 쓰려다 멈춘 것이다.
두 가지를 가져간다. 하나는 “안 된다”고 말할 때 콘솔 오류를 같이 보는 것이다. 증상 설명으로 코드를 뒤지는 것보다 오류 한 줄이 빠르다. 다른 하나는 재시작이 “새로 시작”이 아니라 “이어서”일 수 있다는 것이다. 한 번만 만들어 두는 것이 있으면 재시작 때 지우는 목록에 넣어야 한다.
빛 기둥이 보스가 없는 자리로 내려왔다
S5 최종전은 칼리고 체력이 0이 되면 하늘에서 빛 기둥이 내려와 맞추고 2페이즈가 시작되는 연출이다. 그런데 빛이 내려오는 자리에 보스가 없었다. 체력이 0이 된 뒤에도 보스가 옆으로 미끄러져 빛이 빈자리에 떨어졌다.
죽기 직전에 잡혀 있던 추적 속도가 남아 있어서였다. 속도를 0으로 해도 그 프레임의 이동이 남았다. 연출 동안은 물리 이동 자체를 끄고, 체력이 0이 된 그 좌표를 저장해 빛·2페이즈 등장 전부 그 자리를 쓰게 했다.
연출은 “그 순간의 자리”를 기준으로 짜인다. 그 자리를 순간에 고정해 두지 않으면 연출 요소끼리 어긋난다. 멈추라고 하는 것과 멈춘 자리를 기억하는 것은 다른 일이다.
빛이 닿자마자 임팩트가 와서 급해 보였다
빛 기둥이 착지하는 순간 바로 화면 흔들림과 배경 교체가 왔다. 둘이 붙어 있으니 급했다. 빛이 완전히 착지한 뒤 잠깐 멈췄다가 임팩트가 오도록 사이에 텀을 뒀다.
연출은 “다음 단계”를 이어 붙이는 게 아니라 단계 사이의 빈 시간까지 설계하는 일이다. 임팩트 직전의 정지가 임팩트를 크게 만든다. 템포를 조절할 값들은 이름을 붙여 한 곳에 모아 두면 숫자 하나씩 만지며 맞출 수 있다.
공격 연타가 안 됐다
공격 버튼을 연타해도 애니메이션이 끝나야 다음 공격이 나가 답답했다. 쿨다운(다음 공격까지 기다리는 시간)이 애니메이션 길이 700ms와 같아서였다.
그렇다고 쿨다운을 아주 짧게 하면 타격 판정이 들어가기 전에 다음 공격이 시작돼 앞 공격이 취소되고 피해가 새어 나간다. 판정 구간이 시작 후 140~385ms라면, 쿨다운을 그 판정창이 끝나는 지점(약 400ms)에 맞추면 매 타가 확실히 들어간 뒤 다음 공격이 이어진다.
앞선 TIL 1·5에서 판정 구간을 애니메이션과 분리해 둔 덕에 쿨다운을 판정 기준으로 잡을 수 있었다. 연타감은 애니메이션 길이가 아니라 판정창 끝이 결정한다.