Let enemies break tank collision stalemates

main
darcy 4 weeks ago
parent 8516754065
commit 6b468704df

@ -213,6 +213,7 @@
team,
fireTimer: 0,
aiTimer: 0.4 + Math.random() * 1.2,
avoidTimer: 0,
alive: true,
};
}
@ -347,9 +348,10 @@
const livingEnemies = enemies.filter((enemy) => enemy.alive);
for (const enemy of livingEnemies) {
enemy.fireTimer = Math.max(0, enemy.fireTimer - dt);
enemy.avoidTimer = Math.max(0, enemy.avoidTimer - dt);
enemy.aiTimer -= dt;
if (enemy.aiTimer <= 0) {
if (enemy.aiTimer <= 0 && enemy.avoidTimer <= 0) {
enemy.dir = chooseEnemyDirection(enemy);
enemy.aiTimer = 0.45 + Math.random() * 1.25;
}
@ -357,12 +359,16 @@
const dir = DIRS[enemy.dir];
const moved = moveTank(enemy, dir.x * ENEMY_SPEED * dt, dir.y * ENEMY_SPEED * dt, livingEnemies);
if (!moved) {
enemy.dir = randomDirection();
enemy.aiTimer = 0.25;
const escapeDir = chooseOpenEnemyDirection(enemy, livingEnemies);
enemy.dir = escapeDir || randomDirection();
enemy.avoidTimer = 0.55;
enemy.aiTimer = 0.2;
const next = DIRS[enemy.dir];
moveTank(enemy, next.x * ENEMY_SPEED * dt, next.y * ENEMY_SPEED * dt, livingEnemies);
}
if (canSeePlayer(enemy) || Math.random() < dt * 0.18) {
facePlayer(enemy);
if (enemy.avoidTimer <= 0) facePlayer(enemy);
fire(enemy);
}
}
@ -383,6 +389,35 @@
return names[Math.floor(Math.random() * names.length)];
}
function chooseOpenEnemyDirection(enemy, livingEnemies) {
const preferred = shuffledDirections().sort((a, b) => distanceFromPlayer(enemy, b) - distanceFromPlayer(enemy, a));
return preferred.find((name) => canMove(enemy, name, livingEnemies));
}
function shuffledDirections() {
const names = Object.keys(DIRS);
for (let i = names.length - 1; i > 0; i -= 1) {
const j = Math.floor(Math.random() * (i + 1));
[names[i], names[j]] = [names[j], names[i]];
}
return names;
}
function distanceFromPlayer(enemy, dirName) {
const dir = DIRS[dirName];
const nextX = enemy.x + dir.x * TILE;
const nextY = enemy.y + dir.y * TILE;
const dx = nextX - player.x;
const dy = nextY - player.y;
return dx * dx + dy * dy;
}
function canMove(entity, dirName, peerEnemies) {
const dir = DIRS[dirName];
const probe = { ...entity, x: entity.x + dir.x * 4, y: entity.y + dir.y * 4 };
return !isBlocked(probe, peerEnemies.filter((peer) => peer !== entity));
}
function facePlayer(enemy) {
const dx = player.x - enemy.x;
const dy = player.y - enemy.y;

Loading…
Cancel
Save