監督スクリプトを記述しよう(ぷよ消滅の仕組み作成3)
このページでは、前々回、前回に引き続き、監督スクリプトの仕事の一つである、ぷよの落下が完了次第、同色ぷよが4個以上隣り合っているぷよを消滅させるのスクリプト文を書いていきます。
前々回、前回を経て、同色ぷよが何個隣り合っているかをカウントするスクリプトの方向性が大体定まりました。今回こそ、いよいよ具体的にスクリプト文を書いていきますよー!
今回、一気に結構な分量のスクリプトを書いていきますが、落ち着いて一つ一つ理解していって下さい。混乱したらお茶でもどーぞ( ^-^)_旦~
再帰呼び出しを用いてスクリプトを記述しよう
今回から具体的にスクリプト文を書いていきますが、以降の具体的な書き方については正直人それぞれになると思います。本記事ではワガハイ式ぷよぷよの制作方式で進めます。
まず、各ぷよに以下のような4種類の変数を定義します。各変数の意味については、以下スクリプト中のコメント文を参考にして下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
GameObject[] puyos; float[] puyox = new float[100]; float[] puyoy = new float[100]; int[] checks = new int[100]; int[] samecolornums = new int[100]; this.puyos = GameObject.FindGameObjectsWithTag("puyo"); int i = 0; foreach(GameObject puyo in this.puyos){ //checks[i]:i番ぷよの確認作業終了フラグ…0:未完了、1:完了 this.checks[i] = 0; //samecolornums[i]:i番ぷよと隣り合っている同色ぷよの数、基本は1(自分自身) this.samecolornums[i] = 1; //puyox[i],puyoy[i]:i番ぷよの位置座標(丸め誤差対策済) this.puyox[i] = Mathf.RoundToInt(puyo.transform.position.x * 10.0f)/10.0f; this.puyoy[i] = Mathf.RoundToInt(puyo.transform.position.y * 10.0f)/10.0f; i++; } |
次に、いよいよ同色ぷよが何個隣り合っているかをカウントする核心部分に入っていきます!
ワガハイ式ぷよぷよの場合、Checkメソッドを通じて、以下のような隣接同色ぷよ番号のグループを作成していきます。
{0,2}{1}{3}{4}{5}{6,7,12}{8}{9}{10}{11}{13,14,16,17}
そして、先程定義しました隣接同色ぷよのカウント結果を入れる変数samecolornums[i]に自分の属するグループの要素数(=隣接同色ぷよの数)を代入することで、カウント結果を記録していきます。
上のグループの作り方ですが、今回は動的配列を利用して作成します。詳細はこちらのページにて紹介していますが、通常の配列って、箱の数(要素数)を最初に定義すると、後から変更出来ませんよね。対して動的配列を用いますと、簡単に要素を追加・除外して、要素数も簡単に変更することが出来ます。今回はこの便利な配列を使用していきます。
要するに、0番ぷよにCheckメソッドを適用→結果、動的配列samecolorset={0,2}が誕生→「(*)samecolornums[0]=samecolornums[2]=samecolorset.Count(=2)」という手順でカウント結果を記録していきたいのです。よって、Checkメソッドの中身とその周辺をもう少し具体的に書くとこんな具合になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
List<int> samecolorset = new List<int>(); int i = 0; foreach(GameObject puyo in this.puyos){ this.samecolorset.Clear(); Check(i); for(int k = 0; k < this.samecolorset.Count; k++){ //i番ぷよと隣接同色ぷよのsamecolornumsにカウント結果を代入 this.samecolornums[this.samecolorset[k]]=this.samecolorset.Count; } i++; } void Check(int i){ this.samecolorset.Add(i); if(左のぷよ(j1番ぷよ)と色が同じ?) Check(j1); if(右のぷよ(j2番ぷよ)と色が同じ?) Check(j2); if(上のぷよ(j3番ぷよ)と色が同じ?) Check(j3); if(下のぷよ(j4番ぷよ)と色が同じ?) Check(j4); } |
Checkメソッドの周辺についてはこれで完了です。8行目の長い文は、スクリプト前に解説した(*)式をただ一般的な形に書き直しただけです。動的配列samecolorset={0,2}の場合、6~9行目のforループの意味は(*)式と全く一緒になりますよね。
次に、もう少しCheckメソッドの中身を充実させましょう。各if文にて判定する()の中身は似たようなことが書かれていますが、例えば1つ目だと「左のぷよ(j1番ぷよ)と色が同じ?」と書かれています。これをスクリプト文で表現するには、forループを用いて全ぷよに対して「i番ぷよの左にいる?かつ、そのぷよの色=オブジェクト名はi番ぷよと一致してる?」と書いてやれば良いことになります。なので、こんな具合でどうでしょうか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public void Check (int i) { this.samecolorset.Add(i) ; for(int j = 0 ; j < this.puyos.Length ; j++) { if(this.puyox[i] == this.puyox[j] && this.puyoy[i] == this.puyoy[j] + 1.0f && this.puyos[i].transform.name == this.puyos[j].transform.name){ // 下(j番ぷよ)と自分自身(i番ぷよ)が同色 Check(j); } if(this.puyox[i] == this.puyox[j] && this.puyoy[i] == this.puyoy[j] - 1.0f && this.puyos[i].transform.name == this.puyos[j].transform.name){ // 上(j番ぷよ)と自分自身(i番ぷよ)が同色 Check(j); } if(this.puyox[i] == this.puyox[j] + 1.0f && this.puyoy[i] == this.puyoy[j] && this.puyos[i].transform.name == this.puyos[j].transform.name){ // 左(j番ぷよ)と自分自身(i番ぷよ)が同色 Check(j); } if(this.puyox[i] == this.puyox[j] - 1.0f && this.puyoy[i] == this.puyoy[j] && this.puyos[i].transform.name == this.puyos[j].transform.name){ // 右(j番ぷよ)と自分自身(i番ぷよ)が同色 Check(j); } } return; } |
かなり具体的にスクリプト文が書けてきました!\(^ ^)/今回、一気にスクリプトを書いていきましたので、少し混乱している方もいらっしゃるかもしれません。
その場合一旦落ち着いて…Check(i=0)メソッドが寸劇の内容を再現出来ているか、ご自身で確かめてみて下さい。
次回、もう少しこのスクリプトを改良していきます。まだちょっと不足している所がありますので、それを補っていきます。完成まで、もう少しです!!