横にそろったブロックの消去
一列そろったらブロック消去する処理を実装します。これがないとテトリスにならないですね。
まず呼び出し側を見てみます。MainPanelのゲームループrun()です。
/** * ゲームループ */ public void run() { while (true) { // ブロックを下方向へ移動する boolean isFixed = block.move(Block.DOWN); if (isFixed) { // ブロックが固定されたら // 次のブロックをランダムに作成 nextBlock = createBlock(field); block = nextBlock; } // ブロックがそろった行を消す field.deleteLine(); repaint(); ・・・ } }
ブロックを固定した後に、ブロックがそろった行を消す処理deleteLine()が入っています。ブロック消せようが消せまいが一応呼び出しています。消せるかどうかの判定はdeleteLine()に入ってます。では核心のdeleteLine()です。
/** * ブロックがそろった行を消去 */ public void deleteLine() { for (int y = 0; y < ROW - 1; y++) { int count = 0; for (int x = 1; x < COL - 1; x++) { // ブロックがある列の数を数える if (field[y][x] == 1) count++; } // そろった行が見つかった! if (count == Field.COL - 2) { // その行を消去 for (int x = 1; x < COL - 1; x++) { field[y][x] = 0; } // それより上の行を落とす for (int ty = y; ty > 0; ty--) { for (int tx = 1; tx < COL - 1; tx++) { field[ty][tx] = field[ty - 1][tx]; } } } } }
結構シンプルですよね?ポイントは、
- 上から順に1行ずつ調べていく
- 1行のブロックがあるマスの数を数える
- もし埋まっていたらその行のブロックを削除する
- その行より上にあるブロックを一段下にずらす
なぜ上から調べていったかは忘れてしまいました・・・テトリスはぷよぷよと違って連鎖消去がないため下から調べていっても別によさそうです。下からだと一段下にずらす処理が多そうだったからやめたのだったかな。
今は一瞬で消えて、下にずらすのも一瞬ですが、エフェクトやアニメーションを入れたいですね。