コンテンツにスキップ

ステージごとにマップを切り替える小技

※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;
}

Untitled

↓↑ マウスクリックで切り替え

Untitled

この時気を付けなければならないのは、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といった用語については、各自で調べてみてください。