캐릭터가 작아서 안 보인다: 랜선포차 화상 그리드를 머리~허리 구도로 당긴 날
2×3 화상 그리드의 캐릭터가 작다는 말을 듣고 구도를 다시 잡았다. 보여 줄 세로 범위를 2.5에서 1.93으로 줄이고, 이름표와 배탈 게이지를 얇게 만든 과정을 커밋으로 정리했다.

랜선포차는 우유 벌칙 파티 게임이다. 폰을 세로로 들면 위쪽 절반에 여섯 명이 2×3 칸으로 보이고, 아래쪽에 미니게임 조작 영역과 채팅이 붙는다. 칸 하나하나를 화상채팅 창처럼 보이게 만든 것이 이 게임의 화면 콘셉트다.
9월 28일, 이 칸에 대해 짧은 피드백을 받았다. “캐릭터가 작아서 잘 안 보인다.” 코드 주석에도 이 문장을 날짜와 함께 그대로 적어 두었다. 이날 저녁 시안을 비교하고, 그중 하나를 골라 커밋했다(92148fb, 병합 2320455). 이 글은 그 하루 작업의 기록이다.
화상채팅 구도는 이틀 전에 이미 한 번 바꿨다
구도를 손댄 건 이번이 처음이 아니다. 9월 26일 플레이 피드백을 반영한 커밋(9f3a1d6)에서, 캐릭터를 전신 대신 얼굴과 상체만 보이는 화상채팅 구도로 바꿨다. 흔들림 연출의 중심도 발에서 목으로 옮겼다. 얼굴만 보이는 구도에서 발을 기준으로 돌리면 머리가 화면 밖으로 튀기 때문이다.
캐릭터 그림은 모두 512×512 좌표 위에 그려져 있고, 그림마다 정수리·얼굴·목·손 위치를 앵커로 갖고 있다. 구도는 이 앵커로 정한다. 정수리부터 목까지의 길이를 기준 단위(span)로 잡고, “정수리 위로 몇 span, 목 아래로 몇 span”을 칸 높이에 맞춰 넣는 식이다. 그림마다 머리 크기가 달라도 같은 규칙으로 맞출 수 있다.
9월 26일의 값은 정수리 위 0.45, 목 아래 1.05였다. 머리 하나 길이까지 더하면 세로로 2.5 span을 칸에 넣은 셈이다. 게다가 칸 위쪽 16px는 이름표 자리로 비워 두고 그 아래부터 그렸다. 폰 화면의 작은 칸에 머리부터 배까지 넣고 위까지 비우니, 얼굴이 작아질 수밖에 없었다.
시안 두 개를 같은 장면에서 찍었다
같은 판의 같은 순간을 세 가지 구도로 캡처해 나란히 놓았다. 지금 구도, 시안 A(머리허리), 시안 B(머리가슴)다. 장면도 세 가지로 찍었다. 평범한 진행 장면, 배탈 게이지가 높은 사람이 섞인 장면, 화장실에 간 사람이 있는 장면이다.

