using AlienAttack.MonoGame.Things.Bullets; using Microsoft.Xna.Framework; namespace AlienAttack.MonoGame.Things.Enemies.Mines; public class RedMine(int x, int y) : Mine(x, y) { protected bool IsCharging = false; protected Vector2 TargetCenter; protected override string CoverColor => "Red"; protected override float ExplodeRadius => 18f; protected override int MaxHealth => 10; // Tunables private const float DetectRange = 200f; private const float ChargeSpeed = 5f; // try 3.5–6.0 protected override void OnUpdate(SpriteUpdateContext context) { // If not charging yet, see if we should lock on if (!IsCharging) { if (DistanceToPlayer > DetectRange) return; Charge(context.Player); } // We are charging: steer directly toward the locked target point Vector2 toTarget = TargetCenter - new Vector2(XPosition + Origin.X, YPosition + Origin.Y); float dist = toTarget.Length(); if (dist <= ExplodeRadius) { IsDead = true; // Optionally: explode at target (top-left adjustment) XPosition = TargetCenter.X - Origin.X; YPosition = TargetCenter.Y - Origin.Y; SpawnExplosion(context); // uses current XPosition/YPosition return; } // Normalize direction (avoid NaN if dist == 0) Vector2 dir = toTarget / dist; // Set velocities for base.Update to apply next frame XVelocity = dir.X * ChargeSpeed; YVelocity = dir.Y * ChargeSpeed; // Optional: if you want it to stop “floating down” once charging // (it will anyway, because we overwrite YVelocity) } public override void OnCollision(SpriteCollisionContext context) { base.OnCollision(context); if (context.Sprite is Bullet bullet && bullet.Owner is Player player && IsCharging == false) { Charge(player); } } private void Charge(Sprite target) { IsCharging = true; float x = target.XPosition + target.Origin.X; float y = target.YPosition + target.Origin.Y; TargetCenter = new Vector2(x, y); RotationSpeed *= ChargeSpeed; } }