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();
  }
}
投稿者

manager

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は受付られません。(スパム対策)