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

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

【テトリス #3】ブロックを落とす

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

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

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

  • TypeScript
  • React
  • SCSS
  • Create React App

今回は、ブロックを上から下に落とすロジックを作っていきます。

ブロック形状情報の修正

ブロック形状情報に、centerを追加します。
これは今後の回転操作にも使用しますが、今回は新しいブロックの 生成時の位置の決定に利用します。

# before
i: [
  [0, 0],
  [1, 0],
  [2, 0],
  [3, 0],
],
...

# after
i: {
  tiles: [
    [0, 0],
    [1, 0],
    [2, 0],
    [3, 0],
  ],
  center: [1.5, 0.5],
},
...

ブロックを落とす処理の実装

ブロックを落とす処理を実装します。

現在のブロックの位置を元に、1つ下の段に落とすか、ブロックが既に最下段にいる場合は次のブロックを返します。

なお、既に積まれているブロックに対応する処理は、今後実装します。

export const getNextBlock = (
  fallingBlock: Block | null,
  boardWidth: number,
  boardHeight: number
): Block | null => {
  if (fallingBlock === null) {
    // 新しいブロックを作成する.
    const type = BLOCK_TYPES[Math.floor(BLOCK_TYPES.length * Math.random())];
    return {
      x: Math.floor(boardWidth / 2 - 0.5 - BLOCK_SHAPES[type].center[0]),
      y: boardHeight - 1,
      type,
    };
  }

  if (fallingBlock.y === 0) {
    // TODO: 既存のブロックに接したことを判定する.
    return null;
  }

  // ブロックを一段下に落とす.
  return {
    ...fallingBlock,
    y: fallingBlock.y - 1,
  };
};

イベント処理

react hooksでは、useEffectにてイベント処理を行います。

今回は、いずれかのキーを押したときに、登録したnextStepを呼び出します。
なお、今後の実装では、キー操作ではなく一定時間ごとに呼び出されるように修正します。

  useEffect(() => {
    window.addEventListener('keydown', nextStep);

    return () => {
      window.removeEventListener('keydown', nextStep);
    };
  });

完成

以上までで、キー操作ごとにブロックが下に落ちるようになりました。

画像の中央あたりの緑のブロックが、今回作成した落ちている途中のブロックです。

Pull Request

https://github.com/nek0meshi/tetris/pull/8

あとがき

一歩一歩着実に機能を実装しています。

ところで、最近はブログサイトの自作を計画中です。