dfsaf

🧩 Syntax:
let maze = [];
let mazeWidth = 19;

let Kind = {
  player: 1,
  enemy: 2,
  trap: 3,
  hostage: 4,
  sword: 5,
};

let Buff = {
  snare: 1,
  rescue: 2,
  swordCount: 0,
};
let Item = {
  noWeapon: 0,
  weaponS: 3,
};


class Actor {
  constructor() {
    this.kind = 0;
    this.image = "";
    this.x = 0;
    this.y = 0;
    this.buff = 0;
    this.buffTimer = 0;
  }
}
let goal = new Actor();
goal.kind = 9;
goal.image = "▲";
goal.x = 1;
goal.y = 1;
let player = new Actor();
player.kind = 1;
player.image = "〇";
player.x = 1;
player.y = 1;
let enemy = new Actor();
enemy.kind = 2;
enemy.image = "E";
enemy.x = 11;
enemy.y = 11;
enemy.buffTimer = 0;
let enemy2 = new Actor();
enemy2.kind = Kind.enemy;
enemy2.image = "F";
enemy2.x = 13;
enemy2.y = 11;
let enemy3 = new Actor();
enemy3.kind = Kind.enemy;
enemy3.image = "G";
enemy3.x = 9;
enemy3.y = 9;
let enemy4 = new Actor();
enemy4.kind = Kind.enemy;
enemy4.image = "K";
enemy4.x = 11;
enemy4.y = 11;
let sword = new Actor();
sword.kind = Kind.sword;
sword.image = "剣";
sword.x = 11;
sword.y = 5;
let hostage = new Actor();
hostage.x = mazeWidth - 2;
hostage.y = mazeWidth - 2;
hostage.kind = Kind.hostage;
hostage.image = "友";
//PosXstack = [11,11,11,11,11,11,11]
//PosYstack = [11,11,11,11,11,11,11]; 
let actors = [goal, player, enemy,hostage, sword];
//////////////////////////////////////////////////////////////////////
function setup() {
  createCanvas(480, 480);
  //迷路生成
  maze.push(new Array(mazeWidth).fill(1));
  for (let y = 0; y < mazeWidth - 2; y++) {
    maze.push(new Array(mazeWidth).fill(0));
    maze[y + 1][0] = 1;
    maze[y + 1][mazeWidth - 1] = 1;
  }
  maze.push(new Array(mazeWidth).fill(1));

  for (let y = 2; y < mazeWidth - 2; y += 2) {
    for (let x = 2; x < mazeWidth - 2; x += 2) {
      maze[y][x] = 1;
      while (true) {
        // let r = floor(random(0, y===2 ? 4 : 3));
        let r = floor(random(0, 4));
        let a = [1, 0, -1, 0][r];
        let b = [0, 1, 0, -1][r];
        if (maze[y + b][x + a] === 1) continue;
        maze[y + b][x + a] = 1;
        break;
      }
    }
  }
  debugger;
}
//////////////////////////////////////////////////////////////////////
//周りの壁と敵を数える。友の行き場がなくなればゲームオーバー
let countWalls = (x, y) => {
  let blocks = 0;
  for (let j = x - 1; j <= x + 1; j++) {
    for (let k = y - 1; k <= y + 1; k++) {
      blocks += maze[k][j];
    }
  }
  let enemies = actors.filter(
    (a) => a.kind === Kind.enemy && abs(a.x - x) <= 1 && abs(a.y - y) <= 1
  ).length;
  return blocks + enemies;
};
//////////////////////////////////////////////////////////////////////

let blowoff = (x, y, a, b) => {
  let c = 3; //距離
  while(maze[y][x] === 0 && c>0) {
    x += a;
    y += b;
    c--;
  }
  return [x, y];
};

// ベクトルの演算の関数
// 引数のsはスカラー、vとwは3次元ベクトル
let mul = (s, v) => v.map((e) => s * e);
let add = (v, w) => v.map((e, i) => e + w[i]);
let sub = (v, w) => add(v, mul(-1, w));
let dot = (v, w) => v[0] * w[0] + v[1] * w[1];
let norm = (v) => sqrt(v[0] ** 2 + v[1] ** 2);
let normalize = (v) => mul(1 / norm(v), v);
let chase = (a, b, p, q) => {
  let v = [0, 1, 2, 3]
    .map((n) => [[1, 0, -1, 0][n], [0, 1, 0, -1][n]])
    .sort((v, w) => {
      let PE = sub([p, q], [a, b]);
      let r = norm(add(PE, v));
      let s = norm(add(PE, w));
      return r - s;
    })
    .slice(0, 3)
    .filter((v) => maze[q + v[1]][p + v[0]] === 0)
    .filter((v) => {
      return actors
        .filter(
          (act) =>
            (act.buff !== Buff.snare && //罠の上はすり抜けられる
              act.kind === Kind.enemy) ||
            act.kind === Kind.hostage ||
            act.kind === Kind.player
        )
        .every((act) => {
          return act.x !== p + v[0] || act.y !== q + v[1];
        });
    });
  if (v.length === 0) return [0, 0];
  return [v[0][0], v[0][1]];
};

