スマレジエンジニアyushiのブログ

スマレジエンジニアのブログ

【テトリス #12】GameOver画面(2)

テトリスの続きを作っています。

テトリス カテゴリーの記事一覧 - スマレジエンジニアyushiのブログ

技術スタックは下記の通りです。

  • TypeScript
  • React
  • SCSS
  • Create React App

今回は、前回作ったGameOver画面のロジック作成や、Memo化をしていきます。

ロジック

GameOverの判定をし、isGameOveredに反映します。   isGameOveredがtrueになると、親コンポーネントでGameOver画面を表示します。 ブロックが停止したとき、積み上がったタイルの高さがボードの高さ以上なら、GameOverとして判定されます。 

const useBlocks = () => {
  const [isGameOvered, setIsGameOvered] = useState(false); 

  const nextStep = () => {
    // 

    if (
      movedBlock !== null &&
      Math.max(...tiles.map(({ y }) => y)) >= boardHeight
    ) {
      setIsGameOvered(true);
    }
  }

  return {
    // 
    isGameOvered,
    //
  }
}

Memo化

Memo化を行います。
Reactでは変数更新によるComponentの更新時に、波及して子コンポーネントが再Renderされます。
実際のところ、影響の受けない部分の再Renderは不要であり、不要なコストがかかってしまいます。

これを避ける仕組みがMemo化です。

react.dev

Memo化では対象の記述が依存する変数を宣言しておくことで、それ以外の変数の更新時には再Renderしないようにする仕組みです。

下記のように書き換えを行いました。

function GameOver() {
  const text = useMemo(
    () =>
      ['GAME', 'OVER']
        .map((item, index1) =>
          item
            .split('')
            .map((t, index2) => <span key={index1 * 100 + index2}>{t}</span>)
        )
        .reduce(
          (prev, cur, index) =>
            (prev.length > 0
              ? [...prev, <br key={10000 + index} />]
              : []
            ).concat([...cur]),
          []
        ),
    []
  );

  return (
    <div className="GameOver">
      <div className="title-text">{text}</div>
    </div>
  );
}

第2引数には依存する変数を記述するのですが、今回は依存対象がないため空配列となります。

Pull Request

github.com

まとめ

GameOver機能がついたことで、ついにゲームとして成立した感じがします。

Memo化は全体的に実施していきたいですし、機能も引き続き追加していきたいです。