ステージごとにマップを切り替える小技
※2次元配列の 配列名 を代入(実際にはリンクをコピー)するだけで、そのステージのマップデータに切り替わります。この時、 [ ]や添字(インデックス)は書きません。
1.利用シーン
パックマンや横スクロールゲーム、もしくはRPGなど、ステージをクリアして次のステージに行くとき、マップを変えることがあります。
もしこのような小技を使わなければ、map1[i][j]を使ったステージ1用のプログラムとmap2[i][j]を使ったステージ2用のプログラムを別々に書かなければなりません。ほとんど同じ処理なのに、別のプログラムをいくつも書くのは無駄でしょう。
2.小技を使った場合
この小技では、二次元配列 blank をあらかじめ用意します(配列名は任意です。blankでなくても構いません)。この配列に、ステージ1ではmap1のデータを、ステージ2ではmap2のデータを代入します(正確に言うと、配列への参照先(リンク)を切り替えます)。そして、マップの表示やプレーヤーの当たり判定などのプログラムは、map1[i][j]やmap2[i][j]ではなくblank[i][j]を使って書きます。
※下記はサンプルプログラムなので、本来はステージクリアでマップが自動的に切り替わるのですが、ここではマウスクリックでステージが変わりマップが切り替わります。
//ステージごとにマップを切り替える小技。
int[][] blank;
int[][] map1 = {{1, 1, 0}, {0, 1, 0}, {0, 1, 1}};
int[][] map2 = {{0, 0, 0, 1}, {1, 1, 0, 1}, {0, 1, 1, 1}, {1, 1, 0, 1}};
int imax=0;int jmax=0;
boolean playFlg = false;int stage = 1;
void setup() { size(300, 300);}
void draw() {
//マップデータ設定 if (playFlg == false) { //ステージ変更直後(クリック直後)の時だけ処理する if (stage == 1) { blank = map1; } if (stage == 2) { blank = map2; } imax = blank.length; // blankに代入したmap1またはmap2の行数 jmax = blank[0].length; // blankに代入したmap1またはmap2の列数 playFlg = true; }
//マップ描画 background(0); for (int i=0; i<imax; i++) { for (int j=0; j<jmax; j++) { if (blank[i][j] == 0) { fill(0, 0, 255); // 青 } else if (blank[i][j] == 1) { fill(0, 255, 0); // 緑 } rect(j*50, i*50, 50, 50); //iは行なのでy座標、jは列なのでx座標になることに注意 } }}
void mouseClicked() { stage = 3 - stage; //stageを1と2で切り替える ←「プレーヤーを切り替える小技」参照 playFlg = false;}
↓↑ マウスクリックで切り替え
この時気を付けなければならないのは、map1とmap2で配列の大きさ(行数・列数)が異なる場合があることです。この大きさをきちんと把握しておかないと、添字が範囲外であるというエラー(Array Index Out Of Bounds Exception)が出てしまいます。
その時に使えるのが、2次元配列 blank の行数・列数を求めるテクニックです。
imax = blank.length; jmax = blank[0].length;
blank.length
で行数を、 blank[0].length
で列数を求めることができます。
※ステージが変わる際のマップの切り替え処理は、この小技以外にもいろいろな方法があります。例えば、クラスを使って状態遷移を記述するとか、ArrayListを利用する方法もあるでしょう。これをきっかけにいろいろと調べてみてください。
※ここでは配列の参照先(リンク)のコピー、いわゆるshallow copyをしています。コピー先(または元)で要素を変更すると、コピー元(または先)も変更される方式です。それが不都合の場合は、要素を一つ一つコピーするdeep copyをするのが良いでしょう。shallow copyやdeep copyといった用語については、各自で調べてみてください。