let keyDownFrames = 0;
function draw() {
  background(220);
  for (let y = 0; y < mazeWidth; y++) {
    for (let x = 0; x < mazeWidth; x++) {
      let w = width / mazeWidth;
      let m = maze[y][x];
      if (m === 1) {
        rect(w * x, w * y, w, w);
      }
    }
  }

  if (keyIsPressed) {
    keyDownFrames++;
  } else {
    keyDownFrames = 0;
  }
  

  
    //////////////////////////////////////////////////////////////////////
    //ここからキー入力処理ループ
  if (keyDownFrames === 1) {
    let k = keyCode - 37;
    if (k >= 0 && k < 4) {
      let a = [-1, 0, 1, 0][k];
      let b = [0, -1, 0, 1][k];
      let p = player;
      if (maze[p.y + b][p.x + a] === 0) {
        let move = chase(p.x + a, p.y + b, p.x, p.y);
        p.x += move[0];
        p.y += move[1];
      }
    }
    //罠を置く t=84
    let trapCount = actors.filter((a) => a.kind === Kind.trap).length; //????
    if (keyCode === 84 && trapCount < 3) {
      let trap = new Actor();
      trap.x = player.x;
      trap.y = player.y;
      trap.image = "罠";
      trap.kind = Kind.trap;
      actors.push(trap);

      //let trap2 = new Actor();
      //trap2.x = player.x;
      //trap2.y = player.y;
      //trap2.image = '穴';
      //actors.push(trap2);
    }
    //剣で攻撃 s=83

    if (keyCode === 83 && player.Item === Item.weaponS && Buff.swordCount < 3) {
      background(200, 200, 200);
      background(200, 100, 100);
      background(200, 200, 200);
      background(200, 100, 100);
      let hitEnemyVec = [
        [1, 0],
        [0, 1],
        [-1, 0],
        [0, -1],
      ].filter((w) => enemy.x + w[0] === player.x && enemy.y + w[1] === player.y);

      if (hitEnemyVec.length > 0) {
        //敵をふきとばしたい
        //敵ーの動きを5ターン スタックに記憶しておく
        //主人公と敵が接触していて剣があるとき、sキーで攻撃
        //敵の位置が5ターン前に戻る
        //enemy.x =PosXstack[0];
        //enemy.y =PosYstack[0];
        let v = hitEnemyVec[0];
        let enemyNewPos = blowoff(enemy.x, enemy.y, -v[0], -v[1]);
        enemy.x = enemyNewPos[0];
        enemy.y = enemyNewPos[1];
      }

      Buff.swordCount += 1;
      if (Buff.swordCount >= 3) {
        player.image = "〇";
        player.Item === Item.noWeapon;
      }
      console.log(Buff.swordCount);
    }

    //敵の思考ルーチン処理 主人公をおいかける
    for (let enemy of actors.filter((a) => a.kind === Kind.enemy)) {
      if (enemy.buffTimer === 0) {
        let rival = hostage.buff === Buff.rescue ? hostage : player;
        let chaseVec = chase(rival.x, rival.y, enemy.x, enemy.y);
        enemy.x += chaseVec[0];
        enemy.y += chaseVec[1];
        //PosXstack.push(enemy.x);//スタックに格納
        //PosYstack.push(enemy.y);   
        //PosXstack.shift();
        //PosYstack.shift();  
        //console.log(PosXstack);
        //console.log(PosYstack);
        
        for (let trap of actors.filter((a) => a.kind === Kind.trap)) {
          if (trap.x === enemy.x && trap.y === enemy.y) {
            enemy.buff = Buff.snare;
            enemy.buffTimer = 5;
          }
        }
      } else {
        enemy.buffTimer -= 1;
      }
    }

    // 友と主人公の位置交換
    // 救出
    let hitHostage = [
      [1, 0],
      [0, 1],
      [-1, 0],
      [0, -1],
    ].some(
      (w) => player.x + w[0] === hostage.x && player.y + w[1] === hostage.y
    );

    if (hostage.buff === Buff.rescue) {
      let chaseVec = chase(player.x, player.y, hostage.x, hostage.y);
      hostage.x += chaseVec[0];
      hostage.y += chaseVec[1];
    }
  }
  //アイテムを拾う処理 剣
  if (player.x === sword.x && player.y === sword.y) {
    player.Item = Item.weaponS;
    sword.x = -10;
    sword.y = -10;
    player.image = "◎";
  }

  //ここまでキー入力処理ループ

  //ゴール条件
  let hitHostage = [
    [1, 0],
    [0, 1],
    [-1, 0],
    [0, -1],
  ].some((w) => goal.x + w[0] === hostage.x && goal.y + w[1] === hostage.y);
  if (hitHostage) {
    background(0, 0, 255);
    textAlign(LEFT, TOP);
    fill(255);
    for (let actor of actors) {
      actor.image = "";
    }
    text("救出成功", 150, 200);
    noLoop();
  }

  textSize(20);
  //ゲームオーバー条件
  if (countWalls(player.x, player.y) >= 8) {
    background(200, 200, 00);
    textAlign(LEFT, TOP);
    fill(15);
    for (let actor of actors) {
      actor.image = "";
    }
    text("主人公が追い詰められてゲームオーバー", 80, 220);
    noLoop();
  }
  if (countWalls(hostage.x, hostage.y) >= 8) {
    background(255, 0, 0);
    textAlign(LEFT, TOP);
    fill(15);
    for (let actor of actors) {
      actor.image = "";
    }
    text("友が追い詰められてゲームオーバー", 80, 220);
    noLoop();
  }

  //アクターの配置
  textSize(34);
  for (let actor of actors) {
    let w = width / mazeWidth;
    textAlign(LEFT, TOP);
    text(actor.image, w * actor.x, w * actor.y);
  }
}