안녕하세요! 이번 글에서는 냥트코인 프로젝트의 디자인과 퍼블리싱 과정에 관해 이야기해 보려고 합니다.
보통 프론트엔드 개발자는 디자이너가 만들어준 UI를 코드로 구현하는 역할을 맡습니다. 하지만 만약 디자인 시안조차 없는 상태에서 개발을 시작해야 한다면 어떨까요? 디자인 감각이 뛰어난 개발자라면 몰라도, 대부분의 개발자는 이런 상황에서 당황할 수밖에 없습니다.
다행히 이번 프로젝트에서는 난아님과 다은님, 그리고 저까지 총 세 명이 디자인을 고민할 수 있었습니다. 물론 전문적인 UI/UX 디자이너는 아니었지만, 개발자가 직접 디자인해야 하는 상황에서 어떻게 UI를 구상하고, CSS를 효율적으로 적용하며, 어떤 어려움을 겪었는지 솔직하게 풀어보겠습니다.
이 글이 게임을 처음 만드는 분들께 작은 참고가 되고, 팀원들에게는 프로젝트를 돌아보는 기회가 되길 바랍니다. 편하게 읽어주세요!
디자인 접근 방식
보통 프론트엔드 개발자는 디자이너가 만들어준 UI 시안을 받아 퍼블리싱하는 역할을 합니다. 하지만 이번 프로젝트에서는 디자이너 없이 프론트엔드 개발자가 직접 디자인해야 하는 상황이었습니다. 난아님과 다은님은 실무 경험은 없었지만, 디자인에 관한 공부를 해왔고, 그동안 쌓아온 감각을 활용해 프로젝트의 스타일을 정하기로 했습니다.
1. 디자인 레퍼런스를 찾아라!
디자인을 처음부터 만들어내는 것은 쉽지 않았습니다.
그래서 Pinterest, Dribbble, 그리고 Google 검색을 활용하여 원하는 분위기를 찾았습니다.

이렇게 여러 자료를 수집한 후, Figma에서 비슷한 분위기의 디자인을 한데 모아 비교하면서 컨셉을 구체화했습니다.
2. 두 가지 시안 제작 - 고민의 시작
초기 디자인 시안을 두 가지로 나누어 작업했습니다.
- 깔끔하고 심플한 UI 중심의 디자인
- 개성을 강조한 강렬한 스타일의 디자인

두 시안 모두 장단점이 있었고, 팀원들의 의견도 갈렸습니다.
- 1번 디자인은 가독성이 뛰어나고 직관적이지만, 다소 평범하다는 의견이 있었습니다.
- 2번 디자인은 개성이 강하고 독창적이었지만, 사용성이 떨어질 가능성이 있었습니다.
3. 최종 컨셉 - 두 개를 결합한 레트로 스타일
결국 두 시안의 장점을 결합하여 하나의 컨셉을 만들었습니다.
- 심플한 UI의 가독성을 유지하면서도,
- 개성 있는 컬러와 요소를 추가하고,
- 픽셀 아트 느낌을 살리면서, 타이포그래피와 색감에서 레트로 감성을 더하는 방향으로 결정했습니다.
이렇게 해서 냥트코인의 레트로 스타일이 완성되었습니다.
번외: 로고 디자인도 쉽지 않았다...
사실 UI뿐만 아니라 로고 디자인도 큰 고민거리였습니다.
초기에 심플한 로고가 레트로한 스타일, 두 가지 로고 시안을 만들었고,
UI와 마찬가지로 팀원들의 의견이 분분했습니다.
결국, UI와 로고의 톤을 맞추는 방향으로 조율했지만,
최종 결정을 내리기까지 꽤 오랜 시간이 걸렸습니다. 😂


번외2: 디자인이 확정되면서 기능 정의까지 흔들렸다?!
디자인이 확정되면서 예상치 못한 일이 벌어졌습니다.
UI가 구체화하다 보니, 기능 정의에 대한 생각도 달라진 것입니다.
결국, 화면 설계서를 두 번이나 다시 수정해야 했습니다.

