2次元の擬似配列をあやつる!
ピースクリップに対応する変数
前回、ステージクリップに、図1のようにインスタンス名を付けてピースクリップを配置したが、次に、各ピースクリップに対応する変数を用意し、この変数に、各ピースクリップが表示するピースが置かれたフレーム番号を格納する。この変数とピースクリップを関連付けるために擬似配列を用いる。これは、以前のレクチャーでカードゲーム(神経衰弱)を作る時に、各カードのスーツ及びナンバーを示すフレーム番号を管理した方法と同じ手法だ。ただし、15パズルのピースは、縦横2次元に動くため、管理方法は、もう少し複雑になる。擬似配列も2次元で考える必要が出て来る訳だ。
各ピースクリップと表示するピースが置かれたフレーム番号を保持する変数の対応をまとめると表1のようになる。下2桁の数字で対応を表していることが、見て取れると思う。この下2桁の数字1桁ずつが、2次元配列の縦横のインデックスを表している。
表1 ピースクリップの各インスタンスとその制御のための変数の対応
インスタンス名 | 対応する変数名 | 設定する初期値 |
p00 | v00 | 1 |
p01 | v01 | 2 |
p02 | v02 | 3 |
p03 | v03 | 4 |
p10 | v10 | 5 |
p11 | v11 | 6 |
p12 | v12 | 7 |
p13 | v13 | 8 |
p20 | v20 | 9 |
p21 | v21 | 10 |
p22 | v22 | 11 |
p23 | v23 | 12 |
p30 | v30 | 13 |
p31 | v31 | 14 |
p32 | v32 | 15 |
p33 | v33 | 16 |
この対応付けは、メインとなるFlashムービー(以下、シーン1)の2フレーム目のフレームアクションによって、次のように行なう。
リスト1のように2重のfor文で変数iおよびjをそれぞれ0,1,2,3と変化させて、add演算子によって文字列 "/:v" として連結し変数名とする。これにset関数を使って初期値をセットし、同様に文字列 "stage/p" にi,jを連結してインスタンス名とする。こうして名前の下2桁で対応するピースクリップと変数の組ができる。ここでピースクリップの表示フレームを対応する変数の値で設定すると、図3のように一枚の完成画のようにピースが並ぶことになる。
実際のゲームではここで操作ガイドを表示し、5キーの押下を待って16番目のピースを一枚抜いて空きを作り、シャッフルした上で、ゲーム開始となる。
16番目のピースを一枚抜く
16番目のピースを抜く処理は、シーン1の3フレーム目に置いたボタンのオブジェクトアクションとして記述する(ここでは、ピースのシャッフル処理も行なっているが、それについては後で説明する)。
ピースを抜いた所は、本来は空きとなるが、実際にはピースクリップの17フレーム目に置いた黒(空き)のイメージと置き換える。
変数i_17とj_17は、現在黒(空き)のイメージが表示フレームとなっているピース位置の縦横のインデックス(0~3)を保持する。ここに16番目のピース位置(3,3)を記録し、変数v33に17をセットする。このため、ピースp33の表示フレームは17フレーム目となり、空きフレームとなる。
ピースを移動させる
シャッフル後、シーン1の4~6フレームでループを作る。このループがゲームのメインループとなる。ピースを移動するためのキー入力は、このループ内に置いたボタンのオブジェクトアクションとして記述し、リスト3のようになる(リスト3は、2キーが押下された場合のスクリプト例であるが、4キー、6キー、8キーの押下時も同様なスクリプトとなる。それぞれの詳細は、実際のflaを参照されたい)。
2キーが押下された時、空きピースの下にあるピースを上方にスライドさせる。これは先にも記したように空きピースも実はピースクリップの17フレーム目を表示しているピースであるため、実際には上下の表示ピースの交換という形を取る。
ここで、処理の最後にcheckStageというサブルーチンをcallしているが、これはスライドの結果すべてのピースが定位置に揃ったか否か(すなわち"パズルの完成")を判定するための関数である。
すべてのピースが揃ったか確認する
すべてのピースが揃ったか否かの判定は、シーン1の9フレーム目に設定したフレームアクションによって判定する。このフレームは、checkStageというラベルが設定されており、他のフレームやオブジェクトのアクションからcall命令により呼び出すことにより、サブルーチンとして機能する。
戻り値としての変数checkStsにあらかじめ"1(=すべて一致)"をセットしておき、2重のfor文によって変数v00~v33の値を確認する。空きピースのセル以外に初期値と異なる値が発見された場合、checkStsを"0(=不一致あり)"にリセットする。サブルーチンを抜けるまで、checkStsが1のままなら、パズルは完成されているという訳だ。
ピースをシャッフルする
14、15番目のピースの入れ替わりを防止しつつシャッフルする
最後に、先送りにしておいたピースのシャッフルを説明しよう。リスト5を見ればわかる通り、ピースのシャッフルは適当な回数(ここでは200回)、ランダム(乱数)にピースの移動を行ない、それによってシャッフルを実現している。
こんなことをしなくても、以前カードゲーム(神経衰弱)でやったようにランダムで2つのピースを選び出し交換するという事を繰り返せば良さそうに思うかも知れない。ただ、残念ながら、今回はそう簡単な方法でシャッフルすることはできない。なぜなら、「14-15問題」があるからだ。前回説明したように、15パズルは、14番目と15番目のピースのみを入れ替えた場合、決して解くことができない。この問題に陥らないために、実際にピース(と対応する変数の値)をスライドさせながら、パズルをシャッフルさせているのである。