using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace SuperPolarity { static class ActorManager { static SuperPolarity Game; static int OutlierBounds; static IList Actors; static ActorManager() { OutlierBounds = 100; Actors = new List(); } static public void CheckIn(Actor actor) { Actors.Add(actor); } static public void CheckOut(Actor actor) { actor.CleanUp(); Actors.Remove(actor); actor = null; } static public void Update(GameTime gameTime) { CheckActors(); CheckOutliers(); foreach (Actor actor in Actors) { actor.Update(gameTime); } } static public void Draw(SpriteBatch spriteBatch) { foreach (Actor actor in Actors) { actor.Draw(spriteBatch); } } static void CheckActors() { for (var i = Actors.Count - 1; i >= 0; i--) { if (i >= Actors.Count) { i = Actors.Count - 1; } if (Actors.Count == 0) { return; } Actor actor = Actors[i]; for (var j = i - 1; j >= 0; j--) { Actor other = Actors[j]; CheckCollision(actor, other); if (actor.GetType().IsSubclassOf(typeof(Ship)) && other.GetType().IsSubclassOf(typeof(Ship))) { CheckMagnetism((Ship)actor, (Ship)other); } } } } static void CheckCollision(Actor actor, Actor other) { var collision = Rectangle.Intersect(actor.Box, other.Box); var inverseCollision = Rectangle.Intersect(other.Box, actor.Box); if (!collision.IsEmpty && !actor.Dying && !other.Dying) { actor.Collide(other, collision); other.Collide(actor, inverseCollision); } } static void CheckMagnetism(Ship actor, Ship other) { if (actor.CurrentPolarity != Ship.Polarity.Neutral && other.CurrentPolarity != Ship.Polarity.Neutral) { var dy = other.Position.Y - actor.Position.Y; var dx = other.Position.X - actor.Position.X; var linearDistance = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)); var angle = (float) Math.Atan2(dy, dx); var otherAngle = (float)Math.Atan2(-dy, -dx); if (linearDistance < actor.MagneticRadius || linearDistance < other.MagneticRadius) { actor.Magnetize(other, (float)linearDistance, angle); other.Magnetize(actor, (float)linearDistance, otherAngle); } } } static void CheckOutliers() { for (var i = Actors.Count; i > 0; i--) { var actor = Actors[i-1]; if (actor.Position.X < -OutlierBounds || actor.Position.Y < -OutlierBounds || actor.Position.X > Game.GraphicsDevice.Viewport.Width + OutlierBounds || actor.Position.Y > Game.GraphicsDevice.Viewport.Height + OutlierBounds) { CheckOut(actor); if (actor.Parent != null) { actor.Parent.Children.Remove(actor); } } } } static public void Empty() { foreach (Actor actor in Actors) { actor.CleanUp(); } Actors.Clear(); } internal static void SetGame(SuperPolarity game) { Game = game; } public static void Bomb() { for (var i = Actors.Count - 1; i >= 0; i--) { var actor = Actors[i]; if (actor.GetType() == typeof(StandardShip)) { CheckOut(actor); Renderer.CheckOut(actor); } } } public static int CountBaddies() { return Actors.Where(a => a.GetType() == typeof(StandardShip)).Count(); } } }