🎮 FruitSpinner 개발일지 #5 — 보이는 것이 전부다

🎨 그래디언트에서 플랫으로 초기 버전의 육각형은 그래디언트 가 들어간 입체적인 스타일이었다. 구 모양 하이라이트에 그림자까지. 그런데 과일 이모지와 조합하니 너무 복잡해 보였다. 이모지 자체가 이미 디테일이 있는 그래픽인데, 배경까지 화려하면 시각적 노이즈가 심해진다. 결국 하늘색 플랫 벡터 스타일 로 바꿨다. 육각형은 단순한 배경 역할만 하고, 과일 이모지가 주인공이 되는 구조. 컵이나 파이프 같은 UI 요소도 같은 스타일로 통일했다. 🖼️ Canvas 렌더링 순서의 함정 플랫 스타일로 바꾼 뒤 이상한 현상이 생겼다. 과일 이모지가 흐릿하게 보이는 것이다. 원인을 찾아보니 렌더링 순서 문제였다. Canvas 는 나중에 그린 것이 위에 올라간다. 그런데 육각형 배경을 그릴 때 배경색 과 테두리를 한 번에 그리고 있었다. 배경색이 이모지 위에 반투명하게 덮여서 이모지가 흐려 보였던 것이다. 해결은 단순했다. 모든 육각형의 배경과 테두리를 먼저 그리고, 그 다음에 모든 이모지를 따로 그리는 2패스 렌더링 으로 바꿨다. 배경 레이어 → 이모지 레이어. 이 순서만 지키면 이모지가 항상 선명하게 보인다. 교훈: Canvas에서 복잡한 요소를 그릴 때는 "무엇을 먼저 그릴 것인가"가 핵심이다. 🍎 이모지의 한계와 장점 이모지를 게임 그래픽으로 쓰는 건 장단점이 분명하다. 장점은 명확하다. 별도 에셋 없이 바로 쓸 수 있고, 누구나 알아보는 직관적인 그래픽이다. 과일 8종(🍎🍊🍋🍇🍓🍑🥝🍒)이 색상까지 자동으로 구분된다. 개발 속도 면에서 이보다 빠른 방법은 없다. 한계도 있다. OS마다 이모지 디자인이 다르다. iOS에서 예쁘게 보이던 과일이 Android에서는 다른 느낌일 수 있다. 크기 조절이 완벽하지 않아서 잎사귀 같은 부분이 튀어나오기도 한다. 그래서 육각형이라는 명확한 경계 안에 가두는 방식 을 택한 것이기도 하다. 💧 물방울 실험 한 가지 재미있는 실험을 했다. 같은 ...

🎮 FruitSpinner 개발일지 #4 — 과일이 주스가 되기까지

🍊 과일을 터뜨리면 끝? 매칭된 과일이 팡! 하고 터지는 것만으로는 뭔가 부족했다. 터졌다 → 점수 올라감 은 너무 밋밋하다. 과일이 터진 후에 뭔가 더 일어나면 좋겠다고 생각했고, 그래서 나온 게 주스 만들기 시스템 이다. 매칭된 과일이 사라지는 대신, 파이프를 타고 빨려 들어가서 갈리고, 주스가 되어 컵에 담긴다. 게임에 만드는 재미 를 더한 셈이다. ✨ 4단계 파이프라인 전체 흐름은 이렇다. 매칭된 과일이 화면 왼쪽의 파이프 입구로 빨려 들어간다(1단계). 파이프 안에서 블렌더 가 과일을 간다(2단계). 갈린 주스가 꼭지를 통해 아래로 흘러내린다(3단계). 컵에 주스가 채워지면서 점수가 올라간다(4단계). 각 단계마다 애니메이션과 효과음이 붙어서 하나의 연속된 경험이 된다. 🎵 사운드 삽질기 효과를 구현이 예상 외로 까다로웠다. Web Audio API 의 오실레이터로 사운드를 직접 합성했는데, 첫 결과물은 SF 영화 사운드 같았다. 블렌더 소리가 위잉~ 위잉~! 하는 전자음이 나왔다. 실제 믹서기는 저주파 진동에 가까운 "우르르르" 소리인데, 오실레이터 기본 설정으로는 그런 소리가 안 나왔다. triangle 파형에 120~200Hz 대역을 오가는 방식으로 바꾸니 그제야 믹서기 느낌이 났다. 주스 따르는 소리도 마찬가지. 처음엔 톤 기반 사운드가 나왔는데, 실제 액체 소리는 화이트 노이즈에 밴드패스 필터 를 걸어야 비슷해진다. 노이즈 버퍼를 직접 생성하고 필터를 적용해서 쪼르르르~ 소리를 만들었다. 결론: 게임 사운드는 현실에 가까울수록 몰입감이 높다. 스타일리시한 전자음보다 실제 소리를 흉내는 게 플레이어한테 더 자연스럽게 느껴진다. 🍹 컵이 왜 거기 있어? 주스 시스템의 비주얼에서도 시행착오가 있었다. 꼭지와 컵을 처음 그렸을 때, 컵이 꼭지 옆에 위치해 있었다. 현실에서 컵은 꼭지 아래 에 있어야 주스를 받을 수 있다. 사소하지만 이런 물리적 상식 에 어긋나면 플레...

