HOME > ActionScript > テトリスアルゴリズム > システム その2

システム その2

自動落下処理

フィールドに配置したテトリミノを自動的へ落とす機能を追加します。
機能追加と言いましても単に落下させるだけならキーイベントの矢印下方向に割り当てている処理をタイマーオブジェクトで一定時間ごとに実行すれば完了です。
今回はそれに加えて、少しずつ落下速度が早まったり、回復したりする処理も一緒に追加します。

ソースファイル pt9.zip

タイマーオブジェクト

繰り返しを止める

冒頭でも言いましたが、落下させるだけならタイマーオブジェクトのリスナー関数に一行記述しておしまいです(main.asファイル 383行目)。

ですがここで一つ重要なポイントがあります。
それは下に一つ移動する処理を一回実行する度にタイマーを止めると言う事です(main.asファイル 553行目)。
繰り返すのに一回一回止めると言うのは何か矛盾しているように聞こえますが、これを行わないと動作にちょっと違和感が出てきます。

と言いますのも、テトリミノを下へ移動する処理はタイマーオブジェクトで繰り返し行う自動落下と、キー操作で行う下移動の2種類があり、これらは別々に処理を実行します。と言う事は、タイミング的にはこれらの実行が重なる場合があるのです。

具体的に言いますと、テトリミノを下へ一つ移動させようと下キーを一回押したはずが、自動落下の処理と重なってしまい、コンッコンッと下へ二つ移動してしまう状況が出来てしまうと言う事です。処理的にエラーが返るわけでもないのですが、操作感としてちょっと小気味よくないです。
で、これに対する対処方法が、テトリミノの下方向への移動処理を実行した時点でタイマーオブジェクトを一度止め、処理が終わった後に再スタートするというものです。

repeatCountとcurrentCount

一回一回止めるのが重要であるならば、タイマーオブジェクトをインスタンス化する時の引数でrepeatCountプロパティを1回で指定して実行すれば確実に一回で停止します。

var myTimer:Timer = new Timer(delay, 1);

ただしこの方法の場合は注意が必要な事が一つあります。repeatCountを1で指定し、一回だけ実行して止まったタイマーをそのまま再びstart()で起動しようとしても動作しません。仮にstop()を実行してからstart()を実行しても同じです。

これは繰り返し回数をカウントしているcurrentCountプロパティの値がrepeatCountの値に達しているからで、この状態の場合は単にstart()メソッドを実行して起動しようとも動きません。
なのでrepeatCountを1で指定した場合は都度reset()を実行してcurrentCountプロパティを0に初期化してからstart()を行う必要があります。
repeatCountを無限大で動作させている場合と、どちらも手間は変わりませんので好みで選択して良いですが、内部的な動作はちょっと違ったりしますので注意が必要です。

落下速度の加速

速度とは

では自動落下を加速する処理を追加する考え方です。今回は単純に、フィールドにテトリミノが一つ固定される度に落下速度が上がるようにします。
一つ明確にしておきたい事は以下の事です。

「自動落下の速度 = dropTimerのdeleyプロパティの値」

dropTimerは今回自動落下機能に使用しているタイマーオブジェクトです。テトリミノの落下速度はタイマーオブジェクトのdeleyプロパティの値が大きくなるとゆっくりになり、小さくなると速くなるという関係にあります。わかっていれば当たり前の事なのですがこの後の説明で混乱が起きないように明確にしておきます。
あと、速さとか速度とかごっちゃに言ってしまうかもしれませんがベクトルじゃないのでそこは大目に見て下さい。

加速度

加速させるとはタイマーオブジェクトのdeleyプロパティの値を少しずつ減らしていくことです。この時の減らす量をここでは「加速度」と呼ぶ事にします。この加速度が大きいとdeleyプロパティの値が大きく減る為一気に速くなります。小さいと、少しずつ減るので緩やかに速くなります。

今回はdropAccelと言うグローバル変数に加速度の値を保存し、落下速度の調節はdeleyプロパティとdropAccelの二つの値で調整していきます。dropAccelの値は固定したテトリミノの数をカウントして増加させます。要するにたくさん積まさる程、加速度の値が大きくなるので落下速度の速まり方も速くなってきます。

速度調整の処理はdropTimerRegulator()関数(main.asファイル 388行目)の中で行っています。この関数を実行して速度の変更を行うタイミングはテトリミノを固定した直後に毎回実行します(main.asファイル 559行目)。

落下速度の減速

速度の回復措置

加速するだけだと厳しいので減速する処理も追加します。減速の処理が起きるのはテトリミノをテトリス(4ライン)で消した時です。この時にその時点での落下速度を遅く、加速度を減少させます。
減速の処理を行うのも加速の時と同じくdropTimerRegulator()関数ですが、減速が発生するのはテトリスで消した時ですので加速を行う場合とは実行するポイントが違います(main.asファイル 585行目)。

加速も減速もそれぞれ定数で上限と下限を決め、「それ以上速くならない」「それ以上遅くならない」ようにしています。
定数の値を変え足りすると加減速の具合が変わりますし、dropTimerRegulator()関数を少し変更しても結構変わりますので試してみてください。

今回は大雑把なプロセスで速度の変動処理を追加しましたが、スコアやレベルなどの色々な要素や状況を絡めてもう少し細かい変動処理を加えるともっと押し迫るような演出も出来るようになります。

動作確認

動かない時はFlash画面上を一度クリックしてみてください。
最初は余裕ですが、速くなりだすと結構厳し目です。
次回の「次のテトリミノ」を表示する機能を追加すると楽勝なんですけどね。

例によってソースコードは前回までの部分もちょこちょこと変更していますが、今回はバグを二つ見つけたのでその修正も含まれます(大枠の部分は変わっていません)。
バグは「回転の補正」処理部分と、固定フィールドより上のセル(新しいテトリミノを配置する位置辺り)に固定されたテトリミノがあった場合に、ラインが揃ってもその部分は下へ落ちずに残ってしまうと言うしょうもないバグです。

Flashファイルをご覧いただくためには、
アドビシステム株式会社のフラッシュプレーヤー(Flash Player)が必要です。
インストールされていない方は下のボタンから、最新版が無償で入手できます。

Adobe Flash Playerのダウンロード

ソースファイルについて

ソースファイルはasファイルのみです。

使用する環境としてはFlashIDE(動作確認はSC4のみ)を想定していますので。適当に用意したflaファイルに、ダウンロードしたソースファイルをドキュメントクラスとして適切に設定すれば問題無く動作します。
また、コーディングはFlashDevelopを使用して行っておりますので、プロジェクト内にファイルを適切に配置、もしくはクラスパスを設定するなどすればFlashDevelopだけでも問題なく動作します。Stageサイズは幅、高さともに500pxです。
申し訳ありませんが、ご質問等にはお答えできませんので、ご使用は環境に合わせて各自行ってください。

TOP