윗줄 두 칸만 잘라 세 구도를 비교했다. 닉네임은 가렸다.
A와 B는 둘 다 얼굴이 확실히 커졌다. 비교 화면에 추천으로 표시해 둔 것은 A였고, 커밋도 A로 했다. 머리~허리까지 담으면 감자 캐릭터 옆의 우유팩처럼 손에 든 소품도 칸 안에 들어온다. A를 코드로 옮기면서 이 소품이 잘리지 않게 하는 규칙을 하나 더 붙였다.
구도 숫자를 바꾸고 위쪽 16px를 돌려받았다
시안 A의 값은 정수리 위 0.38, 목 아래 0.55다. 세로 범위가 2.5 span에서 1.93 span으로 줄었다.
| 항목 | 9월 26일 구도 | 시안 A (9월 28일) |
|---|---|---|
| 정수리 위 | 0.45 span | 0.38 span |
| 목 아래 | 1.05 span | 0.55 span |
| 세로 범위 합계 | 2.5 span | 1.93 span |
| 칸 위쪽 여백 | 16px 비움 | 없음 (칸 위 끝부터 채움) |
| 손 소품 | 범위 안에 있으면 보임 | 손 앵커 아래 34까지 늘 보이게 |
세로 범위만 따지면 2.5÷1.93, 약 1.3배다. 여기에 이름표 자리로 비워 두던 위쪽 16px를 캐릭터에게 돌려준 몫이 더해진다. 16px가 칸 높이에서 차지하는 비중은 칸이 작을수록 커진다. 커밋 메시지에는 둘을 합친 확대 폭을 “약 1.55배”로 적었다.
손 소품 규칙은 따로 넣었다. 목 아래 0.55 span에서 자르면 손이 배 근처에 있는 그림은 우유팩이 잘린다. 그래서 손 소품을 든 경우에는 아래 경계를 손 앵커보다 34만큼 더 내렸다.
export const CLOSE_FRAME = { top: 0.38, bottom: 0.55, hand: 34 };
let bottom = a.neck[1] + span * CLOSE_FRAME.bottom;
// 손 소품이 잘려 나가지 않게. 배 부여잡음(3단계) 그림은 손 소품을 숨긴다
const hand = this.avatar?.hand;
if (hand && hand !== "none" && this.stage < 3)
bottom = Math.max(bottom, a.hand[1] + CLOSE_FRAME.hand);
return { cx: a.face[0], top: a.head[1] - span * CLOSE_FRAME.top, bottom };
배탈 3단계 그림은 원래 손 소품을 숨기므로 이 보정도 하지 않는다. 숨긴 소품 자리까지 비워 둘 이유가 없어서다.
전신 구도는 그대로 두었다
모든 그림을 당기면 안 되는 경우가 둘 있다. 하나는 배탈 게이지가 다 차서 화장실로 뛰어가는 4단계 그림이다. 휴지를 들고 달리는 전신 그림이라 머리가 아래나 옆에 가 있다. 다른 하나는 라운드 사이 숨 고르기 동안 보여 주는 몸풀기 자세다. 이것도 다리 동작까지 보여야 한다.
이 두 경우에는 구도 정보에 “전신” 표시를 붙이고, 예전처럼 칸 위 16px와 아래 4px를 비운 채 그린다. 위는 이름표 한 줄, 아래는 얇아진 배탈 게이지 자리다. 꾸미기 화면의 단일 캐릭터 미리보기도 예전 구도를 유지했다. 거기서는 옷과 소품을 고르는 중이라 몸 전체가 보여야 한다.

배탈 게이지가 높은 칸과 화장실에 간 칸. 시안 A에서도 화장실행은 전신으로 남고, 게이지는 칸 아래 가장자리의 얇은 줄이 됐다.
이름표와 배탈 게이지를 캐릭터 밖으로 뺐다
얼굴을 키우면 칸 위아래의 글자가 그만큼 얼굴을 덮는다. 그래서 겹쳐 있던 표시도 같이 줄였다.
| 표시 | 이전 | 시안 A |
|---|---|---|
| 이름표 | 닉네임 띠 아래 칭호 띠, 두 줄 | 반투명 한 줄, 칭호는 닉네임 옆에 말줄임 |
| 이름표 글자 | 0.72rem | 0.6rem (칭호 0.55rem) |
| 배탈 게이지 | 칸 아래 6px 막대 + 잔 수·퍼센트가 든 상자 | 칸 아래 가장자리 3px 줄 |
| 잔 수·퍼센트 | 게이지 양옆 | 왼쪽 아래 작은 반투명 칩 |
이름표 검정 배경의 불투명도는 55%에서 38%로 낮췄다. 확대 구도에서는 이름표가 머리 위에 살짝 얹히는데, 그래도 머리카락과 모자가 비쳐 보이게 하려는 것이다. 이름표가 한 줄로 줄어든 만큼 칸 오른쪽 위의 상태 배지도 6px 위로 올렸다. 이름표와 게이지는 터치를 받지 않게 해서, 칸을 눌러 사람을 고르는 미니게임에서 글자 위를 눌러도 칸이 눌린다.
돌아보며
이틀 사이에 구도를 두 번 바꿨다. 첫 번째는 전신에서 화상채팅 구도로 가는 방향 전환이었고, 두 번째는 그 방향 안에서 숫자를 고친 일이다. 두 번째가 더 빨랐던 건 구도가 앵커와 span 비율로 정해져 있어서였다. 56종 그림을 하나씩 손보지 않고 숫자 세 개만 바꾸면 됐다. 대신 그 규칙에 맞지 않는 화장실행, 몸풀기, 꾸미기 미리보기는 따로 표시해서 빼야 했다.
같은 날 추가한 몸풀기 자세 그림은 기울이기를 버리고 몸풀기 자세를 두 장씩 그렸다에, 배탈 단계와 화장실 관전은 배탈 게이지와 화장실 관전에 적었다. 커진 캐릭터는 랜선포차 게임 페이지에서 바로 들어가 볼 수 있다.


