未熟者ですので無駄な部分も多いかと思います。なんとか動くものができましたのでアップすることにしました。まずは動かしている動画を
以下がコードです。冒頭のrcの値で迷路の規模を変えることができます。上の実行動画は15✕15のブロックです。
目の高さehを低くすると周りが見渡せないので、まさに迷路の中という視線になり、いまどこにいるのか、もうわかりません。
int rc = 15; // 一辺の区画の数 int bs = 100; // ブロックの1辺の大きさ color cl; // ブロックの色 ArrayList<PVector> mpos; // 区画の座標リスト PVector pos; float centerX, centerY, centerZ; // 注視点の座標 int emn = 1; // eyeの区画番号の初期値 int nemn; int ed = 2; // eyeの向きの初期値 int dis = 300; // 視線の距離 int eh = 150; // eyeの高さ void setup(){ size(800,800,P3D); // ブロックのx座標,ブロック作成するか否か,z座標を格納 mpos = new ArrayList<PVector>(); // 全ての区画の座標を格納 for (int i = 0; i < rc * rc; i++) { float x = bs / 2 + (i % rc) * bs; float z = bs / 2 + (i / rc) * bs; mpos.add(new PVector(x, 0, z)); } // 周囲を壁で囲む for (int i = 0; i < rc * rc; i++) { int row = i / rc; //行 int col = i % rc; //列 if (row == 0 || row == rc - 1 || col == 0 || col == rc - 1) { mpos.get(i).y = 1; } } // 棒倒し法による迷路作成 for (int i = 2; i < rc - 2; i += 2) { for (int j = 2; j < rc - 2; j += 2) { int num = i + j * rc; mpos.get(num).y = 1; createMaze(num); } } mpos.get(1).y = 0; //スタート地点のブロックを取り除く mpos.get(rc * rc -2).y = 0; // ゴール地点のブロックを取り除く } void draw() { background(0); // 環境光(全体を少し明るくする) ambientLight(100, 100, 100); // ライトの設定(白色のライトを少し右斜め上から照射) directionalLight(255, 255, 255, 1, -1, -1); pos = mpos.get(emn); getCenter(emn, ed); camera(pos.x, -eh, pos.z, centerX, centerY, centerZ, 0, 1, 0); for(int i = 0; i < rc * rc; i++) { pos = mpos.get(i); if (pos.y == 1) { if (i % 4 == 0) { cl = color(0, 100, 0); } else { cl = color(#f4a460); } stroke(0); createBox(pos.x, 0, pos.z, bs,bs,bs, cl); } } pos = mpos.get(rc * rc -3); cl = color(255,255,0); createBox(pos.x, -bs, pos.z, bs, bs, bs, cl); pos = mpos.get(rc * rc -1); cl = color(255,0,255); createBox(pos.x, -bs, pos.z, bs, bs, bs, cl); checkGoal(); } // 棒倒し法によりブロックを設置して迷路作成 void createMaze(int num) { int north = num - rc; int east = num + 1; int south = num + rc; int west = num -1; // 周囲の区画を調べてブロックが無い場所をリストに格納 ArrayList<Integer> directions = new ArrayList<Integer>(); // 3行目のみ北に壁を作ることを認める if (num / rc == 2) { if (north >=0 && mpos.get(north).y == 0) directions.add(north); if (east < rc * rc && mpos.get(east).y == 0) directions.add(east); if (south < rc * rc && mpos.get(south).y == 0) directions.add(south); if (west >= 0 && mpos.get(west).y == 0) directions.add(west); } else { // それ以外の行では北に壁を作らせない if (east < rc * rc && mpos.get(east).y == 0) directions.add(east); if (south < rc * rc && mpos.get(south).y == 0) directions.add(south); if (west >= 0 && mpos.get(west).y == 0) directions.add(west); } // リストからランダムに選択して壁を作る if (directions.size() > 0 ) { int idx = (int)random(directions.size()); int chosen = directions.get(idx); mpos.get(chosen).y = 1; } } void createBox(float x, float y, float z, int w, int h, int d, color cl) { fill(cl); pushMatrix(); translate(x, y, z); box(w, h, d); popMatrix(); } // 注視点の座標を取得 void getCenter(int emn, int ed) { pos = mpos.get(emn); switch (ed) { case 0: // 北を向いているとき centerX = pos.x; centerZ = pos.z - dis; break; case 1: // 東を向いているとき centerX = pos.x + dis; centerZ = pos.z; break; case 2: // 南を向いているとき centerX = pos.x; centerZ = pos.z + dis; break; case 3: // 西を向いているとき centerX = pos.x - dis; centerZ = pos.z; break; } } // 進行方向の次の区画番号を取得 void nextPosition() { nemn = emn; // デフォルトは変更なし switch (ed) { case 0: // 前方向(北) if (emn > rc) { // 上端でない場合 nemn = emn - rc; } break; case 1: // 右方向(東) if (emn % rc < rc) { // 右端でない場合 nemn = emn + 1; } break; case 2: // 後ろ方向(南) if (emn < rc * rc - rc) { // 下端でない場合 nemn = emn + rc; } break; case 3: // 左方向(西) if (emn % rc > 0) { // 左端でない場合 nemn = emn - 1; } break; } // 移動先が壁でない場合のみ更新 if (mpos.get(nemn).y != 1) { emn = nemn; } } void keyPressed() { switch (keyCode) { case UP: // 前進 nextPosition(); getCenter(emn, ed); break; case RIGHT: // 右に向く ed = (ed + 1) % 4; getCenter(emn, ed); break; case LEFT: // 左に向く ed = (ed + 3) % 4; getCenter(emn, ed); break; } } // ゴールしたときの処理 void checkGoal() { if (emn == rc * rc - 2) { // カメラをゴール地点から遠くに配置して、ゴールの全体を見渡せるようにする camera(pos.x, -eh, pos.z + 400, pos.x, -eh, pos.z, 0, 1, 0); pushMatrix(); translate(pos.x, -eh, pos.z); textSize(50); textAlign(CENTER, CENTER); fill(255, 255, 0); text("GOAL!!!", 0, 0); popMatrix(); } }