34
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

音ゲーを0から作ろうとしたら健康になれた話

Last updated at Posted at 2024-09-01

こんにちは、Watanabe Jin(@Sicut_study)です。

IMG_3545.JPEG

突然ですが、みなさんは健康でしょうか?
私は今年27歳になったのですが、健康診断が大荒れしています。

IMG_3534.JPEG

4年前に視力が右2.0、左1.8あったのですが、右0.7、左0.5まで落ちてしまいました
このままのペースで進むと10年後には視力が-0.5になってしまいます。

image.png

このままのペースで低下すると2030年には視力が-0.7になってしまいます。
おそらくエンジニアとして毎日パソコンに向かっているのが原因です。

以前、アイトレーニングを1ヶ月1時間やるチャレンジをして努力をすれば視力が上がることがわかっています。
(検証動画を実際に投稿しました)

image.png

アイトレーニングは効果があるのですが、毎日1時間やるのは面白みがなく辛かったです。
そこで思いつきました。
視力検査とリズムゲームを組み合わせたら退屈な視力検査も楽しめるのではないか?

名称未設定のデザイン (4).png

そこで今回は、次回の健康診断で無双するために、健康になるリズムゲームをReactで実装してみたいと思います。

「リズムゲーム」を開発してみよう

IMG_3546.JPEG

まずはネットでReactを使ってリズムゲームを作っている前提を調べました。
調べた感じでは参考になりそうな記事がなかったので、0から設計していきます。

MPV(Minimum Viable Product)を3つに分けて実装していく方針を立てました。

MVP1 : ランドルト環が出現する(矢印キーで判定する)

まずはランドルト環を出現させて、正しい方向の矢印キーを押すとポイントが手に入る基本の部分を実装していきます。

IMG_3537.JPEG

setIntervalを活用して一定時間だけ出現、時間に合わせてサイズを変更するアニメーションをつけました。

  useEffect(() => {
    if (isStarted) {
      const timings = [1000, 5000, 15000]; // 1秒、5秒、15秒で出す
      const timeouts: Array<number> = [];

      timings.forEach((timing) => {
        const timeoutId = setTimeout(() => {
          setCircleSize(0); // 最初は円が見えない
          setIsCircleVisible(true);

          const startTime = performance.now();
          const animationId = requestAnimationFrame(function animate(time) {
            const progress = (time - startTime) / 1000;
            setCircleSize(progress * 100);

            if (progress < 1) {
              requestAnimationFrame(animate); //徐々に円を大きくする
            } else {
              setTimeout(() => {
                setIsCircleVisible(false);
              }, 2000); // 2秒でさいだいになr
            }
          });

          return () => {
            cancelAnimationFrame(animationId);
          };
        }, timing);

        timeouts.push(timeoutId);
      });

      return () => {
        timeouts.forEach((timeoutId) => clearTimeout(timeoutId));
      };
    }
  }, [isStarted]);

スタートボタンを押すと、徐々にランドルト環がでてくるようにできました。

image.png

MVP2 : 音楽に合わせて出現する

MVP1でそれっぽいゲームができたので次は音楽に合わせて出していきます。
今回は「シャイニングスター」という曲を使います。

どのタイミングで出せばいいのかわからないので、ChatGPTに聞いています。

リズムゲームのタイミングを計算するには、曲のテンポ(BPM: Beats Per Minute)を知る必要があります。一般的に、BPMに基づいてリズムゲームのノーツが配置されます。「シャイニングスター」の場合、BPMを測定し、そのBPMに基づいて秒数を計算します。

まずは「シャイニングスター」のBPMを調べ、そこから適切なタイミングを割り出します。少々お待ちください。

「シャイニングスター」のBPMを150と仮定して、1番のリズムゲームのノーツ配置に最適なタイミングを計算しました。以下の秒数に合わせてノーツを配置すると、曲に合ったリズムゲームが作れると思います。

タイミング(秒):

0.0
0.4
0.8

BPMを解析して教えてくれました。ここまでできるのがすごすぎる。
あとはこのリズムに合わせていい感じにランドルト環を表示します。

image.png

視力も選べるようにしたので、その日の気分難易度選ぶことができます。

        <select
          onChange={(e) => setSelectedSize(Number(e.target.value))}
          className="bg-gray-800 text-white p-2 rounded-lg"
        >
          <option value={100}>視力1.0</option>
          <option value={120}>視力0.9</option>
          <option value={140}>視力0.8</option>
          <option value={160}>視力0.7</option>
          <option value={180}>視力0.6</option>
          <option value={200}>視力0.5</option>
          <option value={220}>視力0.4</option>
          <option value={240}>視力0.3</option>
          <option value={260}>視力0.2</option>
          <option value={280}>視力0.1</option>
        </select>

MVP3 : 5ptで豪華演出になる

太鼓の達人の盛り上がった演出を取り入れてみようと思います。

image.png

やり方は簡単です。「5pt手に入ったら背景を映像に変えるだけです」

  return (
    <div
      className="flex flex-col items-center justify-center min-h-screen text-white"
      style={{
        background: backgroundChanged
          ? "none"
          : "linear-gradient(to bottom right, #48c6ef, #6f86d6)",
      }}
    >
      {backgroundChanged && (
        <video
          autoPlay
          loop
          muted
          className="absolute inset-0 object-cover w-full h-full"
        >
          <source src="background.mp4" type="video/mp4" />
        </video>
      )}
      <audio ref={audioRef} src="song.mp3" />
      <div
        className="relative flex items-center justify-center z-10"
        style={{
          width: `${selectedSize}px`,
          height: `${selectedSize}px`,
        }}
      >

実際にどんな演出になっているかは最後の動画をご覧ください!

視力検査に必要なものを用意する

IMG_3541.JPEG

視力検査に必要な道具を作ります
私の家には「黒いスプーンがありません」

image.png

今の御時世、一家に一つはあるほうがよいのですが、今回はなかったので自作します。

IMG_3542.JPEG

サングラスを改造して簡易的なものを作成しました

IMG_3543.JPEG

IMG_3544.JPEG

イメージ通りにできました

ゲームには無線のコントローラーが必要なのですがなかったので、発掘したキーボードを代用します

IMG_3552.JPEG

作成したゲームを遊んでみる

IMG_3547.JPEG

それでは実際にプレイしていきます。
こちらは動画でみていただきたいので、以下をご覧ください!(3:33〜)




IMG_3548.JPEG


 ふう、いい汗をかけた。視力も少し良くなった気がする!
 あとは毎日継続して遊んでいくだけだぞ!!
 ・・・
 あっ

IMG_3551.JPEG

 ゲーム遊んでたら視力悪くなるじゃん・・・

視力検査ゲーム VS 視力トレーニング.png

おわりに

今回はいつもと違ったテイストでお送りしました。
プログラミングを学べば数時間程度で楽しく好きなものを作れますので、ぜひともみなさんも個人開発挑戦してみてください。

今回の記事は動画にもしていますのでよければご覧ください!

ここまで読んでいただけた方はいいねとストックよろしくお願いします。
@Sicut_study をフォローいただけるととてもうれしく思います。

普段はTwitterでエンジニアに関する情報を発信していますのでよければ友達になってください👇

また明日の記事でお会いしましょう!

JISOUのメンバー募集中!

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?

興味のある方は、ぜひホームページからお気軽にご連絡ください!
▼▼▼

34
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?