テトリスを作っています。
テトリス カテゴリーの記事一覧 - スマレジエンジニアyushiのブログ
技術スタックは下記の通りです。
- TypeScript
- React
- SCSS
- Create React App
今回は、揃った行を削除します。
データ構造の修正
最初にデータ構造を修正します。
過去の実装にて盤上ブロックをブロックの状態(4つのタイルで1セット)で保持していたのですが、
タイルが消えた時にブロックの一部だけ(4つの内2つだけなど)が残ることがあります。
そのため、盤上のブロックをタイル単位(1つのマス)で保持するようにします。
export type Tile = { x: number; y: number; type: BlockType; };
座標(x, y)の他、表示時の色指定などのために、ブロック種別(BlockType)を保持します。
その他のロジックは既存のものを少しずつ改修するのみです。
揃った行の削除
揃った行があれば、その行番号を返すロジックを作成します。
行のブロック数と列数が一致していることを判定します。
export const getCompletedRows = ( tiles: Tile[], boardWidth: number ): number[] => { return ( Array.from(new Set(tiles.map(({ y }) => y))) // 行のブロック数 = 列数 .filter((y) => tiles.filter((tile) => tile.y === y).length === boardWidth) ); };
行を削除するロジックです。
同時に、削除した分上の行を下に落とします。
export const deleteRows = (tiles: Tile[], rows: number[]): Tile[] => { return ( tiles // 対象の行の削除 .filter(({ y }) => !rows.includes(y)) // 自身より下の行について、削除した分ブロックを下に落とす .map((tile) => ({ ...tile, y: tile.y - rows.filter((row) => row < tile.y).length, })) ); };
hooksのnextStep関数に組み込みます。
let nextTiles = [...tiles, ...getTiles(fallingBlock)]; const completedRows = getCompletedRows(nextTiles, boardWidth); if (completedRows.length) { nextTiles = deleteRows(nextTiles, completedRows); } setTiles(nextTiles);
Pull Request
あとがき
コロナにかかってとても大変でした。