Oops!!

プログラミングとかのラフなブログ

LINEで遊べるババ抜きを作りました

LINEで遊べるババ抜きを作りました

東海オンエアがババ抜きをやっている動画を参考にして、LINEのグループを利用したババ抜きを作りました。

余談ですが、東海オンエアとは同じ岡崎城西高校出身で城西ネタが出ると嬉しいのでよく見ています。

動画内でゲーム名は言っていなかったと思うので「Reward Joker Game - 報酬ババ抜き」と名付けました。

遊んでみたい方は下記のリンクからお願いします。(実はまだ2人以上でテストしていないのでバグがあるかもしれません)

Reward Joker Game - 報酬ババ抜き

作った動機

ちょうど仕事でLINEのAPIについての相談を受けて調べていました。その流れで仕事で使う前にそれを使って何か作りたいなーと思っていました。

そこにタイミングよく東海オンエアの動画が流れてきたので「あ、これ作れそうだな」と言う事で作りました。

開発期間は1週間弱です。

使用している技術やサービスは以下です。プレイヤー同士の状態を同期するためにFirebase Realtime Databaseを使用しています。

  • TypeScript
  • Next.js
  • LINE Front-end Framework
  • Firebase Realtime Database
  • Vercel

簡単な技術解説

技術的に特別な事をしていませんが、実際に作って行く上で状態を示すパラメータが複数あったり、意外とシンプルじゃないなと思いながら作ってました。

ルーティングをシーンによって切り替える

はじめはシーン毎にNext.jsの<Link>でルーティングをさせていましたが、リロードやページに戻った場合の同期が面倒になりました。 なのでシーンの切り替えは読み込むコンポーネントを切り替えるだけで、URLを切り替えないようにしています。

実際のコードとは違いますが、こんなイメージです。

/* index.tsx */
import { Start } from 'components/Start'
import { Play } from 'components/Play'
import { Result } from 'components/Result'
import { Loading } from 'components/Loading'
import { useScene } from 'hooks/useScene'

export default function Page () {
  const { scene, sceneLoaded } = useScene()

  if (!sceneLoaded) return <Loading />
  if (scene === 0) return <Start />
  if (scene === 1) return <Play />
  if (scene === 2) return <Result />
} 

useSceneはFirebase Realtime Databaseから常に最新のsceneを取得しています。

LINE Front-end Frameworkを使ったログイン

ますLINE Developersへログインして、チャネルを作成します。チャンネルの設定の中にLIFFがあるのでアプリを追加し、ここでアプリ内で開くブラウザのサイズを設定します。今回は画面全体にしたかったのでFullを使用しています。

LINE Developers

import { useEffect, useState } from 'react'

type UserState = { pictureUrl: string, userId: string, displayName: string }

export const useAuth = () => {
  const [room, setRoom] = useState<string>(null)
  const [user, setUser] = useState<UserState>({ userId: null, pictureUrl: null, displayName: null })

  useEffect(() => {
    const mount = async () => {
      const liff = (await import('@line/liff')).default
      await liff.init({ liffId: process.env.liffId })
      if (!liff.isLoggedIn()) {
        liff.login({})
      }
      const profile = await liff.getProfile() as UserState
      setUser(profile)
      const context = liff.getContext()
      setRoom(context.roomId)
    }
    mount()
  }, [])

  return { room, user }
}

Next.jsでliffを使用するとSSR時にエラーが出てしまうので、useEffect内でクライアント側のレンダリング時にimportしています。

カードをシャッフルする

カードのシャッフルはフィッシャー – イェーツのシャッフルというのを参考にしています。

フィッシャー – イェーツのシャッフル

最後に

他にも東海オンエアは面白いゲームを作っているので、また何かの検証などの際に作ってみたいと思います。

そもそも権利の問題はどうなのかというのもあるけど、何か言われるくらいになったら考えます。

プロフィール画像

すずき ゆうた

愛知県でフリーランスのフロントエンド・エンジニアをしています。Reactを用いた開発が得意です。 他にもプロジェクトマネジメントや組織マネジメントも行ってきました。エビデンスのない事でも自分の経験から書いていくので話半分くらいでお願いします。