디자인이 결정되자, 세부적인 UI/UX 흐름을 더 고민하게 되었습니다.
- "게임 대기방이나 게임방일때 사용자가 이탈했을 때 화면에 어떻게 표시해야 할까?"
- "사기, 팔기 버튼은 어디에 배치해야 가장 편할까?"
- "숫자 선택을 쉽게 하기 위해 5, 10 같은 매크로 버튼을 넣을까?"
이처럼 디자인을 보면서 기능적인 고민이 계속 추가되었고, 이에 따라 기능 정의도 바뀌어야 했습니다.
문제는... 팀원들 모두 너무 바빴다는 것....
보통 기능 정의서는 A4 한 장 표 정리 방식이지만, 이번 프로젝트는 변경이 잦아 UI 흐름 중심으로 정리했습니다.
회의 중에는 화면별 UI 흐름과 기능을 함께 정리하고,
회의 후에는 참가자 목록 업데이트 등 동적인 요소를 도식화하여 가시성을 높였습니다.

기능 확정될 때마다 팀원들한테 공유하고,
각자 확인 후에 메모장으로 피드백을 남기는 방식으로 진행했습니다.
회의 때도 메모장 내용을 기반으로 논의하면서 실시간으로 기능을 조율했고,
결국, 메모장이 실시간 기능 정의 문서 역할을 하게 되었습니다. 😂

퍼블리싱, 생각보다 만만치 않았습니다
Next.js에서 CSS-in-JS는 SSR 환경에서 성능 이슈가 발생할 가능성이 있어,
이번 프로젝트에서는 퍼포먼스를 고려해 Tailwind CSS를 선택했습니다.
특히, 빌드 타임 최적화와 SSR 환경에서의 스타일 적용 속도를 고려했을 때,
Tailwind CSS가 더 적합하다고 판단했습니다.
하지만 퍼블리싱 과정에서 예상치 못한 문제들이 있었습니다.
특히, 힌트 컴포넌트의 배경 이미지 비율 문제와 고양이 아바타 박스(캣박스)의 이미지 정렬 문제가 대표적인 사례였습니다.
1. 힌트 컴포넌트 - 종이 배경 비율 깨짐 문제
발생한 문제
힌트 컴포넌트에서는 배경에 종이 느낌의 PNG 이미지를 삽입하기 위해 background CSS 속성을 사용했습니다.
그러나 힌트의 길이에 따라 배경 이미지 비율이 깨지는 문제가 발생했습니다.

해결 과정
Next.js의 `<Image />` 컴포넌트에 `fill` 속성과 `object-fit` CSS를 적용했습니다. 그러나 기기마다 다르게 보이는 문제가 발생했고, 특히 세로 비율이 고정되지 않아 이미지가 왜곡되었습니다.

이후 모바일 테스틀 통해, 종이 비율을 유지하려면 높이값 조정이 핵심 요소라는 점을 확인했습니다. `object-fit`을 활용하는 대신 미디어 쿼리를 사용하여 `height` 값을 조정하면서 반응형 대응을 했습니다. 이를 통해 기기마다 일관된 비율을 유지하면서 UI의 일관성 확보했습니다.

2. 고양이 아바타 박스 - 이미지 정렬 문제
발생한 문제
고양이 이미지가 일관되지 않게 정렬되는 문제가 있었습니다.
처음에는 부모 태그에 `display: flex; justify-content: center; align-items: center;`를 적용했지만,
고양이 아바타 박스 크기가 변할 때 이미지 위치가 상대적으로 어긋나는 문제가 발생했습니다.
해결 과정
이미지 정렬 문제를 해결하기 위해 flex와 margin을 활용하여 조정하는 방식을 적용했습니다.
- 이미지 부모 요소에 relative를 적용하여 fill 속성이 정상적으로 동작하도록 설정
- `object-fit: contain`을 적용하여 이미지 비율을 유지하면서 크기를 균일하게 조정
- flex box를 기본 정렬 방식으로 유지하면서, margin을 추가로 조정하여 위치를 미세하게 보정

