🔬 This is the enemy's AI—it chases the player by moving toward them. What if you changed `player.x` to `player.x + 100`? The enemy would aim at a point ahead of the player—could this be useful for leading shots or dodging?
const dx = player.x - this.x;
const dy = player.y - this.y;
const distToPlayer = Math.hypot(dx, dy) || 1;
// Chase player
const step = this.speed * dt;
const mx = (dx / distToPlayer) * step;
const my = (dy / distToPlayer) * step;
this.tryMove(mx, my);
class Enemy {
constructor(x, y, depth) {
this.x = x;
this.y = y;
this.radius = tileSize * 0.3;
this.speed = tileSize * (1.8 + depth * 0.15);
this.maxHealth = 35 + depth * 12;
this.health = this.maxHealth;
this.damage = 8 + depth * 2;
this.attackCooldown = 0.7;
this.attackTimer = 0;
this.dead = false;
}
update(dt) {
if (this.dead || gameState !== 'playing') return;
this.attackTimer -= dt;
const dx = player.x - this.x;
const dy = player.y - this.y;
const distToPlayer = Math.hypot(dx, dy) || 1;
// Chase player
const step = this.speed * dt;
const mx = (dx / distToPlayer) * step;
const my = (dy / distToPlayer) * step;
this.tryMove(mx, my);
// Contact damage
const distPlayer = Math.hypot(player.x - this.x, player.y - this.y);
if (distPlayer < this.radius + player.radius * 0.8) {
if (this.attackTimer <= 0) {
player.takeDamage(this.damage);
this.attackTimer = this.attackCooldown;
}
}
}
tryMove(mx, my) {
let newX = this.x + mx;
let newY = this.y;
if (!this.collidesWithWalls(newX, newY)) {
this.x = newX;
}
newX = this.x;
newY = this.y + my;
if (!this.collidesWithWalls(newX, newY)) {
this.y = newY;
}
}
collidesWithWalls(px, py) {
const r = this.radius * 0.8;
const samples = [
{ x: px - r, y: py },
{ x: px + r, y: py },
{ x: px, y: py - r },
{ x: px, y: py + r }
];
for (const s of samples) {
if (isWallAtWorld(s.x, s.y)) return true;
}
return false;
}
takeDamage(amount) {
this.health -= amount;
if (this.health <= 0) {
this.dead = true;
}
}
draw() {
if (this.dead) return;
push();
noStroke();
// Body
fill(220, 80, 80);
ellipse(this.x, this.y, this.radius * 2, this.radius * 2);
// Health bar
const barW = this.radius * 1.6;
const barH = 4;
const hpRatio = constrain(this.health / this.maxHealth, 0, 1);
const bx = this.x - barW / 2;
const by = this.y - this.radius - 8;
stroke(0);
strokeWeight(1);
fill(40);
rect(bx, by, barW, barH);
noStroke();
fill(0, 220, 0);
rect(bx, by, barW * hpRatio, barH);
pop();
}
}