魔法の呪文!? FlashLite1.xのActionScriptの底力を知ろう!

擬似配列を使ったデータ上のシャッフル
複数のオブジェクトやデータを一様に扱いたい場合、
今回作成する"神経衰弱ゲーム"の場合、
(1)擬似配列の作り方
いきなり”
例えば、
- 実際のflaファイルGameCard.
fla (Flash CS3用のもの、 Flash 8用のもの)

ご覧いただけば分かるように各カードクリップは、
(2)各カードのマークやナンバーを保持する変数
前回の復習になるがカードクリップは、
(3)シャッフルさせるスクリプト
ゲームクリップの1フレーム目にカードをシャッフルさせるスクリプトを記述する。もっともカードそのものをシャッフルさせる必要はない。CardVal0~CardVal7に設定するフレーム番号をシャッフルさせるだけで良いのだ。

ここに記述するスクリプトは次のようなものだ。
//0~12の数列を作る・・・・・・①
for(i=0;i<13;i++){
set("Number" add i, i);
}
//適当に交換して、乱数列を作る(頭4つを利用)・・・・・・②
for(i=0;i<13;i++){
idx1 = Random( 13);
idx2 = Random( 13);
temp = Eval("Number" add idx1);
set("Number" add idx1,Eval("Number" add idx2));
set("Number" add idx2,temp);
}
//場に並ぶカードの決定・・・・・・③
for(i=0;i<4;i++){
j=i+4;
switch(Random( 6)){
case 0: //スーツ(ダイヤ×クローバ)
set("CardVal" add i,Eval("Number" add i)+2);
set("CardVal" add j,Eval("Number" add i)+15);
break;
case 1: //スーツ(ダイヤ×ハート)
set("CardVal" add i,Eval("Number" add i)+2);
set("CardVal" add j,Eval("Number" add i)+28);
break;
case 2: //スーツ(ダイヤ×スペード)
set("CardVal" add i,Eval("Number" add i)+2);
set("CardVal" add j,Eval("Number" add i)+41);
break;
case 3: //スーツ(クローバ×ハート)
set("CardVal" add i,Eval("Number" add i)+15);
set("CardVal" add j,Eval("Number" add i)+28);
break;
case 4: //スーツ(クローバ×スペード)
set("CardVal" add i,Eval("Number" add i)+15);
set("CardVal" add j,Eval("Number" add i)+41);
break;
case 5: //スーツ(ハート×スペード)
set("CardVal" add i,Eval("Number" add i)+28);
set("CardVal" add j,Eval("Number" add i)+41);
break;
}
//カードロック状態を未ロックにする・・・・・・④
set("CardLook" add i, 0);
set("CardLook" add j, 0);
}
//場に並ぶカードを切る・・・・・・⑤
for(i=0;i<20;i++){
idx1 = Random( 8);
idx2 = Random( 8);
temp = Eval("CardVal" add idx1);
set("CardVal" add idx1,Eval("CardVal" add idx2));
set("CardVal" add idx2,temp);
}
//各種フラグの初期化・・・・・・⑥
selectCard1 = -1; //1枚目にめくったカードのインデックス
selectCard2 = -1; //2枚目にめくったカードのインデックス
sameCount = 0; //揃った回数
missCount = 0; //ミスした回数
targetIndex = 0; //選択候補カードのインデックス
List1をご覧いただけばわかるように、
- ① 0~12の数列を作る
先に、
場に置かれるカードのナンバーを (マークに関係なく) 決めてしまう。そのためにまず0~12の13個の数値を保存するための擬似配列を作成する。ここでは、 for文による繰り返しの中で変数iの値が0から12へとカウントアップしていくので、 式"Number" add iは、 "Number0"~"Number12"という文字列になる。関数setはこれを変数名として、 そこに変数iの値0~12を代入する。この結果、 変数Number0の値は0、 Number1の値は1というように変数NumberX (Xは連番) は、 そのXと同じ値を保持することになる。 - ② 適当に交換して、
乱数列を作る 関数Randomを利用して適当に選んだ2つのNumberXの保持する値を交換する。これを数回繰り返すことにより、
Number0~Number12の中の値はシャッフルされ、 NumberXを連番で順次参照した時にその値は乱数列となる。この内、 頭から4つが場に並ぶカードのナンバーとなる。 - ③ 場に並ぶカードの決定
ナンバーが決まったら次はマークの番だ。場には必ず同じナンバー異なるマークの4組計8枚のカードが置かれることになるので、
Number0~Number4の値を元にそれぞれ2つずつの異なるマークを割り当てて、 変数CardVal0~CardVal7に代入する。この時CardValXに代入する値は、 カードクリップのフレーム番号であり、 各カードは、 - ダイヤのA~K・・・2~14フレーム目
- クローバのA~K・・・15~27フレーム目
- ハートのA~K・・・28~40フレーム目
- スペードのA~K・・・41~53フレーム目
と並んでいるので、
各マークのAの位置のフレーム番号にNumberXの値を足してあげれば良いということになる。 - ⑤場に並ぶカードを切る
③のままでは、
Card0とCard4、 Card1とCard5というように上下のカードが必ず対になってしまう。そこでCardVal0~CarVal7の値を②と同様に関数Randomを利用して適当に交換する。これで、 やっとカードのシャッフルが完成する。
(4)ゲームを進める上で必要となる変数とその初期値
List1では、
- CardLook0~7
- そのカードがめくれるか否かの状態を示すフラグ。値が"0"の時はめくる事が可能。既にめくれている場合やペアが成立した場合に、
このフラグを"1"としカードをめくる選択対象からはずす。 - selectCard1、
2 - めくられたカードのインデックス
(0~7の連番のこと) を保存する。初期値である"-1"か否かをチェックすることで、 1枚目および2枚目がめくられたか否かの判定が可能となる。 - sameCount
- 2枚のカードのナンバーが揃った回数を保存するカウンター。従って、
この値が4になればゲームクリアということになる。カウンターなので初期値は当然"0"である。 - missCount
- 2枚のカードのナンバーが揃わなかった回数を保存するカウンター。sameCountの逆で、
この値が4になるとゲームオーバーとなる。これも初期値は"0"を設定。 - targetIndex
- 選択候補枠
(現在めくる対象となっているカードを示すハイライト) の付いているカードのインデックスを保存する。
めくるカードを選択させる
どのカードをめくるかプレイヤーに選択させよう。まず、
(1)選択候補枠クリップ(1枚目用)
Fla画面3を見ての通り、

4フレーム目に記述するスクリプトは至って簡単!
//カードが開いているときは点滅しない
if(../../:selectCard1 > -1){
gotoAndPlay(1);
}
変数selectCard1が-1より大きい場合、
(2)選択候補クリップ(1枚目用)
(1)

(3)2枚目用は若干修正
2枚目のカードをめくる際に必要となる選択候補枠クリップと選択候補クリップは、

4フレーム目のスクリプトも修正!
//カードが開いているときは点滅しない
if(../../:selectCard2 > -1){
gotoAndPlay(1);
}
チェックする変数が、

2枚目用選択候補枠は、
そして、
