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);
}
}