using Microsoft.Xna.Framework; using System; namespace AlienAttack.MonoGame.Things.Enemies.Mines; public class BlueMine(int x, int y) : Mine(x, y) { protected override string CoverColor => "Blue"; protected override float ExplodeRadius => 100f; protected override int MaxHealth => 10; protected int IdleThreshold = 100; protected int CurrentIdleThreshold = 100; protected bool IsCharging = false; protected bool TargetReached = false; protected Vector2 TargetOrigin; private const float DriftSpeed = 1f; private const float ChargeSpeed = 4f; protected override void OnUpdate(SpriteUpdateContext context) { // During drift if (!IsCharging) { XVelocity = 0; YVelocity = DriftSpeed; CurrentIdleThreshold--; if (CurrentIdleThreshold > 0) return; // Time to pick a target and charge TargetOrigin = PickTargetBelow(context); IsCharging = true; RotationSpeed *= ChargeSpeed; return; } // During charge Vector2 mineCenter = new(XPosition + Origin.X, YPosition + Origin.Y); Vector2 toTarget = TargetOrigin - mineCenter; float dist = toTarget.Length(); // "Arrive" cleanly: if we can reach it this frame, snap + stop charging float step = ChargeSpeed; // since you're using per-frame velocities if (dist <= step || dist <= 0.001f) { XPosition = TargetOrigin.X - Origin.X; YPosition = TargetOrigin.Y - Origin.Y; IsCharging = false; RotationSpeed = 1.5f; CurrentIdleThreshold = IdleThreshold; XVelocity = 0; YVelocity = DriftSpeed; return; } Vector2 dir = toTarget / dist; XVelocity = dir.X * ChargeSpeed; YVelocity = dir.Y * ChargeSpeed; } private Vector2 PickTargetBelow(SpriteUpdateContext context) { // Mine center in world coords float mineCenterX = XPosition + Origin.X; float mineCenterY = YPosition + Origin.Y; int screenW = context.ViewTransform.ScreenWidth; int screenH = context.ViewTransform.ScreenHeight; // Anywhere horizontally: float x = context.Random.Next(0, screenW); // Somewhere below the mine, but still on-screen. // Clamp minY so Random doesn't throw if we're near bottom. int minY = (int)MathF.Min(mineCenterY + 32f, screenH - 1); int maxY = screenH; // If we're already basically at the bottom, just pick the bottom row float y = (minY < maxY) ? context.Random.Next(minY, maxY) : (screenH - 1); return new Vector2(x, y); } private Vector2 GetTargetDirection() { Vector2 toTarget = TargetOrigin - new Vector2(XPosition + Origin.X, YPosition + Origin.Y); float dist = toTarget.Length(); return toTarget / dist; } }