import { BaseEnemy } from './BaseEnemy.js'; const PREFERRED_DIST = 300; const SHOOT_INTERVAL = 2000; // ms const PROJECTILE_SPEED = 200; const PROJECTILE_DAMAGE = 10; const PROJECTILE_COLOR = 0xff00ff; export class ShooterEnemy extends BaseEnemy { constructor(scene, x, y, player) { super(scene, x, y, player, { frameOffset: 6, radius: 16, hp: 60, speed: 50, xp: 30, contactDamage: 8, }); this._shootTimer = SHOOT_INTERVAL * Math.random(); // stagger first shot this.projectiles = scene.add.group(); this._deathPulseColor = 0x9900ff; this._deathSound = 'sfx-death-shooter'; } _die() { this._gridDeathPulse(); super._die(); } update(delta) { super.update(delta); this._strafe(); this._handleShoot(delta); this._updateProjectiles(); } _strafe() { const dist = Phaser.Math.Distance.Between(this.x, this.y, this.player.x, this.player.y); const angle = Phaser.Math.Angle.Between(this.x, this.y, this.player.x, this.player.y); let vx = 0, vy = 0; if (dist > PREFERRED_DIST + 30) { // Move closer vx = Math.cos(angle) * this.speed; vy = Math.sin(angle) * this.speed; } else if (dist < PREFERRED_DIST - 30) { // Move away vx = -Math.cos(angle) * this.speed; vy = -Math.sin(angle) * this.speed; } else { // Strafe perpendicular const perp = angle + Math.PI / 2; vx = Math.cos(perp) * this.speed; vy = Math.sin(perp) * this.speed; } this.sprite.body.setVelocity(vx, vy); } _handleShoot(delta) { this._shootTimer -= delta; if (this._shootTimer <= 0) { this._shootTimer = SHOOT_INTERVAL; this._fireProjectile(); } } _fireProjectile() { this.scene.sound.play('sfx-shooter-shoot', { volume: 0.35 }); const angle = Phaser.Math.Angle.Between(this.x, this.y, this.player.x, this.player.y); const proj = this.scene.add.circle(this.x, this.y, 6, PROJECTILE_COLOR); this.scene.physics.add.existing(proj); proj.body.setVelocity( Math.cos(angle) * PROJECTILE_SPEED, Math.sin(angle) * PROJECTILE_SPEED ); proj.damage = PROJECTILE_DAMAGE; this.projectiles.add(proj); // Register with scene for collision this.scene.events.emit('enemy-projectile-spawned', proj); } _updateProjectiles() { const W = this.scene.scale.width; const H = this.scene.scale.height; this.projectiles.getChildren().forEach(p => { if (p.x < -30 || p.x > W + 30 || p.y < -30 || p.y > H + 30) p.destroy(); }); } destroy() { this.projectiles.clear(true, true); super.destroy(); } }