
3Dになっている意味としては、「壁」に見えるということ以外にありません。変数の値によって迷路の規模が変わります。ボールをUP, DOWN, RIGHT, LEFTキーで動かします。
コードは以下のとおりです。
int rc = 21; // 一辺の区画の数(奇数が望ましい?) int bs = 100; // ブロックの1辺の大きさ color cl; // 区画の色 ArrayList<PVector> mpos; // 区画の座標とブロックの有無 PVector pos; float centerX, centerY, centerZ; // 注視点の座標 int emn = 1; // 初期の球の区画番号 int nemn; int ed = 2; // eyeの向きの初期値 int dis = 100; // 視線の距離 void setup(){ size(600, 600, P3D); mpos = new ArrayList<PVector>(); // すべての区画の座標を格納、yには初期値の0 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)); } // 周りの区画のyを1(ブロックを置く) 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; } } // 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); camera((rc * bs) / 2, -(rc * bs), (rc * bs) / 2, (rc * bs) / 2, bs, (rc * bs) / 2 - 1, 0, 1, 0); for(int i = 0; i < rc * rc; i++) { pos = mpos.get(i); if (pos.y == 1) { cl = color(#FFDEAD); stroke(0); createBox(pos.x, 0, pos.z, bs,bs,bs, cl); } } createBall(emn); checkGoal(); } void createMaze(int num) { ArrayList<Integer> directions = new ArrayList<Integer>(); int north = num - rc; int east = num + 1; int south = num + rc; int west = num -1; // 3行目のみ東西南北の4方向を調べる 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 { // 4行目以下は北は選択肢から外す 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 createBall(int emn) { pos = mpos.get(emn); fill(150, 50, 200); noStroke(); pushMatrix(); translate(pos.x, 0, pos.z); sphere(40); popMatrix(); } void keyPressed() { switch (keyCode) { case UP: ed = 0; break; case RIGHT: ed = 1; break; case DOWN: ed = 2; break; case LEFT: ed = 3; break; } nextPosition(); } void nextPosition() { nemn = emn; // デフォルトは変更なし(動かない) switch (ed) { case 0: // UP if (emn > rc) { // 上端でないとき nemn = emn - rc; } break; case 1: // RIGHT if (emn % rc < rc) { // 右端でないとき nemn = emn + 1; } break; case 2: // DOWN if (emn < rc * rc - rc) { // 下端でないとき nemn = emn + rc; } break; case 3: // LEFT if (emn % rc > 0) { // 左端でないとき nemn = emn - 1; } break; } // 移動先が壁でない場合のみ更新(移動) if (mpos.get(nemn).y == 0) { emn = nemn; } } void checkGoal() { if (emn == rc * rc - 2) { pushMatrix(); translate((rc * bs) /2 , -200, (rc * bs) /2); rotateX(radians(90)); textSize(rc * 20); textAlign(CENTER, CENTER); fill(#32CD32); text("GOAL!!!", 0, 0); popMatrix(); } }