물리 엔진 없이 리듬을 만드는 법 — 두들타워 제작기
두들타워를 처음 기획할 때 "블록이 진짜처럼 흔들리게" 만들고 싶다는 요청이 나온 적이 있다. 흔들리는 추처럼 양 끝에서 느려지고 가운데서 빨라지는, 진자 운동에 가까운 움직임을 상상한 것이다. 실제로 만들어 보니 그건 잘못된 방향이었다.
등속으로 결정한 이유
두들타워의 블록은 물리 엔진을 전혀 쓰지 않는다. 한 프레임마다 정해진 속도만큼 위치를 더하고, 화면 가장자리를 살짝 넘어선 지점에서 방향만 뒤집는다. 가속도도 감속도 없는 순수한 등속 운동이다. 처음엔 진자 운동을 흉내 내려 했지만, 실제로 플레이해보니 문제가 생겼다. 속도가 구간마다 달라지면 플레이어가 몸으로 익힌 리듬이 매번 미묘하게 어긋났다. 한 번은 감이 맞았다가 한 번은 안 맞는, 실력이 아니라 운으로 갈리는 게임처럼 느껴졌다. 반면 등속으로 바꾸자 한 왕복의 시간이 완전히 예측 가능해졌고, 몇 층만 지켜보면 몸이 리듬을 외웠다. 타이밍 게임에서는 물리적으로 '진짜 같은' 움직임보다 '예측 가능한' 움직임이 더 중요하다는 걸 이 과정에서 배웠다. 정확히 반복되는 리듬이라야 몸이 그 리듬을 외울 수 있고, 몸이 외운 리듬이라야 손이 눈보다 먼저 움직일 수 있다는 게 이 게임 전체를 관통하는 전제다.
속도는 층이 아니라 점수를 본다
완전히 고정된 속도는 아니다. 누적 점수가 오를수록 블록의 이동 속도가 조금씩 빨라지다가 상한선에서 멈춘다. 층수가 아니라 점수를 기준으로 삼은 이유는, PERFECT를 자주 낸 사람일수록 점수가 빨리 오르고, 그만큼 빨리 어려워지는 쪽이 밸런스에 맞다고 판단해서다. 같은 층에 있어도 지금까지 잘해온 사람과 그렇지 못한 사람이 서로 다른 속도의 블록을 상대하게 되는 셈이다. 실제 공식은 "기본 속도 2.4에 점수 곱하기 0.09를 더하되, 6을 넘지 않는다"로 짜여 있다. 즉 점수가 0일 때는 초당 2.4칸, 점수가 40점을 넘어서면 계산상 6.0칸에 도달해 그 뒤로는 더 빨라지지 않는다. 시작 속도 대비 최대 속도가 2.5배 정도 빨라지는 셈인데, 이 배율은 실력이 늘수록 확실히 더 어려워지되 손이 따라가지 못할 정도로 폭주하지는 않는 선에서 여러 차례 조정을 거쳐 정해진 값이다. 점수와 속도를 이렇게 직접 묶어둔 덕분에, 잘하는 사람에게는 도전이 계속 이어지고 아직 손에 익지 않은 사람에게는 초반 여러 층을 느긋한 속도에서 연습할 여유가 자연스럽게 주어진다.
잘려나간 조각에만 중력을 준다
정작 이 게임에서 유일하게 물리 시뮬레이션다운 계산이 들어가는 곳은 메인 블록이 아니라, 삐져나와 잘려 떨어지는 조각들이다. 이 조각들은 매 프레임 아래로 떨어지는 속도가 조금씩 더 빨라지도록(중력 가속도에 해당하는 값을 속도에 계속 더하는 방식으로) 계산되고, 동시에 회전값도 같이 누적된다. 메인 블록은 순수한 등속 이동인데, 화면 밖으로 떨어져 나가는 조각은 이렇게 단순하게나마 중력을 흉내 낸다. 플레이어가 직접 조작하는 대상은 예측 가능해야 하고, 결과로 나타나는 연출은 무너지듯 자연스러워야 한다는, 서로 다른 두 가지 요구를 각각 다른 방식으로 풀어낸 셈이다.
화면보다 넓게 왕복한다
블록은 화면에 보이는 영역 안에서만 왕복하지 않는다. 보이는 가장자리를 18px 정도 넘어선 지점에서 방향을 바꾼다. 완전히 화면 끝에서 딱 맞춰 돌아오게 하면, 블록이 화면 경계에 붙어 잠깐 멈춘 것처럼 어색해 보이는 순간이 생겼기 때문이다. 살짝 더 넓게 왕복시키고 그 여유분은 화면 밖에 숨겨두는 것만으로 훨씬 자연스러운 움직임이 됐다. 손그림 게임의 디테일 대부분이 이런 식이다. 거창한 물리 계산보다, 눈에 거슬리는 지점을 하나씩 찾아 작은 숫자로 다듬는 작업에 더 가깝다.
카메라는 8층부터, 그것도 스르륵 움직인다
탑이 계속 쌓이는데 화면은 한정돼 있으니 어딘가에서는 시점을 위로 옮겨야 한다. 두들타워는 쌓인 층수가 8층을 넘어서기 전까지는 카메라를 전혀 움직이지 않는다. 목표 위치를 정하는 공식은 "지금까지 쌓은 층수에서 8을 뺀 값을 층 높이만큼 곱한다, 다만 0보다 작아지지 않는다"로 짜여 있어서, 8층까지는 항상 0으로 계산돼 카메라가 그대로 멈춰 있다. 그리고 9층부터는 목표 위치가 조금씩 올라가는데, 카메라가 그 목표 위치로 순간이동하듯 뚝 끊겨 움직이지는 않는다. 실제 코드는 매 프레임 "지금 카메라 위치와 목표 위치의 차이 중 12%만큼만 이동한다"는 식으로 계산돼 있다. 이런 방식을 흔히 '선형 보간(lerp)에 의한 카메라 추적'이라고 부르는데, 목표 지점에 가까워질수록 이동폭 자체가 작아지기 때문에 카메라가 마치 관성이 있는 것처럼 부드럽게 감속하며 목표에 다가가는 것처럼 보인다. 블록은 딱딱 끊어지는 등속으로 움직이지만 카메라는 부드럽게 미끄러지듯 움직이도록, 같은 화면 안에서도 요소마다 다른 움직임의 질감을 의도적으로 섞은 셈이다.
착지할 때 살짝 눌리는 이유
블록을 성공적으로 쌓을 때마다 맨 위 블록이 아주 짧은 순간 옆으로 살짝 퍼졌다가 원래 모양으로 돌아오는 연출이 있다. 가로로는 살짝 늘어나고 세로로는 살짝 눌리는 식인데, 이건 애니메이션 업계에서 '스쿼시 앤 스트레치(squash and stretch)'라고 부르는 아주 오래된 기법이다. 딱딱한 물체가 바닥에 닿는 순간 아주 미세하게 찌그러졌다가 되돌아오는 모습이, 실제로는 없는 무게감과 탄성을 시각적으로 만들어낸다. 두들타워에서는 블록이 놓인 직후 한동안 남아 있는 짧은 타이머 값을 이용해 이 찌그러지는 정도를 계산하고, 시간이 지나면서 그 값이 줄어들도록 만들어 자연스럽게 원래 모양으로 돌아오게 한다. 등속으로 딱딱 끊어지듯 움직이는 블록의 예측 가능함과, 착지 순간의 말랑한 탄성감은 서로 다른 인상처럼 보이지만, 실은 둘 다 "블록 하나하나가 손에 잡힐 듯 살아있게 느껴지게 만든다"는 같은 목표를 향한 장치다. 몸으로 외울 수 있을 만큼 예측 가능한 리듬과, 순간순간 눈을 즐겁게 하는 작은 흔들림을 동시에 만족시키는 게 이 게임을 다듬는 작업의 핵심이었다.