矢印キーで上下左右 または マウスでCanvasの上下左右の部分をクリックで移動
コードは下記です。
let mpos = []; // 座標と軌跡の有無 let rc = 31; // 区画の一辺の数(奇数が望ましい) let blockSize = 12; // 区画一辺の大きさ let directions = []; let emn = 1; // 初期の球の区画番号 let ed = 2; // 向きの初期値 let bd1 = 130, bd2 = 240; // マウスクリックのボーダー let ballSize = blockSize * 0.8; function setup() { createCanvas(372, 372); rectMode(CENTER); // すべての区画の座標を格納、zには初期値の0 for (let i = 0; i < rc * rc; i++) { let x = blockSize / 2 + (i % rc) * blockSize; let y = blockSize / 2 + Math.floor(i / rc) * blockSize; mpos.push(createVector(x, y, 0)); } // 周りの区画の z を 1(壁) for (let i = 0; i < rc * rc; i++) { let row = Math.floor(i / rc); //行 let col = i % rc; //列 if (row == 0 || row == rc - 1 || col == 0 || col == rc - 1) { mpos[i].z = 1; } } // 1区画おきにブロックを置いて棒倒しで迷路作成 for (let i = 2; i < rc - 2; i += 2) { for (let j = 2; j < rc - 2; j += 2) { let num = i + j * rc; mpos[num].z = 1; createMaze(num); } } mpos[1].z = 0; // スタート位置はブロック無し mpos[rc * rc - 2].z = 0; // ゴール位置にも無し } function draw() { background(0); // 迷路のブロックを描画 for (let i = 0; i < rc * rc; i++) { if (mpos[i].z == 1) { fill(207, 139, 110); stroke(0); rect(mpos[i].x, mpos[i].y, blockSize, blockSize); } if (mpos[i].z == 2) { fill (255, 255, 0); createBall(i); } } fill(255, 20, 147); createBall(emn); } function createMaze(num) { directions = []; // 配列を毎回リセット let north = num - rc; let east = num + 1; let south = num + rc; let west = num -1; // 3行目のみ東西南北の4方向を調べる if (Math.floor(num / rc) == 2) { if (north >= 0 && mpos[north].z == 0) directions.push(north); if (east < rc * rc && mpos[east].z == 0) directions.push(east); if (south < rc * rc && mpos[south].z == 0) directions.push(south); if (west >= 0 && mpos[west].z == 0) directions.push(west); } else { // 4行目以下は北は選択肢から外す if (east < rc * rc && mpos[east].z == 0) directions.push(east); if (south < rc * rc && mpos[south].z == 0) directions.push(south); if (west >= 0 && mpos[west].z == 0) directions.push(west); } if (directions.length > 0) { let idx = floor(random(directions.length)); let chosen = directions[idx]; mpos[chosen].z = 1; } } function createBall(emn) { noStroke(); ellipse(mpos[emn].x, mpos[emn].y, ballSize, ballSize); } function keyPressed() { switch (keyCode) { case UP_ARROW: // 上 ed = 0; break; case RIGHT_ARROW: // 右 ed = 1; break; case DOWN_ARROW: // 下 ed = 2; break; case LEFT_ARROW: // 下 ed = 3; break; } nextPosition(); } function mousePressed() { let clickedX = mouseX; let clickedY = mouseY; if (clickedY < bd1 && clickedX > bd1 && clickedX < bd2) { // 上部 ed = 0; } if (clickedX > bd2 && clickedY > bd1 && clickedY < bd2) { // 右部 ed = 1; } if (clickedY > bd2 && clickedX > bd1 && clickedX < bd2) { // 下部 ed = 2; } if (clickedX < bd1 && clickedY > bd1 && clickedY < bd2) { // 左部 ed = 3; } nextPosition(); } function 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; } // 移動先が壁でない場合のみ更新(移動) let oemn = emn; if (mpos[nemn].z == 0 || mpos[nemn].z == 2) { emn = nemn; mpos[oemn].z = 2; // 軌跡 } }