矢印キーで上下左右 または マウスで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; // 軌跡
   }
}