🐾 CatsPaw – 낙서를 통해 소통하는 그림 퀴즈 게임
고양이 손을 빌린 듯한 귀여운 낙서를 그리고 맞히며 소통하는 웹 기반 게임입니다.
🎮 게임 모드
- [멀티모드] 최대 4인이 실시간으로 그림을 그리고 맞히며 즐기는 파티형 게임
- [싱글모드] AI가 사용자의 그림을 인식하고 정답을 추측하는 1인 플레이 모드
🏆 경쟁과 소통
- [싱글모드 랭킹 시스템] 점수를 기준으로 상위 3명의 유저가 메인 페이지에 노출
- [라운지 기능] 라운지에서는 멀티 모드 결과를 공유해 플레이어 간 추가 재미와 소통을 제공
👤 사용자 기능
- [마이 페이지] 닉네임과 프로필 캐릭터를 설정하여 “Cat’s Paw”만의 개성 있는 프로필 변경 가능
- [유저 페이지] 친구 추가 및 다른 유저의 포스트 열람 기능 지원
| 구분 | 사용 기술 |
|---|---|
| 프론트엔드 | |
| 협업 툴 | |
| 서비스 배포 환경 | |
| 디자인 |
| 한유빈 | 박준규 | 이예빈 | 황수지 |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
| @yubin121 | @parkjungyuxx | @llyybbb | @ssujissuji |
멀티모드
- Supabase Realtime을 사용하여 실시간 이벤트 감지
- 인원 수에 따라 전체 턴 수가 결정되고 각 턴마다 sender와 receiver가 랜덤으로 배정되도록 Edge Function 구현 후 배포
- 짝수 턴마다 제출한 그림은 Supabase Storage에 업로드
- 모든 플레이어가 제시어 또는 그림을 제출 완료한 상태라면 즉시 다음 턴으로 넘어가고, 그렇지 않다면 각 턴의 타이머가 종료되는 즉시 자동 저장 후 넘어가는 구조로 구현
- 다음 턴으로 넘어갔을 때 다른 플레이어의 제시어나 그림을 바로 받아오지 못한 경우, Polling 기법을 활용하여 받아올 수 있도록 설계
- 게임 종료 후, 처음에 설정한 각 제시어가 모든 턴을 지나면서 어떻게 변화했는지 시각적으로 확인 가능하도록 앨범 형식으로 로직 구현
- 원하는 결과 앨범을 캡처하여 커뮤니티로 공유 가능하도록 구현
데이터베이스 설계
- 프로젝트에 사용되는 Supabase Database 모든 설계 구현
싱글모드
- Google의 Teachable Machine을 활용하여 Quick, Draw! 기반 낙서 데이터를 직접 학습시켜, 맞춤형 이미지 분류 모델을 구축
- 학습된 모델을 통해 유저가 그린 그림을 예측하고, 예측 결과를 기반으로 정답 여부를 실시간으로 판단하는 구조를 구현
- GPT, Gemini 등 생성형 AI에 비해 로딩 시간이 짧고 예측 속도가 빠른 장점을 극대화하여, 스피드 게임의 몰입도를 유지할 수 있도록 최적화
- 사용자가 제출한 그림은 Supabase Storage에 업로드되며, 게임 종료 후 결과 화면에서 예측 결과와 함께 시각적으로 확인할 수 있게 구성
실시간 채팅
- Supabase Realtime 기능을 활용하여, 동일한 게임방에 있는 유저들 간의 실시간 채팅이 가능하도록 구현
- 게임방 고유 ID를 기준으로 유저들을 분리하여, 각 게임방 내에서만 메시지를 주고받을 수 있는 채팅 룸 구조 구현
- 메시지 전송 시점, 작성자, 방 정보 등 관련 데이터를 함께 저장하고, 페이지 이동 또는 새로고침 시에도 기존 채팅 내역을 유지할 수 있도록, DB에 저장된 메시지를 불러와 초기 렌더링 시 채팅 내역을 복원하도록 구성
- 게임 중 사용자 간 자유로운 소통을 통해 몰입감과 재미 요소를 높이는 데 기여
드로잉 캔버스
- Konva.js 기반으로 선 그리기, 지우개, 색상 선택, 선 굵기 조절 등 다양한 드로잉 툴을 제공하여, 사용자의 자유로운 그림 표현을 지원
- Canvas API의 getImageData를 활용하여 동일 영역 색상 변경이 가능한 전체 색 채우기(Fill) 기능을 구현
- 사용자의 드로잉 작업 내역을 기록하고, 이전 상태로 되돌릴 수 있는 Undo 기능을 통해 자유도 높은 그림 그리기를 지원
게임 타이머
- 게임의 각 단계(제시어 보기, 그림 그리기, 추측 시간 등)에 맞는 개별 타이머 시스템을 구현
- 전역 상태로 타이머를 관리하여, 게임 모드에 따라 유연하게 타이머를 재활용할 수 있도록 설계
- 타이머 종료 시 자동으로 다음 단계로 넘어가는 게임 흐름 컨트롤 로직을 함께 구성하여 게임 진행을 자동화
로그인
- supabase OAuth 로그인 구현 및 로그인 상태 관리
- 익명 로그인 구현
메인 페이지 애니메이션
- GSAP(GreenSock Animation Platform)을 활용하여 메인 페이지의 스크롤 및 드로잉 애니메이션 구현
- 부드러운 사용자 경험을 위한 스크롤 스무더(ScrollSmoother) 효과 적용
싱글모드 랭킹
- 싱글모드 게임 결과가 저장되는
game_scores테이블에서 유저별 최고 점수를 집계 - 동일 유저가 중복되지 않도록 상위 3명의 최고 점수를 기준으로 정렬하여 추출하는 서버 사이드 함수
get_top_3_user_scores작성 - Supabase의
.rpc()메서드를 통해 해당 함수에 접근하고, 이를 기반으로 최상위 유저 정보를 화면에 시각적으로 렌더링
기본 캐릭터 등록 및 캐릭터 변경
- 모든 캐릭터 이미지를 Supabase Storage에 업로드하여 URL 기반 접근을 가능하게 하고, 프론트엔드에서는 이미지 파일명만으로 캐릭터 정보를 관리
- 회원가입하는 모든 유저들의 기본 프로필 사진을 cat’s paw의 기본 캐릭터로 변경하도록 supabase에 트리거 함수를 적용
친구
friend_requests와friends테이블을 설계하여 요청과 수락 상태를 명확히 구분- 친구 요청 수락 시 해당 row는
friend_requests에서 삭제되고friends테이블에 자동으로 추가되도록 트리거 함수 작성 - Supabase의 Realtime 기능을 활용하여 친구 요청 및 친구 상태의 변경 사항이 사용자 화면에 실시간으로 반영되도록 구현
커뮤니티
- 사용자의 로그인/로그아웃 상태에 따른 접근 제어
- 좋아요 중복 방지 설정
- 무한 스크롤 기능 구현
- React Loader 함수를 이용하여 라우트 진입 시점에 미리 데이터 페칭하도록 구현
요소 디자인
- 웹페이지 전반적인 요소 디자인
- GSAP(GreenSock Animation Platform)을 활용하여 스크롤에 따라 다양한 애니메이션을 볼 수 있습니다.
- 스크롤 스무더(ScrollSmoother) 효과를 적용함으로써 부드러운 사용자 경험을 제공합니다.
- 싱글모드 점수에 따른 랭킹 시스템 및 라운지의 인기 게시물을 모아서 확인할 수 있습니다.
- 프로젝트 컨셉에 맞게 낙서 형태로 디자인되었습니다.
3._.mp4
- 마이 페이지에선 나의 정보, 친구 관련 목록, 전체 유저 목록, 게시글 목록 조회가 가능합니다.
- 나의 이름과 캐릭터를 변경할 수 있고, 친구와 유저는 검색이 가능하며 친구 신청/수락/거절/조회 기능을 포함합니다.
- 유저 페이지에선 해당 유저의 정보, 친구 목록, 전체 유저 목록, 해당 유저의 게시글 목록이 조회 가능하며 나와의 친구상태가 버튼으로 표시됩니다.
3._.mp4
1) 게시글 확인 및 상호작용
- 유저들이 게시한 글들을 확인할 수 있습니다.(일상공유, 게임 결과 공유)
- 로그인 한 유저는 게시글에 좋아요 누르기, 댓글 달기를 통해 소통할 수 있습니다.
- 좋아요는 취소 가능하고, 댓글은 수정 및 삭제도 할 수 있습니다.
- 로그인 한 유저는 자신이 작성한 게시물을 삭제 또는 수정할 수 있습니다.
- 라운지 내 게시물들은 카드 형태로 되어 있어 페이지 이동보다는 무한스크롤을 사용하여 사용자 경험을 개선하였습다.
- 게시물은 인기순, 최신순으로 정렬해서 확인할 수 있습니다.
- 게시물의 제목, 내용 또는 유저 닉네임 검색을 통해 특정 게시물을 확인할 수 있습니다.
2) 게시글 작성
- 로그인한 유저는 오른쪽 하단 연필 아이콘을 눌러 게시글을 작성할 수 있습니다.
- 제목, 내용은 필수적으로 입력해야 하고 이미지 첨부는 선택적으로 할 수 있습니다.
3) 게시물 수정
- 로그인 한 유저는 자신이 작성한 게시물을 수정할 수 있습니다.
- 제목, 본문, 이미지 삭제 및 추가를 할 수 있습니다.
3._.mp4
1) 모드 선택 및 BGM 설정
- 사용자가 원하는 모드를 선택할 수 있습니다.
- 좌측 하단의 버튼을 눌러 BGM과 함께 즐길 수 있습니다.
- 게임 시작 시 긴박한 BGM으로 전환됩니다.
2) 그림 그리기
- 제시어는 15개의 단어 중 랜덤으로 선택되어 사용자에게 제공됩니다.
- 사용자는 제시어에 맞는 그림을 캔버스에 그립니다.
- 캔버스는 Konva.js 기반으로 구현되어, 선 그리기, 지우개, 색상 선택, 선 굵기 조절, 색 채우기(Fill), Undo 등 다양한 도구를 제공합니다.
3) AI 정답 예측
- 사용자가 그림을 제출하면, 해당 이미지는 Teachable Machine에서 학습한 이미지 분류 모델에 전달됩니다.
- 모델은 가장 유사한 결과를 예측하며, 예측된 단어와 실제 제시어를 비교해 정답 여부를 판단합니다.
- 제출된 그림은 Supabase Storage에 저장됩니다.
4) 반복 진행
- 정답 여부가 표시된 후, 다음 제시어가 다시 랜덤으로 선택되어 그림 그리기 단계가 반복됩니다.
- 전체 게임 시간은 3분으로, 이 시간 동안 사용자는 최대한 많은 제시어에 대해 그림을 그릴 수 있습니다.
5) 결과 화면
- 3분이 지나면 자동으로 결과 화면으로 전환됩니다.
- 결과 화면에서는 사용자가 그린 그림을 슬라이드 형식으로 확인할 수 있으며, 맞힌 개수를 기준으로 점수가 계산됩니다.
- 점수는 game_scores 테이블에 저장되어, 메인 랭킹에 반영됩니다.
3._.mp4
1) 모드 선택 및 BGM 설정
- 사용자가 원하는 모드를 선택할 수 있습니다.
- 좌측 하단의 버튼을 눌러 BGM과 함께 즐길 수 있습니다.
- 게임 시작 시 긴박한 BGM으로 전환됩니다.
2) 방 만들기
- 사용자는 직접 게임방을 만들어 방장이 될 수 있습니다.
- 비밀번호를 설정하여 원하는 사람들만 입장 가능하도록 할 수 있습니다.
3) 대기방 입장
- 다른 사용자가 만들어놓은 게임방에 입장할 수 있습니다.
- 입장 후 채팅을 통해 사용자들끼리 실시간으로 소통할 수 있습니다.
- 모든 사용자가 Ready 상태일 경우, 방장은 Start 버튼을 눌러 게임을 시작할 수 있습니다.
4) 제시어 설정
- 사용자가 원하는 제시어를 직접 설정합니다.
- 한 단어로 간단하게 설정해도 되지만, 구체적이고 길게 작성하면 멀티모드의 재미를 배로 느낄 수 있습니다.
- 제한 시간은 1분입니다. 1분이 넘어가면 자동 저장 후 다음 턴으로 넘어갑니다.
5) 그림 그리기
- 이전 턴에서 다른 사용자가 설정한 제시어를 랜덤으로 받아옵니다.
- 사용자는 제시어에 맞는 그림을 캔버스에 그립니다.
- 캔버스는 Konva.js 기반으로 구현되어, 선 그리기, 지우개, 색상 선택, 선 굵기 조절, 색 채우기(Fill), Undo 등 다양한 도구를 제공합니다.
- 제출된 그림은 Supabase Storage에 저장됩니다.
- 제한 시간은 1분 30초입니다. 1분 30초가 넘어가면 자동 저장 후 다음 턴으로 넘어갑니다.
6) 제시어 예측
- 이전 턴에서 다른 사용자가 그린 그림을 랜덤으로 받아옵니다.
- 그림을 보고 어떤 제시어를 바탕으로 그린 그림일지 예측합니다.
- 제한 시간은 1분입니다. 1분이 넘어가면 자동 저장 후 다음 턴으로 넘어갑니다.
7) 반복 진행
- 그림 그리는 단계와 제시어 예측하는 단계를 번갈아가면서 플레이합니다.
- 전체 턴 수는 인원 수에 따라 결정됩니다.
- 각 턴에서 모든 사용자가 제출 버튼을 누른 상태라면 즉시 다음 턴으로 넘어가고, 그렇지 않으면 타이머가 종료된 순간 자동 저장 후 넘어갑니다.
8) 실시간 채팅
- Supabase Realtime을 활용하여 게임방 ID 기반 채팅 룸이 구성됩니다.
- 게임 대기 화면부터 결과 화면까지 실시간으로 사용자끼리 소통할 수 있습니다.
- 채팅 메시지는 작성자, 전송 시점, 방 정보와 함께 DB에 저장되며, 페이지 이동 시에도 이전 메시지를 다시 불러와 보여줍니다.
- 게임 중 사용자 간 자유로운 소통을 통해 몰입감 있는 플레이가 가능하도록 구성되었습니다.
9) 결과 화면
- 모든 턴이 종료되면 자동으로 결과 화면으로 전환됩니다.
- 처음에 설정한 각 제시어가 모든 턴을 지나면서 어떻게 변화했는지 앨범 형식으로 확인 가능합니다.
- 결과공유 버튼을 통해 마음에 들거나 재밌는 게임 결과를 커뮤니티에 바로 공유할 수 있습니다.
3._.mp4
GPT나 Gemini 등 외부 AI 모델을 활용한 이미지 예측은 응답 속도가 느려 게임 흐름에 방해가 되었다.
이미지 전송과 결과 응답까지 많은 시간이 걸려 실시간 반응이 필요한 게임 특성과 맞지 않았다.
이 문제를 해결하기 위해 Teachable Machine을 사용하여 클라이언트에서 바로 예측 가능한 모델을 학습하고 연동했다.
이를 통해 빠르고 끊김 없는 예측이 가능해져 게임 몰입도가 향상되었다.
Konva.js만으로는 동일한 색상 영역을 채우는 기능 구현이 어려웠다.
Konva는 벡터 기반으로 픽셀 단위 조작이 어렵고, Flood Fill 알고리즘 구현에 적합하지 않았다.
해결을 위해 Canvas API의 getImageData와 putImageData를 활용해 픽셀 단위의 색상 채우기 알고리즘을 구현하고, 이를 Konva와 결합하여 기능을 완성했다.
Konva의 드로잉 기능과 Canvas의 이미지 조작 기능을 병행함으로써 원하는 영역에 정확하게 색을 채울 수 있도록 구현할 수 있었다.
클라이언트의 각 환경마다 다음 턴으로 넘어가는 속도가 조금씩 달라, 먼저 넘어간 사용자가 이전 턴의 데이터를 받지 못하고 진행되는 문제가 있었다.
게임 특성상 이전 턴의 데이터를 받아와야 다음 턴을 진행할 수 있었다.
Supabase의 Realtime 기능을 활용하여 실시간 이벤트 감지 후 해당 조건 성립 시 다 같이 이동하는 방식을 시도해보았지만, Realtime 수신 속도 또한 클라이언트별 차이가 존재했다.
따라서 다음 턴으로 이동 후 데이터를 제대로 받아오지 못한 경우라면 Polling 기법을 통해 재호출함으로써 데이터 수신 오류를 방지할 수 있었다.




