HOME > ActionScript > テトリスアルゴリズム > ラインを消す
フィールドに固定できるようになったので、今度は揃ったラインを消す機能を追加します。
これでやっとテトリスと言っていい動作になりますが、まだゲームオーバー処理などシステム的な処理を付けていないのでゲームとしては成り立ちません。
今回ラインを消す処理を追加するために考える主なことは次のようなことです。
大雑把ですみません。
ラインが揃っているかどうかを調べる方法を考えます。
ラインが揃うとはつまり、フィールドデータ配列の二次元目の配列要素に「EMPTY(0)」が一つもない事を意味します。
そう考えるとこれを調べる方法は非常に簡単で、そのままその状態かどうかを評価すれば良いわけです。
この「ラインが揃っているかどうかを調べる」処理は、今回追加したlineChecker()関数(main.asファイル 722行目)で行います。この関数はフィールドデータ上で揃っているラインを検出すると、その行数(フィールドデータ配列の一次元目のインデックス)情報を配列で返してきます。
後はいつものように、その情報を基にしてフィールドデータを更新→再描画という流れになります。
処理自体はフィールドデータ配列を走査して探索をかけるだけですので全然難しい事はありません。
ですが常にフィールドデータ配列全部の要素を走査する必要があるわけではありません。一般的なテトリスの仕様を考えますと、空白のライン(テトリミノが全く固定されていないライン)があった場合、それより上のラインにはもう絶対にテトリミノは存在しないのです。存在しない状況がある事がわかっているなら、これを検出してそこで処理を終わらせたいのが心情です。
その為、ラインが揃っているかどうかを調べる評価の他に「ラインが完全な空白行かどうか」を調べて処理を中断するロジックを用意しておきます。
フィールドの下(フィールドデータ配列の一次元目の末尾)から探索を開始し、「ラインが揃っていない」と言う事が検出出来た場合には続いて「完全な空白行か」を調べる処理を行うと言うプロセスです。
コードを見て貰うとわかるのですが、ラインが揃っていないとわかった後に再度そのラインを「完全な空白行か」を調べるので2回探索を行います(main.asファイル 737行目と745行目)。ちょっと無駄な気もしますが、「ラインが揃っているかどうか」と「完全な空白行か」の評価を同時に行おうとすると、非常にわかりづらくなる為、敢えて2回の評価を別に行う形をとっています。
ラインが揃っているかどうかを調べる事が出来るようになったので、後はそれを基にフィールドデータを更新して行くだけなのですが、その前にlineChecker()関数を実行するタイミングについてです。
調べるタイミングは「テトリミノが固定」された時です。これはテトリミノが固定される度に、毎回チェックを行います。逆に言いますと、その時以外は調べる必要がないです。
今回の機能を追加するに当たりtetriminoControl()メソッドを変更しています(main.asファイル 313行目)。下へ移動する場合の処理ブロックにラインをチェックして、その戻り値によって処理を分岐するようにしています(main.asファイル 359行目~396行目)
ラインを消すと言う事はフィールドデータ配列の二次元目の配列の値を全てEMPTY(0)にするか、その二次元目の配列そのものを削除してしまう事です。
どちらの方法で再現するにしてもただ値を変更したり、配列を削除しても意味がありません。テトリスと言うゲームはラインが消えたらその上に積まれているテトリミノが下へ落ちるものだからです。
これをデータ的に考えますと、揃っていたラインの要素の値を全てEMPTYにした場合は、それより先頭方向にある要素の値を順じ後ろへ移行していく必要があります。配列そのものを削除した場合は一番先頭に空のフィールド情報を持った配列を新しく加えてやる必要があります。
どちらの方法でも良いのですが、私は後者の配列そのものを削除して新しい空のフィールド情報を持った配列を先頭に追加する方法で「ラインを消して詰める」というデータの移行処理を再現しています。
ラインを消して詰める処理の理屈は単純なのですが、一つ重要な事があります。
単に「ラインを消す」「ラインを詰める」の処理を配列データの操作だけで終了してしまうと、実際のゲームの表示上ではそのプロセスが何にも解りません。
「なんかラインが減った」という描画が行われるわけで、つまらないのです。
重要な事とはラインを詰める前にラインを消した状態を一瞬だけ描画する事です。
テトリミノが動かない時はFlash画面上を一度クリックしてみてください。
ラインが消えることによって動作だけはテトリスっぽいです。
極端な言い方をしますと、ここまで以外の処理はおまけみたいなものです。極端すぎてすみません。
定数のFILL_RAG(main.asファイル 36行目)は、ラインが揃ってから消えるまでの一瞬の時間差のディレイタイム値です。値を0にすると全く時間差なしでラインが消えますので、どんな感じになるのか興味がある場合は値を変更してみてください。
ソースファイルはasファイルのみです。
使用する環境としてはFlashIDE(動作確認はSC4のみ)を想定していますので。適当に用意したflaファイルに、ダウンロードしたソースファイルをドキュメントクラスとして適切に設定すれば問題無く動作します。
また、コーディングはFlashDevelopを使用して行っておりますので、プロジェクト内にファイルを適切に配置、もしくはクラスパスを設定するなどすればFlashDevelopだけでも問題なく動作します。Stageサイズは幅、高さともに500pxです。
申し訳ありませんが、ご質問等にはお答えできませんので、ご使用は環境に合わせて各自行ってください。