퍼블리싱, 예상보다 훨씬 어려웠다.
이번 프로젝트는 레트로 디자인을 적용하다 보니 일반적인 퍼블리싱 방식으로는 해결이 어려운 경우가 많았습니다. 디자인 의도를 최대한 살리면서도 퍼포먼스와 유지보수성을 고려하는 것이 쉽지 않았습니다.
결국, 완벽한 구현보다는 현실적인 타협이 필요하다는 것을 깨달았습니다. "이 정도면 괜찮겠지"라고 생각했던 부분들이, 실제로 구현할 때는 예상치 못한 변수가 발생하는 경우가 많았습니다.
예를 들어, 힌트 컴포넌트의 이미지를 단순히 `object-fit: cover;`로 설정하면 자연스럽게 적용될 줄 알았지만, 힌트 길이에 따라 이미지 비율이 깨지는 문제가 발생했습니다.
디자인과 개발 균형을 맞추는 것이 중요하다는 점을 깨달았지만, 현재 받은 피드백을 반영하지 못한 부분이 남아 있습니다. 앞으로 보완할 부분이 많습니다.
이제 퍼블리싱을 어느 정도 마무리했으니, 다음 단계에서는 소켓 이벤트를 활용한 인터랙션 구현에 대한 글을 다룰 예정입니다. (언제 글을 올릴 수 있을지는 모르겠지만....!)
🔥 디자인을 함께 고민해준 난아님과 다은님, 정말 감사합니다! 🎨✨

'냥트코인' 카테고리의 다른 글
[냥트코인 제작기 1편] 프론트엔드 개발자가 어떻게 게임 기획을 했을까? (0) | 2025.01.15 |
---|
안녕하세요! 이번 글에서는 냥트코인 프로젝트의 디자인과 퍼블리싱 과정에 관해 이야기해 보려고 합니다.
보통 프론트엔드 개발자는 디자이너가 만들어준 UI를 코드로 구현하는 역할을 맡습니다. 하지만 만약 디자인 시안조차 없는 상태에서 개발을 시작해야 한다면 어떨까요? 디자인 감각이 뛰어난 개발자라면 몰라도, 대부분의 개발자는 이런 상황에서 당황할 수밖에 없습니다.
다행히 이번 프로젝트에서는 난아님과 다은님, 그리고 저까지 총 세 명이 디자인을 고민할 수 있었습니다. 물론 전문적인 UI/UX 디자이너는 아니었지만, 개발자가 직접 디자인해야 하는 상황에서 어떻게 UI를 구상하고, CSS를 효율적으로 적용하며, 어떤 어려움을 겪었는지 솔직하게 풀어보겠습니다.
이 글이 게임을 처음 만드는 분들께 작은 참고가 되고, 팀원들에게는 프로젝트를 돌아보는 기회가 되길 바랍니다. 편하게 읽어주세요!
디자인 접근 방식
보통 프론트엔드 개발자는 디자이너가 만들어준 UI 시안을 받아 퍼블리싱하는 역할을 합니다. 하지만 이번 프로젝트에서는 디자이너 없이 프론트엔드 개발자가 직접 디자인해야 하는 상황이었습니다. 난아님과 다은님은 실무 경험은 없었지만, 디자인에 관한 공부를 해왔고, 그동안 쌓아온 감각을 활용해 프로젝트의 스타일을 정하기로 했습니다.
1. 디자인 레퍼런스를 찾아라!
디자인을 처음부터 만들어내는 것은 쉽지 않았습니다.
그래서 Pinterest, Dribbble, 그리고 Google 검색을 활용하여 원하는 분위기를 찾았습니다.

