React

“React는 게임엔 안 맞다.” 그래서 만들어봤습니다.

인어공쭈 2025. 11. 12. 18:06

React로 만든 “하리니 오락실” 제작 썰

“아니, 프론트 개발자가 오락실을 만든다고?”
네, React로요. 그리고 또 1등했습니다. 😏

 

하리니 오락실의 정체

하리니 오락실은 영끌 앱 안의 미니게임 센터예요.
“앱 안에 오락실이 있다고요?”
네, 광고도 노출하고, 포인트도 쓰고,
유저도 붙잡는 일석삼조 프로젝트입니다.

목표 요약하면 이렇습니다 👇

  • 리텐션 확보 — “하리니 보러 매일 출근각”
  • 광고 구좌 확보 — “죽었을 때 광고 보면 부활 (상술의 미학)”
  • 포인트 소진 — “이왕이면 즐겁게 소비하게 하자”
  • 체류시간 확보 — “유저가 앱에서 못 나가게 하자 😈”

PM님이 한 줄로 정리했습니다.
“유저의 시간을 뺏자. 착하게.”

 

🎮 게임 두 개, 미친듯이 단순하게

 

React로 FPS 떨어지는 순간, 그건 게임이 아니라 슬라이드쇼입니다.
그래서 단순함 + 몰입감 + 중독성 이 세 가지를 목표로 했어요.

1) 바구니 캐치 (Basket Catch)

하늘에서 과일이 떨어집니다.
유저는 바구니를 좌우로 흔듭니다.
그리고… 폭탄도 떨어집니다. 💣

  • 사과 🍎: +100점
  • 오렌지 🍊: +80점
  • 폭탄 💣: -1 생명
  • 불 🔥: 속도 미쳤음 (벌받음)

 

게임이 단순하다고요?
근데 3판만 하면 알 거예요.
이게 왜 멈출 수 없는지.

 

2) 하리니 쌓기 (Harini Stack)

블록이 좌우로 왔다갔다,
클릭하면 “착”하고 쌓입니다.
살짝만 삐끗하면 “짤림” 😭

Perfect Stack을 성공하면
하리니가 “헤헤~ 잘했어” 하는데,
그 순간 도파민이 쏟아집니다.

“이거 React로 만들었다는 게 말이 되냐고요”
→ 됩니다. 커서와 함께라면..ㅋㅋ

 

 

Canvas와 React, 그 위험한 동거

React는 화면 리렌더링을 사랑하고,
Canvas는 그걸 극도로 싫어합니다.

결국 이렇게 결론 내렸죠:

“React야, 넌 UI만 해. Canvas는 내가 그릴게.”

export class GameEngine {
  update(dt) {
    this.updatePlayer(dt);
    this.updateItems(dt);
  }

  render() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    this.renderPlayer();
    this.renderItems();
  }
}

 

하루 10판 제한 시스템

유저들이 미친 듯이 플레이하면
서버비도, 정신도 타들어가요.

그래서 하루 10판만 가능하게 했습니다.

Zustand + localStorage로 간단하게 구현했는데,
이게 또 은근히 UX에 영향을 줘요.

10판 끝나면 하리니가 나와서 말하죠.

“이봐요, 쉬었다 하죠 ☕ (친구 초대하면 한 판 더!)”

→ 사람들은 안 쉽습니다.

 

랭킹 시스템: 사람의 경쟁심은 무료가 아닙니다

하루 종일 게임하다가 랭킹창 눌러보면
“내 점수 2등이네?”
→ 5분 후 1등 빼앗김
→ 10분 후 다시 접속

Retention 확보 성공 👏

Prisma ORM으로 groupBy 쿼리 날리며,
“이게 진짜 DB에서 되는구나” 감탄했습니다.

const rankings = await prisma.score.groupBy({
  by: ["userId"],
  _max: { score: true },
  orderBy: { _max: { score: "desc" } },
  take: 50,
});

 

랭킹이 실시간으로 오를 때,
그게 진짜 하리니 오락실의 dopamine trigger입니다.

 

버그는 게임의 일부였다

  • 아이템이 너무 많이 떨어져서 FPS 20 → Object Pooling 도입
  • 모바일 터치가 300ms 느림 → passive: false

 

반응형 & 터치 대응

Canvas 크기 조정은 지옥이었습니다.
기기마다 픽셀 비율이 달라서
“하리니 머리가 길어졌다 짧아졌다” 반복 😇

결국 devicePixelRatio 기반으로 정규화.
지금은 모든 기기에서
하리니가 일정합니다. (감격)

 

결과: 또 1등 했다

“부틀리 게임센터 1등 발표합니다.”


프로젝트: 하리니 오락실

👏👏👏

 

반응형

'React' 카테고리의 다른 글

React - 리엑트의 랜더링 과정  (1) 2024.05.11
React - 상태관리 (Zustand 그외 Redux...)  (0) 2023.05.23