🎮 FruitSpinner 개발일지 #3 — 게임의 뼈대를 세우다

1편에서 아이디어를 잡고, 2편에서 AI와 함께 개발 방향을 정했다면, 이번 3편은 실제 게임의 뼈대가 되는 핵심 시스템들을 구현한 이야기다. 육각형 격자, 보드 회전, 매칭 판정까지 — 게임이 게임다워지는 순간들이었다. 🍎 육각형 격자라는 선택 1편에서 잠깐 언급했지만, 원형 배치에서 육각형 격자 로 바꾼 건 이 프로젝트의 가장 중요한 기술적 결정이었다. 원형 배치의 문제는 단순하다. 바깥 링으로 갈수록 같은 링 내 과일 사이 간격이 벌어진다. 안쪽은 빽빽한데 바깥은 듬성듬성. 이웃 판정도 어려워지고 보기에도 어색하다. 육각형 격자(Hex Grid) 는 이 문제를 깔끔하게 해결한다. 모든 과일이 정확히 6개의 이웃과 동일한 거리를 유지한다. 벌집 구조와 같은 원리다. ⚙️ 큐브 좌표 시스템 육각형 격자를 코드로 다루려면 좌표 시스템이 필요하다. 일반적인 x, y 대신 큐브 좌표 ( q, r, s )를 사용했다. 세 값의 합이 항상 0이 되는 제약 조건이 있어서, 이웃 찾기와 거리 계산이 단순한 덧뺄셈으로 해결된다. 이웃을 찾을 때 거리 기반으로 하면 회전할 때 문제가 생긴다. 타원형 탐색도 고려해봤지만, 판이 회전하면 타원 방향도 같이 돌아야 해서 복잡해진다. 결국 격자 좌표 기반으로 이웃을 명시적으로 지정하는 방식이 가장 안정적이었다. 🔥 회전하는 보드 버블 스피너의 핵심은 회전 이다. 과일을 발사할 때마다 충돌 지점에 따라 보드 전체가 회전한다. 이게 단순한 퍼즐을 전략 게임으로 만드는 요소다. 구현 자체는 Canvas의 translate + rotate 로 어렵지 않다. 문제는 회전 후에도 과일 이모지가 똑바로 보여야 한다는 점이다. 육각형 배경은 판과 함께 회전하되, 위에 올라가는 이모지는 역방향으로 회전을 상쇄시켜서 항상 정면을 향하게 했다. 🛠️ 매칭 판정 같은 과일 3개 이상이 연결되면 터지는 로직. BFS(너비 우선 탐색) 로 같은 색 이웃을 타고 가면서 그룹을 찾고, 3개 이상이면 매칭 성공이다...

🎮 FruitSpinner 개발일지 #2 — AI와 함께 게임 만들기