이렇게 여러 자료를 수집한 후, Figma에서 비슷한 분위기의 디자인을 한데 모아 비교하면서 컨셉을 구체화했습니다.
2. 두 가지 시안 제작 - 고민의 시작
초기 디자인 시안을 두 가지로 나누어 작업했습니다.
- 깔끔하고 심플한 UI 중심의 디자인
- 개성을 강조한 강렬한 스타일의 디자인

두 시안 모두 장단점이 있었고, 팀원들의 의견도 갈렸습니다.
- 1번 디자인은 가독성이 뛰어나고 직관적이지만, 다소 평범하다는 의견이 있었습니다.
- 2번 디자인은 개성이 강하고 독창적이었지만, 사용성이 떨어질 가능성이 있었습니다.
3. 최종 컨셉 - 두 개를 결합한 레트로 스타일
결국 두 시안의 장점을 결합하여 하나의 컨셉을 만들었습니다.
- 심플한 UI의 가독성을 유지하면서도,
- 개성 있는 컬러와 요소를 추가하고,
- 픽셀 아트 느낌을 살리면서, 타이포그래피와 색감에서 레트로 감성을 더하는 방향으로 결정했습니다.
이렇게 해서 냥트코인의 레트로 스타일이 완성되었습니다.
번외: 로고 디자인도 쉽지 않았다...
사실 UI뿐만 아니라 로고 디자인도 큰 고민거리였습니다.
초기에 심플한 로고가 레트로한 스타일, 두 가지 로고 시안을 만들었고,
UI와 마찬가지로 팀원들의 의견이 분분했습니다.
결국, UI와 로고의 톤을 맞추는 방향으로 조율했지만,
최종 결정을 내리기까지 꽤 오랜 시간이 걸렸습니다. 😂


번외2: 디자인이 확정되면서 기능 정의까지 흔들렸다?!
디자인이 확정되면서 예상치 못한 일이 벌어졌습니다.
UI가 구체화하다 보니, 기능 정의에 대한 생각도 달라진 것입니다.
결국, 화면 설계서를 두 번이나 다시 수정해야 했습니다.

디자인이 결정되자, 세부적인 UI/UX 흐름을 더 고민하게 되었습니다.
- "게임 대기방이나 게임방일때 사용자가 이탈했을 때 화면에 어떻게 표시해야 할까?"
- "사기, 팔기 버튼은 어디에 배치해야 가장 편할까?"
- "숫자 선택을 쉽게 하기 위해 5, 10 같은 매크로 버튼을 넣을까?"
이처럼 디자인을 보면서 기능적인 고민이 계속 추가되었고, 이에 따라 기능 정의도 바뀌어야 했습니다.
문제는... 팀원들 모두 너무 바빴다는 것....
보통 기능 정의서는 A4 한 장 표 정리 방식이지만, 이번 프로젝트는 변경이 잦아 UI 흐름 중심으로 정리했습니다.
회의 중에는 화면별 UI 흐름과 기능을 함께 정리하고,
회의 후에는 참가자 목록 업데이트 등 동적인 요소를 도식화하여 가시성을 높였습니다.

기능 확정될 때마다 팀원들한테 공유하고,
각자 확인 후에 메모장으로 피드백을 남기는 방식으로 진행했습니다.
회의 때도 메모장 내용을 기반으로 논의하면서 실시간으로 기능을 조율했고,
결국, 메모장이 실시간 기능 정의 문서 역할을 하게 되었습니다. 😂

