DSのマリオ６４のミニゲームぽいやつ

## お詫び

今、完成 & 書き上げたので何も文章を考えていないです。

今の時刻: ![Screen Shot 2023-12-24 at 23.56.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89256/f87cd4de-2d54-adf7-f7b9-202d7a579305.png)

## はじめに

[クソアプリカレンダー](https://qiita.com/advent-calendar/2023/kuso-app) 24日目を担当します。今年が 6回目の参加です。

これまでに作ったものはこのようなものです。

https://qiita.com/sadnessOjisan/items/45d2c3e6e3f5a38a7f0b

https://qiita.com/sadnessOjisan/items/98619eaaef1da8d6545a

https://qiita.com/sadnessOjisan/items/51bb949466fdd065a5a6

https://qiita.com/sadnessOjisan/items/8399f41b475fe3f61618

https://qiita.com/sadnessOjisan/items/1d164c65034bb8b5f02c

毎年参加しているからこのセクションがだんだん賑わってくる。

## 何を作ったのか

DSのマリオ６４のミニゲームぽいやつ です

クソアプリ名は...好きなサービスです！

## 成果物

https://find-y.web.app

## DSのマリオ６４のミニゲームとは

<iframe width="560" height="315" src="https://www.youtube.com/embed/SSBpEqQ5n4o?si=lfaLKal6GtS5frp4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

## きっかけ１

めちゃくちゃ強い人の動画が流れてきた。

https://youtube.com/shorts/KsoKLUpYXyY?si=tewOayjiR6J7Z8Ae

## きっかけ２

findy のスコアの話でこのまえTLが賑わっていた（何かのイベントきっかけぽい）。
そのとき、ここにエイプリルフール企画で何か連携できるようなものを作れば、findy に声をかけてもらえるのではと思い立つ。

![Screen Shot 2023-12-25 at 0.03.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89256/35a50d49-b692-5f12-ceda-d9c5c13adabb.png)

ということで、Findyから連携できるサービスと、そのサービスが提供する認証認可プロバイダーを作ろうとした。find-y のIDを連携させることでスコア連携させるという仕組みだ。元々、自作の認証認可プロバイダには興味があった。が、やってみようとしたところ、そもそもスコアの改竄という不正にどうしても対処できなくて諦めた。何か良い方法はないだろうか。

## 技術的な解説

ふつ〜〜〜〜の React + Vite + TS のクライアントサイドレンダリング。静的な JS/HTML を firebase app にデプロイ。

特筆することがあるとすれば、sin/cos を使っていること + style タグと classname でスタイリングしていること。

```jsx
import { FC, ReactNode } from "react";

export const CSSAnimationRightLeftBlock: FC<{
  children: ReactNode;
  idx: number;
}> = ({ children, idx }) => {
  return (
    <div className={`block-${idx}`}>
      <style>{`
          .block-${idx} {
            position: absolute;
            left: ${Math.random() * 800}px;
            top: ${Math.random() * 400 + 100}px;
            font-size: 32px;
            animation: animate 3s 0s infinite linear;
        }
        @keyframes animate {
            0% {
                transform: translateY(calc(sin(0deg) * 150px)) translateX(calc(cos(0deg) * 50px));
            }
            50% {
                transform: translateY(calc(sin(0deg) * 150px)) translateX(calc(cos(180deg) * 50px));
            }
            100% {
                transform: translateY(calc(sin(0deg) * 150px)) translateX(calc(cos(360deg) * 50px));
            }
        }
      `}</style>
      {children}
    </div>
  );
};
```

CSSライブラリ探す時間が無かったのと keyframe が欲しかったのでこうした。`@scope` を使えば style の衝突も避けられるとの期待だが、うまくいなかなかったので繰り返し要素のスタイリングは idx を渡して classname をいじっている。

本家ミニゲームは周期性を持ったアニメーションがあったので、この実装は苦労した。JS と setTimeout だとカクカクした動きになることに気づいて、この解決に悩んだ。その時 [Marqueeタグに詳しくないと攻略できないブロック崩しゲーム](https://qiita.com/sadnessOjisan/items/51bb949466fdd065a5a6) の経験から、滑らかな動きを実現する方法としての marquee を思い出したが、 marquee がとる範囲が多くて要素が重なってクリックイベントを検出するのが難しかったのと、marquee に対する JSX（TS?)のLSPサポートが切れていて開発体験が最悪だったので撤退。そのとき sin/cos が Chrome でも使えるようになったことになったことを思い出したので試してみたけど、学生時代に数学をサボったせいで、三角関数をうまく使いこなせない。三角関数を使えば周期性を実現できるってのは、ツイッターのレスバで学んだ（学校の勉強は役に立つのか立たないのかみたいなやつ）。実質半日での開発だったのでこの辺りの調査が足りていないので、冬休みゆっくり調べることにします。