개발의 시작은 단순했다. 버블 스피너의 기획 내용을 정리한 문서를 Claude에게 보내고 "이거 만들어줘" 라고 했다. 그랬더니 정말 돌아가는 게임이 나왔다. 600×600 Canvas 에 버블이 배치되고, 클릭하면 발사되고, 회전도 하는. 물론 그게 완성은 아니었다. 여기서부터 진짜 개발이 시작됐다. 🤖 프롬프트 한 줄로 시작된 개발 AI와의 개발은 기존 코딩과 꽤 다른 경험이었다. 코드를 한 줄씩 짜는 대신, "이 부분 이렇게 바꿔줘" 라고 요청하고 결과를 확인하는 방식이다. 예를 들어 이런 식이다: "버블 간격이 너무 넓어. 딱 붙게 해줘" → 상수값 조정 "물방울이 합쳐지는 것처럼 같은 색끼리 뭉쳐 보이게 할 수 있어?" → 렌더링 로직 변경 "효과음이 SF 같은데, 진짜 믹서기 소리처럼 해줘" → 오디오 파라미터 수정 한 번에 완벽한 결과가 나오는 경우는 거의 없었다. "이건 아닌데" 라고 피드백하고, 다시 수정하고, 또 확인하고. 이 반복이 개발 과정의 대부분이었다. ✅ 잘 된 것들 빠른 프로토타이핑이 압도적으로 좋았다. 아이디어를 말하면 몇 분 안에 동작하는 코드가 나온다. "과일 모양으로 바꿔볼까?" 라는 아이디어를 실제로 확인하는 데 5분이면 충분했다. 기술적 판단도 도움이 됐다. 원형 배치의 한계를 설명해주고 육각형 격자 를 제안한 것, 물리 엔진 라이브러리들의 차이를 비교해준 것, Canvas 최적화에 대해 "지금은 할 필요 없다" 고 현실적으로 조언해준 것 등. ⚠️ 아쉬웠던 것들 맥락을 잃는 순간이 있다. 대화가 길어지면 이전에 합의한 내용을 다시 설명해야 할 때가 있었다. "아까 그건 안 하기로 했잖아" 라고 상기시켜야 하는 상황. 과하게 바꾸는 경향. "이 부분만 수정해줘" 라고 했는데...

🎮 FruitSpinner 개발일지 #1 — 아이디어의 시작

이미지
버블 스피너라는 게임을 아는 사람이 얼마나 될까. 중앙에 버블 덩어리가 있고, 플레이어가 버블을 쏴서 같은 색 3개 이상을 맞추면 터지는 퍼즐 게임이다. 여기에 "회전" 이라는 요소가 붙어서, 쏠 때마다 판이 돌아간다. 단순하지만 중독성 있는 게임. 이 게임을 HTML5 로 만들어보고 싶었다. 정확히 말하면, 이걸 내 손으로 만들어서 토스 인앱 게임 으로 출시해보고 싶었다. 🤔 왜 이 게임이었나 사실 거창한 이유는 없었다. 버블 스피너라는 장르가 구현 난이도 대비 게임성이 좋다고 느꼈고, 모바일 세로 화면에서 한 손으로 플레이하기 딱 좋은 구조라고 생각했다. 복잡한 3D 엔진이나 물리 시뮬레이션 없이도 Canvas 하나 로 충분히 만들 수 있겠다 싶었다. 🤖 AI와 함께 만들기로 했다 여기서 한 가지 실험적인 결정을 했다. Claude(AI) 와 대화하면서 게임을 만들어보기로 한 것이다. 기획 문서를 정리해서 "이거 만들어줘"라고 던졌다. 처음엔 React 버전과 HTML 버전 두 개를 동시에 만들었는데, 금방 "HTML 버전만 하자" 로 방향을 잡았다. 순수 HTML5 Canvas 하나로 가는 게 심플하고, Cordova로 모바일 앱을 만들 때도 깔끔했다. 🐛 첫 번째 문제: 버블이 안 붙는다 초기 버전은 원형 버블을 원형으로 배치하는 구조였다. 그런데 바깥 링으로 갈수록 버블 사이 간격이 벌어지는 문제가 생겼다. 링마다 버블 수가 ring × 6 개씩 늘어나니 당연한 결과였다. 이상한 간격 "육각형이나 8각형이어야 하나?" 고민하다가 육각형 격자(Hexagonal Grid) 로 구조를 바꿨다. 벌집처럼 모든 버블이 6개의 이웃과 동일한 거리로 붙는 방식이다. 이 결정이 게임의 기반이 됐다. 버블 덩어리 🍎 과일이라는 테마 그리고 한 가지 아이디어가 떠올랐다. "버블 대신 과일로 하면 어떨...