퍼블리싱, 생각보다 만만치 않았습니다
Next.js에서 CSS-in-JS는 SSR 환경에서 성능 이슈가 발생할 가능성이 있어,
이번 프로젝트에서는 퍼포먼스를 고려해 Tailwind CSS를 선택했습니다.
특히, 빌드 타임 최적화와 SSR 환경에서의 스타일 적용 속도를 고려했을 때,
Tailwind CSS가 더 적합하다고 판단했습니다.
하지만 퍼블리싱 과정에서 예상치 못한 문제들이 있었습니다.
특히, 힌트 컴포넌트의 배경 이미지 비율 문제와 고양이 아바타 박스(캣박스)의 이미지 정렬 문제가 대표적인 사례였습니다.
1. 힌트 컴포넌트 - 종이 배경 비율 깨짐 문제
발생한 문제
힌트 컴포넌트에서는 배경에 종이 느낌의 PNG 이미지를 삽입하기 위해 background CSS 속성을 사용했습니다.
그러나 힌트의 길이에 따라 배경 이미지 비율이 깨지는 문제가 발생했습니다.

해결 과정
Next.js의 `<Image />` 컴포넌트에 `fill` 속성과 `object-fit` CSS를 적용했습니다. 그러나 기기마다 다르게 보이는 문제가 발생했고, 특히 세로 비율이 고정되지 않아 이미지가 왜곡되었습니다.

이후 모바일 테스틀 통해, 종이 비율을 유지하려면 높이값 조정이 핵심 요소라는 점을 확인했습니다. `object-fit`을 활용하는 대신 미디어 쿼리를 사용하여 `height` 값을 조정하면서 반응형 대응을 했습니다. 이를 통해 기기마다 일관된 비율을 유지하면서 UI의 일관성 확보했습니다.

2. 고양이 아바타 박스 - 이미지 정렬 문제
발생한 문제
고양이 이미지가 일관되지 않게 정렬되는 문제가 있었습니다.
처음에는 부모 태그에 `display: flex; justify-content: center; align-items: center;`를 적용했지만,
고양이 아바타 박스 크기가 변할 때 이미지 위치가 상대적으로 어긋나는 문제가 발생했습니다.
해결 과정
이미지 정렬 문제를 해결하기 위해 flex와 margin을 활용하여 조정하는 방식을 적용했습니다.
- 이미지 부모 요소에 relative를 적용하여 fill 속성이 정상적으로 동작하도록 설정
- `object-fit: contain`을 적용하여 이미지 비율을 유지하면서 크기를 균일하게 조정
- flex box를 기본 정렬 방식으로 유지하면서, margin을 추가로 조정하여 위치를 미세하게 보정

퍼블리싱, 예상보다 훨씬 어려웠다.
이번 프로젝트는 레트로 디자인을 적용하다 보니 일반적인 퍼블리싱 방식으로는 해결이 어려운 경우가 많았습니다. 디자인 의도를 최대한 살리면서도 퍼포먼스와 유지보수성을 고려하는 것이 쉽지 않았습니다.
결국, 완벽한 구현보다는 현실적인 타협이 필요하다는 것을 깨달았습니다. "이 정도면 괜찮겠지"라고 생각했던 부분들이, 실제로 구현할 때는 예상치 못한 변수가 발생하는 경우가 많았습니다.
예를 들어, 힌트 컴포넌트의 이미지를 단순히 `object-fit: cover;`로 설정하면 자연스럽게 적용될 줄 알았지만, 힌트 길이에 따라 이미지 비율이 깨지는 문제가 발생했습니다.
디자인과 개발 균형을 맞추는 것이 중요하다는 점을 깨달았지만, 현재 받은 피드백을 반영하지 못한 부분이 남아 있습니다. 앞으로 보완할 부분이 많습니다.
이제 퍼블리싱을 어느 정도 마무리했으니, 다음 단계에서는 소켓 이벤트를 활용한 인터랙션 구현에 대한 글을 다룰 예정입니다. (언제 글을 올릴 수 있을지는 모르겠지만....!)
🔥 디자인을 함께 고민해준 난아님과 다은님, 정말 감사합니다! 🎨✨

'냥트코인' 카테고리의 다른 글
[냥트코인 제작기 1편] 프론트엔드 개발자가 어떻게 게임 기획을 했을까? (0) | 2025.01.15 |
---|