보름달 — 1인 개발 스튜디오 · English

코드로 그리는 수묵

작은 모바일 패링 게임의 붓 획, 먹 방울, 한지 한 장까지 전부 게임이 켜질 때 코드로 그려요. 아래에서 게임의 붓을 직접 써 볼 수 있어요.

보름달(FullMoon), 1인 개발 · 2026년 10월

붓으로 그린 먹 원 안의 검객, 위쪽의 먹빛 보스, 따뜻한 한지 위로 튄 먹
선비검객. 원, 검객, 보스, 화살, 종이까지 전부 코드로 만든 그림이에요.

선비검객은 조선 시대를 배경으로, 한지에 먹으로 그린 것처럼 보이게 만든 패링 게임이에요. 저는 그림을 그리는 사람이 아닌데, 공격·보스·검·배경을 수십 가지 넣으면서도 한 사람 손으로 그린 것처럼 통일하고 싶었어요. 그래서 이 게임에는 이미지 파일이 없어요. 게임이 켜질 때 붓 함수 하나로 캔버스에 전부 그리고, 그걸 PixiJS 텍스처로 넘겨요. 앱 전체가 13MB예요.

배경음도 코드로 만드는데, 그건 오디오 파일 없는 가야금에 정리했어요. 이 글은 그림 이야기예요.

게임의 붓으로 그려 보기

종이 위를 끌면 그려져요. 게임에 들어간 붓 함수 그대로가 지금 브라우저에서 돌아가요. 막대는 게임이 쓰는 값과 같은 설정이에요.

1. 획은 선이 아니라 면이에요

캔버스의 선은 처음부터 끝까지 굵기가 같아요. "컴퓨터 그림"이 티 나는 첫 번째 이유죠. 진짜 붓은 닿고, 누르고, 떼면서 빠져요. 그래서 게임의 획은 lineTo 에 lineWidth 를 주는 방식이 아니라, 경로를 따라 만든 채운 다각형이에요.

const widthAt = (u) => {             // u: 시작 0, 끝 1
  let k = 1;
  if (u < taperStart) k = startWidth + (1 - startWidth) * smoothstep(u / taperStart);
  else if (u > 1 - taperEnd) k = endWidth + (1 - endWidth) * smoothstep((1 - u) / taperEnd);
  return width * k;
};

데모에서 '굵기 변화'를 0으로 내리면 평범한 캔버스 선으로 돌아가요. 이 차이가 느낌의 대부분이에요.

2. 반듯하지 않은 가장자리

굵기가 변해도 테두리가 너무 매끈하면 여전히 벡터 그림처럼 보여요. 종이 섬유와 붓털 때문에 실제 가장자리는 조금씩 흔들려요. 그래서 양쪽 가장자리에 각각 1차원 값 노이즈(격자에 무작위 값을 두고 사이를 smoothstep 으로 잇는 것)를 획 길이를 따라 적용해요. 흔들림 크기는 획 길이와 상관없이 약 6px이고, 굵기의 최대 8%만큼 가장자리를 밀어요. 양쪽이 서로 다른 노이즈라 좌우 대칭처럼 보이지 않아요.

3. 번짐, 먹 고임, 마른 붓

나머지는 작은 층 세 개가 해요.

파내기는 따로 둔 임시 캔버스에서 하고 결과만 옮겨 그려요. 그래서 틈은 새 획만 파고, 그 아래 이미 그린 것은 건드리지 않아요. 데모에서 '마른 붓'을 올리면 갈라진 결이 보이고, 0이면 촉촉하고 꽉 찬 획이 돼요.

4. 먹 방울과 튄 먹

먹 방울도 다각형이에요. 원 둘레의 점 22개를 노이즈로 들쭉날쭉하게 밀고, 두 번 그려요. 조금 더 큰 옅은 테 한 번, 진한 방울 한 번. 튄 먹은 방울 하나에 작은 방울과 줄기 일곱에서 열한 개를 바깥으로 흩뿌린 거예요. 싸움 중 먹이 튀는 장면에 써요.

붓으로 그린 공격과 튄 먹이 있는 전장 대련 붓으로 그린 아이콘이 있는 비기 카드

5. 한 번, 흰색으로 굽고 물들이기

이걸 매 프레임 그리면 휴대폰에서는 너무 느려요. 그래서 게임이 켜질 때 화면 밖 캔버스에 한 번만 그리고 PixiJS 텍스처로 만들어요. 대부분은 흰색으로 그려요. 실행 중에 스프라이트의 색조(tint)로 같은 텍스처를 먹빛, 인주 빨강, 옅은 담묵, 금빛으로 바꿔요. 구운 모양 하나로 먹빛 공격도, 인주색 경고도, 금빛 보상도 돼요.

그림마다 씨앗을 정한 난수 생성기(sfc32)를 따로 써요. 그래서 어느 기기에서 언제 켜도 그림이 똑같고, 새 검을 하나 추가해도 그 뒤에 그려지는 보스들의 난수가 밀려서 몰래 다른 그림이 되는 일이 없어요.

6. 방해하지 않는 종이

한지 배경도 같은 방식으로 만들어요. 섬유 노이즈, 옅은 비네팅, 그리고 값 노이즈 세 옥타브로 만든 먼 산 세 겹이 아래로 갈수록 안개로 흩어져요. 가장 가까운 능선 두 겹은 마른 붓 한 획이 따라 그려요. 열 수 있는 화폭(매화, 나루, 궁궐, 소나무, 폭포, 대나무, 달, 설경)도 전부 코드로 그리고, 공격이 지나가는 통로는 비워 둬요.

가장 중요했던 규칙은 대비예요. 가장 진한 산도 종이 대비 약 1.3:1, 예고 표시는 5.6:1, 공격은 14:1이에요. 찰나에 반응하는 게임이라 배경이 공격처럼 보이는 일은 절대 없게 했어요.

겹겹의 먹 산이 있는 한지 타이틀 화면 먹 물결과 함께 있는 묵귀

7. 젖은 먹으로 된 보스

최종 보스 묵귀는 먹 귀신인데, 첫 판은 그냥 검은 실루엣 같았어요. 세 가지로 젖은 느낌을 냈어요.

배운 것

선비검객은 아이폰과 안드로이드에 나와 있어요. 한 번 사면 끝이고 광고도 앱 내 구매도 없어요.

게임 보기 · App Store · Google Play · 소리는 어떻게 만들었나