diff options
Diffstat (limited to 'SuperPolarity')
63 files changed, 3041 insertions, 0 deletions
diff --git a/SuperPolarity/ActorFactory.cs b/SuperPolarity/ActorFactory.cs new file mode 100644 index 0000000..f9c7697 --- /dev/null +++ b/SuperPolarity/ActorFactory.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Content; + +namespace SuperPolarity +{ + static class ActorFactory + { + static internal SuperPolarity Game; + + static public MainShip CreateMainShip(Vector2 position) + { + MainShip mainShip = new MainShip(Game); + mainShip.Initialize(Game.Content.Load<Texture2D>("Graphics\\main-ship"), position); + + ActorManager.CheckIn(mainShip); + + return mainShip; + } + + static public StandardShip CreateShip(Ship.Polarity polarity, Vector2 position) + { + StandardShip ship = new StandardShip(Game); + Texture2D texture; + + if (polarity == Ship.Polarity.Positive) + { + texture = Game.Content.Load<Texture2D>("Graphics\\positive-ship"); + } + else if (polarity == Ship.Polarity.Negative) + { + texture = Game.Content.Load<Texture2D>("Graphics\\negative-ship"); + } + else + { + texture = Game.Content.Load<Texture2D>("Graphics\\neutral-ship"); + } + + ship.Initialize(texture, position); + ship.SetPolarity(polarity); + + ActorManager.CheckIn(ship); + + return ship; + } + + internal static void SetGame(SuperPolarity game) + { + ActorFactory.Game = game; + } + + internal static Bullet CreateBullet(Vector2 position, float angle) + { + Bullet bullet = new Bullet(Game); + + bullet.Initialize(Game.Content.Load<Texture2D>("Graphics\\square"), position); + + bullet.Angle = angle; + + ActorManager.CheckIn(bullet); + + return bullet; + } + + static public StandardShip CreateScout(Ship.Polarity polarity, Vector2 position) + { + StandardShip ship = new StandardShip(Game); + Texture2D texture; + + if (polarity == Ship.Polarity.Positive) + { + texture = Game.Content.Load<Texture2D>("Graphics\\positive-scout"); + } + else if (polarity == Ship.Polarity.Negative) + { + texture = Game.Content.Load<Texture2D>("Graphics\\negative-scout"); + } + else + { + texture = Game.Content.Load<Texture2D>("Graphics\\neutral-scout"); + } + + ship.BoxDimensions.X = 10; + ship.BoxDimensions.Y = 10; + ship.BoxDimensions.W = 10; + ship.BoxDimensions.Z = 10; + + ship.Initialize(texture, position); + ship.MaxVelocity = 5.2f; + ship.FleeVelocity = 6.5f; + ship.ChargeVelocity = 5.5f; + ship.Value = 3; + ship.HP = 0; + ship.AngleChangeProbability = 20; + ship.SetPolarity(polarity); + + ActorManager.CheckIn(ship); + + return ship; + } + + static public StandardShip CreateCruiser(Ship.Polarity polarity, Vector2 position) + { + StandardShip ship = new StandardShip(Game); + Texture2D texture; + + if (polarity == Ship.Polarity.Positive) + { + texture = Game.Content.Load<Texture2D>("Graphics\\positive-cruiser"); + } + else if (polarity == Ship.Polarity.Negative) + { + texture = Game.Content.Load<Texture2D>("Graphics\\negative-cruiser"); + } + else + { + texture = Game.Content.Load<Texture2D>("Graphics\\neutral-cruiser"); + } + + ship.BoxDimensions.X = 40; + ship.BoxDimensions.Y = 40; + ship.BoxDimensions.W = 40; + ship.BoxDimensions.Z = 40; + + ship.Initialize(texture, position); + ship.MagneticRadius = 1000; + ship.RepelRadius = 200; + ship.MaxVelocity = 0.5f; + ship.FleeVelocity = 5; + ship.ChargeVelocity = 1; + ship.Value = 10; + ship.HP = 29; + ship.SetPolarity(polarity); + + ActorManager.CheckIn(ship); + + return ship; + } + } +} diff --git a/SuperPolarity/ActorManager.cs b/SuperPolarity/ActorManager.cs new file mode 100644 index 0000000..f5587b9 --- /dev/null +++ b/SuperPolarity/ActorManager.cs @@ -0,0 +1,160 @@ +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<Actor> Actors; + + static ActorManager() + { + OutlierBounds = 100; + Actors = new List<Actor>(); + } + + 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(); + } + } +} diff --git a/SuperPolarity/Actors/Actor.cs b/SuperPolarity/Actors/Actor.cs new file mode 100644 index 0000000..3bb06be --- /dev/null +++ b/SuperPolarity/Actors/Actor.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class Actor + { + protected SuperPolarity game; + + public List<Actor> Children; + + // Graphics / In-Game + protected Texture2D Texture; + protected Vector2 Origin; + public bool Active; + public Rectangle Box; + public Vector4 BoxDimensions; + protected Texture2D BoxTexture; + + // Physical Properties + public Vector2 Position; + protected Vector2 Velocity; + protected Vector2 Acceleration; + public float Angle; + + // Constraints / Behavior + public float MaxVelocity; + protected float AccelerationRate; + public int HP; + protected bool Immortal; + public bool Dying; + public int Value; + protected Color Color; + + public Actor Parent; + + public int Width + { + get { return Texture.Width; } + } + + public int Height + { + get { return Texture.Height; } + } + + public Actor(SuperPolarity newGame) + { + game = newGame; + BoxDimensions.X = 20; + BoxDimensions.Y = 20; + BoxDimensions.W = 15; + BoxDimensions.Z = 15; + } + + public virtual void Initialize(Texture2D texture, Vector2 position) + { + Texture = texture; + Position = position; + Active = true; + + Children = new List<Actor>(); + + Origin = new Vector2(Texture.Width / 2, Texture.Height / 2); + Velocity = new Vector2(0, 0); + Acceleration = new Vector2(0, 0); + + MaxVelocity = 5; + AccelerationRate = 10; + + HP = 1; + Immortal = false; + + Dying = false; + Value = 1; + + InitBox(); + BoxTexture = new Texture2D(game.GraphicsDevice, 1, 1); + BoxTexture.SetData(new Color[] { Color.White }); + + Color = Color.White; + } + + protected void InitBox() + { + Box = new Rectangle((int)(Position.X - BoxDimensions.X), (int)(Position.Y - BoxDimensions.X), (int)(BoxDimensions.X + BoxDimensions.X + BoxDimensions.W), (int)(BoxDimensions.Y + BoxDimensions.Y + BoxDimensions.Z)); + } + + public void AutoDeccelerate(GameTime gameTime) + { + if (Acceleration.X == 0 && Velocity.X > 0) + { + if (AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds > Velocity.X) + { + Velocity.X = 0; + Acceleration.X = 0; + } + else + { + Acceleration.X = -AccelerationRate; + } + } + + if (Acceleration.X == 0 && Velocity.X < 0) + { + if (-AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds < Velocity.X) + { + Velocity.X = 0; + Acceleration.X = 0; + } + else + { + Acceleration.X = AccelerationRate; + } + } + + if (Acceleration.Y == 0 && Velocity.Y > 0) + { + if (AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds > Velocity.Y) + { + Velocity.Y = 0; + Acceleration.Y = 0; + } + else + { + Acceleration.Y = -AccelerationRate; + } + } + + if (Acceleration.Y == 0 && Velocity.Y < 0) + { + if (-AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds < Velocity.Y) + { + Velocity.Y = 0; + Acceleration.Y = 0; + } + else + { + Acceleration.Y = AccelerationRate; + } + } + } + + public virtual void Update(GameTime gameTime) + { + Move(gameTime); + ChangeAngle(); + CheckOutliers(); + UpdateBox(); + } + + protected virtual void UpdateBox() + { + Box.X = (int)(Position.X - BoxDimensions.X); + Box.Y = (int)(Position.Y - BoxDimensions.Y); + } + + public virtual void Move(GameTime gameTime) + { + AutoDeccelerate(gameTime); + + var maxVelocity = MaxVelocity; + + Velocity.X = Velocity.X + Acceleration.X * (float)gameTime.ElapsedGameTime.TotalSeconds; + Velocity.Y = Velocity.Y + Acceleration.Y * (float)gameTime.ElapsedGameTime.TotalSeconds; + + if (Velocity.X > MaxVelocity) + { + Velocity.X = MaxVelocity; + } + + if (Velocity.X < -MaxVelocity) + { + Velocity.X = -MaxVelocity; + } + + if (Velocity.Y > MaxVelocity) + { + Velocity.Y = MaxVelocity; + } + + if (Velocity.Y < -MaxVelocity) + { + Velocity.Y = -MaxVelocity; + } + + Position.X = Position.X + Velocity.X; + Position.Y = Position.Y + Velocity.Y; + } + + public void ChangeAngle() + { + if (Math.Abs(Velocity.Y) <= 0.1 && Math.Abs(Velocity.X) <= 0.1) + { + return; + } + Angle = (float)Math.Atan2(Velocity.Y, Velocity.X); + } + + public virtual void Draw(SpriteBatch spriteBatch) + { + Actor child = null; + + // TODO: Check what's up with the null children. + if (Children == null) + { + return; + } + for (var i = Children.Count - 1; i >= 0; i--) + { + child = Children[i]; + child.Draw(spriteBatch); + } + + spriteBatch.Draw(Texture, Position, null, Color, Angle, Origin, 1f, SpriteEffects.None, 0f); + //spriteBatch.Draw(BoxTexture, Box, new Color(255, 0, 255, 25)); + } + + void CheckOutliers() + { + for (var i = Children.Count; i > 0; i--) + { + var actor = Children[i - 1]; + if (actor.Position.X < -SuperPolarity.OutlierBounds || actor.Position.Y < -SuperPolarity.OutlierBounds || + actor.Position.X > game.GraphicsDevice.Viewport.Width + SuperPolarity.OutlierBounds || + actor.Position.Y > game.GraphicsDevice.Viewport.Height + SuperPolarity.OutlierBounds) + { + Children.Remove(actor); + } + } + } + + public virtual void Collide(Actor other, Rectangle collision) + { + } + + public void TakeDamage(int amount) + { + if (!Immortal) + { + HP = HP - amount; + if (HP < 0) + { + Die(); + } + } + } + + protected virtual void Die() + { + Dying = true; + } + + public virtual void CleanUp() + { + Texture = null; + BoxTexture = null; + Children = null; + Texture = null; + } + } +} diff --git a/SuperPolarity/Actors/Bullet.cs b/SuperPolarity/Actors/Bullet.cs new file mode 100644 index 0000000..d20289c --- /dev/null +++ b/SuperPolarity/Actors/Bullet.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class Bullet : Actor + { + protected ParticleEngine particleEngine; + public int Power; + + public Bullet(SuperPolarity newGame) + : base(newGame) + { + } + + ~Bullet() + { + particleEngine = null; + } + + public override void Initialize(Texture2D texture, Vector2 position) + { + base.Initialize(texture, position); + BoxDimensions.X = 10; + BoxDimensions.Y = 10; + BoxDimensions.W = 10; + BoxDimensions.Z = 10; + MaxVelocity = 8; + InitBox(); + particleEngine = ParticleEffectFactory.CreateBullet(position); + } + + public override void Update(GameTime gameTime) + { + Velocity.X = (float)(MaxVelocity * Math.Cos(Angle)); + Velocity.Y = (float)(MaxVelocity * Math.Sin(Angle)); + + Power = 1; + + Position += Velocity; + UpdateBox(); + + particleEngine.Update(); + particleEngine.EmitterLocation = Position; + } + + public override void Draw(SpriteBatch spriteBatch) + { + base.Draw(spriteBatch); + particleEngine.Draw(spriteBatch); + } + + public override void Collide(Actor other, Rectangle collision) + { + if (Dying) { return; } + if (other.GetType().IsAssignableFrom(typeof(StandardShip))) + { + Die(); + return; + } + } + + protected override void Die() + { + ActorManager.CheckOut(this); + Renderer.CheckOut(this); + Parent.Children.Remove(this); + } + + public override void CleanUp() + { + base.CleanUp(); + this.particleEngine = null; + } + } +} diff --git a/SuperPolarity/Actors/MainShip.cs b/SuperPolarity/Actors/MainShip.cs new file mode 100644 index 0000000..bf4f3bb --- /dev/null +++ b/SuperPolarity/Actors/MainShip.cs @@ -0,0 +1,314 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Audio; + +namespace SuperPolarity +{ + class MainShip : Ship + { + + public static Color BlueColor; + public static Color RedColor; + + ParticleEngine particleEngine; + + protected bool Shooting; + protected int ShotCooldown; + + protected float CurrentImmortalTime; + protected float MaxImmortalTime; + protected bool Flashing; + + protected SoundEffect PolarityChange; + protected SoundEffect ShootSound; + protected SoundEffect Hit; + + public MainShip(SuperPolarity newGame) : base(newGame) {} + + ~MainShip() + { + particleEngine = null; + } + + public override void Initialize(Texture2D texture, Vector2 position) + { + base.Initialize(texture, position); + + MainShip.BlueColor = new Color(211, 230, 234); + MainShip.RedColor = new Color(235, 160, 185); + + PolarityChange = game.Content.Load<SoundEffect>("Sound\\polaritychange"); + ShootSound = game.Content.Load<SoundEffect>("Sound\\bullet"); + Hit = game.Content.Load<SoundEffect>("Sound\\hit"); + + InitParticleEngine(); + SetPolarity(Polarity.Positive); + + ActVelocity = 2.5f; + + ShotCooldown = 50; + MaxImmortalTime = 1500; + + BoxDimensions.X = 2; + BoxDimensions.Y = 2; + BoxDimensions.W = 2; + BoxDimensions.Z = 2; + InitBox(); + + BindInput(); + } + + void InitParticleEngine() + { + particleEngine = ParticleEffectFactory.CreatePolarCircle(Position); + } + + void BindInput() + { + InputController.Bind("moveX", HandleHorizontalMovement); + InputController.Bind("moveY", HandleVerticalMovement); + InputController.Bind("changePolarity", HandleChangePolarity); + InputController.Bind("shoot", HandleShot); + } + + protected void HandleShot(float value) + { + + Shooting = true; + Timer t = new Timer(new TimerCallback(UnlockShot)); + t.Change(ShotCooldown, Timeout.Infinite); + + if (Children.Count > 10) + { + return; + } + + var bullet = ActorFactory.CreateBullet(Position, Angle); + + Children.Add(bullet); + bullet.Parent = this; + + ShootSound.Play(); + } + + protected void UnlockShot(object state) + { + InputController.Unlock("shoot"); + Shooting = false; + } + + protected void HandleChangePolarity(float value) + { + SwitchPolarity(); + } + + public void HandleHorizontalMovement(float value) + { + if (value >= -0.5 && value <= 0.5) + { + value = 0; + } + + Velocity.X = value * MaxVelocity; + } + + public void HandleVerticalMovement(float value) + { + if (value >= -0.5 && value <= 0.5) + { + value = 0; + } + + Velocity.Y = value * MaxVelocity; + } + + public override void SwitchPolarity() + { + base.SwitchPolarity(); + SwitchParticleEngine(CurrentPolarity); + PolarityChange.Play(); + game.Player.ResetMultiplier(); + } + + public override void SetPolarity(Polarity newPolarity) + { + base.SetPolarity(newPolarity); + SwitchParticleEngine(newPolarity); + } + + protected void SwitchParticleEngine(Polarity polarity) + { + if (polarity == Polarity.Positive) + { + particleEngine.Color = MainShip.RedColor; + } + else if (polarity == Polarity.Negative) + { + particleEngine.Color = MainShip.BlueColor; + } + else + { + particleEngine.Color = Color.Gray; + } + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + particleEngine.EmitterLocation = Position; + particleEngine.Update(); + ConstrainToEdges(); + UpdateImmortality(gameTime); + } + + public void UpdateImmortality(GameTime gameTime) + { + if (Immortal) + { + CurrentImmortalTime += gameTime.ElapsedGameTime.Milliseconds; + + if (Flashing) + { + Color = new Color(255, 255, 255, 128); + } + else + { + Color = Color.White; + } + + Flashing = !Flashing; + + if (CurrentImmortalTime > MaxImmortalTime) + { + Immortal = false; + Color = Color.White; + } + } + } + + public override void Move(GameTime gameTime) + { + var VelocityLimit = MaxVelocity; + var SavedVelocity = new Vector2(Velocity.X, Velocity.Y); + + if (Shooting) + { + VelocityLimit = ActVelocity; + } + + if (SavedVelocity.X > VelocityLimit) + { + SavedVelocity.X = VelocityLimit; + } + + if (SavedVelocity.X < -VelocityLimit) + { + SavedVelocity.X = -VelocityLimit; + } + + if (SavedVelocity.Y > VelocityLimit) + { + SavedVelocity.Y = VelocityLimit; + } + + if (SavedVelocity.Y < -VelocityLimit) + { + SavedVelocity.Y = -VelocityLimit; + } + + Position.X = Position.X + SavedVelocity.X; + Position.Y = Position.Y + SavedVelocity.Y; + } + + public override void Magnetize(Ship ship, float distance, float angle) + { + } + + protected void ConstrainToEdges() + { + if (Position.X < 0) + { + Position.X = 0; + + if (Velocity.X < 0) + { + Velocity.X = 0; + } + } + if (Position.X > game.GraphicsDevice.Viewport.Width) + { + Position.X = game.GraphicsDevice.Viewport.Width; + + if (Velocity.X > 0) + { + Velocity.X = 0; + } + } + if (Position.Y < 0) + { + Position.Y = 0; + + if (Velocity.Y < 0) + { + Velocity.Y = 0; + } + } + if (Position.Y > game.GraphicsDevice.Viewport.Height) + { + Position.Y = game.GraphicsDevice.Viewport.Height; + + if (Velocity.Y < 0) + { + Velocity.Y = 0; + } + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + particleEngine.Draw(spriteBatch); + base.Draw(spriteBatch); + } + + public override void Collide(Actor other, Rectangle collision) + { + if (other.GetType().IsAssignableFrom(typeof(StandardShip)) && + !Immortal) + { + Die(); + } + } + + protected override void Die() + { + game.Player.Lives = game.Player.Lives - 1; + game.Player.ResetMultiplier(); + if (game.Player.Lives < 0) + { + Dying = true; + game.GameOver(); + } + else { + Hit.Play(); + Immortal = true; + CurrentImmortalTime = 0; + } + } + + public override void CleanUp() + { + base.CleanUp(); + particleEngine = null; + InputController.Unbind("moveX", HandleHorizontalMovement); + InputController.Unbind("moveY", HandleVerticalMovement); + InputController.Unbind("changePolarity", HandleChangePolarity); + InputController.Unbind("shoot", HandleShot); + } + } +} diff --git a/SuperPolarity/Actors/Ship.cs b/SuperPolarity/Actors/Ship.cs new file mode 100644 index 0000000..229f639 --- /dev/null +++ b/SuperPolarity/Actors/Ship.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class Ship : Actor + { + public enum Polarity : byte { Negative, Positive, Neutral }; + + public Polarity CurrentPolarity; + public uint MagneticRadius; + + public float FleeVelocity; + public float ActVelocity; + public float ChargeVelocity; + public int RepelRadius; + + protected bool Magnetizing; + + public Ship(SuperPolarity newGame) : base(newGame) { + MagneticRadius = 250; + RepelRadius = 100; + + HP = 2; + + FleeVelocity = 5; + ActVelocity = 1; + ChargeVelocity = 2.5f; + CurrentPolarity = Polarity.Neutral; + Magnetizing = false; + } + + public virtual void SwitchPolarity() + { + if (CurrentPolarity == Polarity.Positive) + { + CurrentPolarity = Polarity.Negative; + } + else + { + CurrentPolarity = Polarity.Positive; + } + } + + public virtual void SetPolarity(Polarity newPolarity) + { + CurrentPolarity = newPolarity; + } + + public virtual void Shoot() + { + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + Magnetizing = false; + } + + public virtual void Magnetize(Ship ship, float distance, float angle) + { + Magnetizing = true; + Polarity polarity = ship.CurrentPolarity; + + if (polarity != CurrentPolarity) + { + Attract(angle); + } + else + { + Repel(distance, angle); + } + } + + protected void Attract(float angle) + { + Velocity.X = (float) (ChargeVelocity * Math.Cos(angle)); + Velocity.Y = (float) (ChargeVelocity * Math.Sin(angle)); + } + + protected void Repel(float distance, float angle) + { + if (distance > RepelRadius) { Magnetizing = false; return; } + Velocity.X = -(float)(FleeVelocity * Math.Cos(angle)); + Velocity.Y = -(float)(FleeVelocity * Math.Sin(angle)); + } + } +} diff --git a/SuperPolarity/Actors/StandardShip.cs b/SuperPolarity/Actors/StandardShip.cs new file mode 100644 index 0000000..ef2fe7f --- /dev/null +++ b/SuperPolarity/Actors/StandardShip.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Content; +using System.Security.Cryptography; + +namespace SuperPolarity +{ + class StandardShip : Ship + { + + protected bool Flashing; + protected int ChangeRate; + protected int CurrentTime; + public int AngleChangeProbability; + protected int BouncePadding; + protected float RotationFactor; + protected Random Random; + protected bool AddingAngle; + + public StandardShip(SuperPolarity newGame) : base(newGame) {} + + public override void Initialize(Texture2D texture, Vector2 position) + { + base.Initialize(texture, position); + + var cryptoResult = new byte[4]; + new RNGCryptoServiceProvider().GetBytes(cryptoResult); + + ChangeRate = 50; + AngleChangeProbability = 50; + BouncePadding = 0; + MaxVelocity = 2; + CurrentTime = 0; + RotationFactor = (float) (3 * Math.PI / 180); + Random = new Random(BitConverter.ToInt32(cryptoResult, 0)); + AddingAngle = true; + } + + public override void Magnetize(Ship ship, float distance, float angle) + { + if (ship.GetType() == typeof(MainShip)) { + base.Magnetize(ship, distance, angle); + } + } + + public override void Update(GameTime gameTime) + { + CurrentTime += gameTime.ElapsedGameTime.Milliseconds; + if (!Magnetizing) + { + AutoMove(); + BounceBack(); + } + ChangeAngle(); + Position += Velocity; + UpdateBox(); + Magnetizing = false; + + if (Flashing) + { + Color = new Color(255, 255, 255, 128); + Flashing = false; + } + else + { + Color = Color.White; + } + } + + protected void AutoMove() + { + float newAngle = Angle; + + if (CurrentTime < ChangeRate) + { + return; + } + + if (Random.Next(AngleChangeProbability) == 2) + { + AddingAngle = !AddingAngle; + } + + CurrentTime = 0; + + if (AddingAngle) + { + newAngle += (float) ( Random.NextDouble() * RotationFactor); + } + else + { + newAngle -= (float) (Random.NextDouble() * RotationFactor); + } + + Velocity.X = (float) (MaxVelocity * Math.Cos(newAngle)); + Velocity.Y = (float) (MaxVelocity * Math.Sin(newAngle)); + } + + protected void BounceBack() + { + if (Position.X + Width < -BouncePadding && Velocity.X < 0) + { + Velocity.X = -Velocity.X; + } + + if (Position.Y + Height < -BouncePadding && Velocity.Y < 0) + { + Velocity.Y = -Velocity.Y; + } + + if (Position.X > game.GraphicsDevice.Viewport.Width + BouncePadding && Velocity.X > 0) + { + Velocity.X = -Velocity.X; + } + + if (Position.Y > game.GraphicsDevice.Viewport.Height + BouncePadding && Velocity.Y > 0) + { + Velocity.Y = -Velocity.Y; + } + } + + public override void Collide(Actor other, Rectangle collision) + { + if (Dying) + { + return; + } + + if (other.GetType() == typeof(MainShip)) + { + Die(); + return; + } + + if (other.GetType() == typeof(Bullet)) + { + var theBullet = (Bullet)other; + TakeDamage(theBullet.Power); + Flashing = true; + } + } + + protected override void Die() + { + ActorManager.CheckOut(this); + Renderer.CheckOut(this); + game.Player.AddScore(Value); + game.Player.AddMultiplier(1); + } + } +} diff --git a/SuperPolarity/BasicGenerator.cs b/SuperPolarity/BasicGenerator.cs new file mode 100644 index 0000000..ba51742 --- /dev/null +++ b/SuperPolarity/BasicGenerator.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; + +namespace SuperPolarity +{ + class BasicGenerator + { + public enum Ships : byte { Ship, Scout, Battlecruiser }; + + protected Ships ShipType; + protected SuperPolarity Game; + protected int ScoreThreshold; + protected int Rate; + protected int CurrentTime; + protected Random Randomizer; + protected Vector2 Position; + + public void Initialize(SuperPolarity game, Vector2 position, Ships shipType, int rate, int scoreThreshold) + { + Game = game; + ShipType = shipType; + ScoreThreshold = scoreThreshold; + Rate = rate; + Randomizer = new Random(); + Position = position; + CurrentTime = rate; + } + + public void Update(GameTime gameTime) + { + if (ActorManager.CountBaddies() > 50) + { + return; + } + + if (Game.Player.Score >= ScoreThreshold) + { + CurrentTime = CurrentTime + gameTime.ElapsedGameTime.Milliseconds; + + if (CurrentTime >= Rate) + { + CurrentTime = 0; + Spawn(); + } + } + } + + protected void Spawn() + { + var polarity = Ship.Polarity.Positive; + + if (Randomizer.Next(2) == 1) + { + polarity = Ship.Polarity.Negative; + } + + if (ShipType == Ships.Ship) + { + Renderer.CheckIn(ActorFactory.CreateShip(polarity, Position)); + } + + if (ShipType == Ships.Scout) + { + Renderer.CheckIn(ActorFactory.CreateScout(polarity, Position)); + } + + if (ShipType == Ships.Battlecruiser) + { + Renderer.CheckIn(ActorFactory.CreateCruiser(polarity, Position)); + } + + } + } +} diff --git a/SuperPolarity/Content/Fonts/SegoeUIMono14.xnb b/SuperPolarity/Content/Fonts/SegoeUIMono14.xnb Binary files differnew file mode 100644 index 0000000..51c4abd --- /dev/null +++ b/SuperPolarity/Content/Fonts/SegoeUIMono14.xnb diff --git a/SuperPolarity/Content/Fonts/bigfont.xnb b/SuperPolarity/Content/Fonts/bigfont.xnb Binary files differnew file mode 100644 index 0000000..c1d876c --- /dev/null +++ b/SuperPolarity/Content/Fonts/bigfont.xnb diff --git a/SuperPolarity/Content/Fonts/smallfont.xnb b/SuperPolarity/Content/Fonts/smallfont.xnb Binary files differnew file mode 100644 index 0000000..a87e66a --- /dev/null +++ b/SuperPolarity/Content/Fonts/smallfont.xnb diff --git a/SuperPolarity/Content/Graphics/circle.xnb b/SuperPolarity/Content/Graphics/circle.xnb Binary files differnew file mode 100644 index 0000000..3471449 --- /dev/null +++ b/SuperPolarity/Content/Graphics/circle.xnb diff --git a/SuperPolarity/Content/Graphics/diamond.xnb b/SuperPolarity/Content/Graphics/diamond.xnb Binary files differnew file mode 100644 index 0000000..8bda70c --- /dev/null +++ b/SuperPolarity/Content/Graphics/diamond.xnb diff --git a/SuperPolarity/Content/Graphics/main-ship.xnb b/SuperPolarity/Content/Graphics/main-ship.xnb Binary files differnew file mode 100644 index 0000000..7108e2f --- /dev/null +++ b/SuperPolarity/Content/Graphics/main-ship.xnb diff --git a/SuperPolarity/Content/Graphics/negative-cruiser.xnb b/SuperPolarity/Content/Graphics/negative-cruiser.xnb Binary files differnew file mode 100644 index 0000000..5c9f41d --- /dev/null +++ b/SuperPolarity/Content/Graphics/negative-cruiser.xnb diff --git a/SuperPolarity/Content/Graphics/negative-destroyer.xnb b/SuperPolarity/Content/Graphics/negative-destroyer.xnb Binary files differnew file mode 100644 index 0000000..fe13745 --- /dev/null +++ b/SuperPolarity/Content/Graphics/negative-destroyer.xnb diff --git a/SuperPolarity/Content/Graphics/negative-scout.xnb b/SuperPolarity/Content/Graphics/negative-scout.xnb Binary files differnew file mode 100644 index 0000000..a5a2e7a --- /dev/null +++ b/SuperPolarity/Content/Graphics/negative-scout.xnb diff --git a/SuperPolarity/Content/Graphics/negative-ship.xnb b/SuperPolarity/Content/Graphics/negative-ship.xnb Binary files differnew file mode 100644 index 0000000..ed41216 --- /dev/null +++ b/SuperPolarity/Content/Graphics/negative-ship.xnb diff --git a/SuperPolarity/Content/Graphics/negative-supercruiser.xnb b/SuperPolarity/Content/Graphics/negative-supercruiser.xnb Binary files differnew file mode 100644 index 0000000..b77f364 --- /dev/null +++ b/SuperPolarity/Content/Graphics/negative-supercruiser.xnb diff --git a/SuperPolarity/Content/Graphics/neutral-cruiser.xnb b/SuperPolarity/Content/Graphics/neutral-cruiser.xnb Binary files differnew file mode 100644 index 0000000..ac99113 --- /dev/null +++ b/SuperPolarity/Content/Graphics/neutral-cruiser.xnb diff --git a/SuperPolarity/Content/Graphics/neutral-destroyer.xnb b/SuperPolarity/Content/Graphics/neutral-destroyer.xnb Binary files differnew file mode 100644 index 0000000..69b5924 --- /dev/null +++ b/SuperPolarity/Content/Graphics/neutral-destroyer.xnb diff --git a/SuperPolarity/Content/Graphics/neutral-scout.xnb b/SuperPolarity/Content/Graphics/neutral-scout.xnb Binary files differnew file mode 100644 index 0000000..5e9ff59 --- /dev/null +++ b/SuperPolarity/Content/Graphics/neutral-scout.xnb diff --git a/SuperPolarity/Content/Graphics/neutral-ship.xnb b/SuperPolarity/Content/Graphics/neutral-ship.xnb Binary files differnew file mode 100644 index 0000000..04259be --- /dev/null +++ b/SuperPolarity/Content/Graphics/neutral-ship.xnb diff --git a/SuperPolarity/Content/Graphics/neutral-supercruiser.xnb b/SuperPolarity/Content/Graphics/neutral-supercruiser.xnb Binary files differnew file mode 100644 index 0000000..1389842 --- /dev/null +++ b/SuperPolarity/Content/Graphics/neutral-supercruiser.xnb diff --git a/SuperPolarity/Content/Graphics/pause-screen.xnb b/SuperPolarity/Content/Graphics/pause-screen.xnb Binary files differnew file mode 100644 index 0000000..2307009 --- /dev/null +++ b/SuperPolarity/Content/Graphics/pause-screen.xnb diff --git a/SuperPolarity/Content/Graphics/polaritydemotitle.xnb b/SuperPolarity/Content/Graphics/polaritydemotitle.xnb Binary files differnew file mode 100644 index 0000000..2fa9cf3 --- /dev/null +++ b/SuperPolarity/Content/Graphics/polaritydemotitle.xnb diff --git a/SuperPolarity/Content/Graphics/positive-cruiser.xnb b/SuperPolarity/Content/Graphics/positive-cruiser.xnb Binary files differnew file mode 100644 index 0000000..b65d2bd --- /dev/null +++ b/SuperPolarity/Content/Graphics/positive-cruiser.xnb diff --git a/SuperPolarity/Content/Graphics/positive-destroyer.xnb b/SuperPolarity/Content/Graphics/positive-destroyer.xnb Binary files differnew file mode 100644 index 0000000..d773175 --- /dev/null +++ b/SuperPolarity/Content/Graphics/positive-destroyer.xnb diff --git a/SuperPolarity/Content/Graphics/positive-scout.xnb b/SuperPolarity/Content/Graphics/positive-scout.xnb Binary files differnew file mode 100644 index 0000000..2b8f9fe --- /dev/null +++ b/SuperPolarity/Content/Graphics/positive-scout.xnb diff --git a/SuperPolarity/Content/Graphics/positive-ship.xnb b/SuperPolarity/Content/Graphics/positive-ship.xnb Binary files differnew file mode 100644 index 0000000..e4e21f1 --- /dev/null +++ b/SuperPolarity/Content/Graphics/positive-ship.xnb diff --git a/SuperPolarity/Content/Graphics/positive-supercruiser.xnb b/SuperPolarity/Content/Graphics/positive-supercruiser.xnb Binary files differnew file mode 100644 index 0000000..2ecca79 --- /dev/null +++ b/SuperPolarity/Content/Graphics/positive-supercruiser.xnb diff --git a/SuperPolarity/Content/Graphics/square.xnb b/SuperPolarity/Content/Graphics/square.xnb Binary files differnew file mode 100644 index 0000000..5a88d89 --- /dev/null +++ b/SuperPolarity/Content/Graphics/square.xnb diff --git a/SuperPolarity/Content/Graphics/star.xnb b/SuperPolarity/Content/Graphics/star.xnb Binary files differnew file mode 100644 index 0000000..763addf --- /dev/null +++ b/SuperPolarity/Content/Graphics/star.xnb diff --git a/SuperPolarity/Content/Sound/bomb.wav b/SuperPolarity/Content/Sound/bomb.wav Binary files differnew file mode 100644 index 0000000..5af439b --- /dev/null +++ b/SuperPolarity/Content/Sound/bomb.wav diff --git a/SuperPolarity/Content/Sound/bullet.wav b/SuperPolarity/Content/Sound/bullet.wav Binary files differnew file mode 100644 index 0000000..6586489 --- /dev/null +++ b/SuperPolarity/Content/Sound/bullet.wav diff --git a/SuperPolarity/Content/Sound/gameover.wav b/SuperPolarity/Content/Sound/gameover.wav Binary files differnew file mode 100644 index 0000000..cac9d23 --- /dev/null +++ b/SuperPolarity/Content/Sound/gameover.wav diff --git a/SuperPolarity/Content/Sound/hit.wav b/SuperPolarity/Content/Sound/hit.wav Binary files differnew file mode 100644 index 0000000..43433cd --- /dev/null +++ b/SuperPolarity/Content/Sound/hit.wav diff --git a/SuperPolarity/Content/Sound/life.wav b/SuperPolarity/Content/Sound/life.wav Binary files differnew file mode 100644 index 0000000..a1d0436 --- /dev/null +++ b/SuperPolarity/Content/Sound/life.wav diff --git a/SuperPolarity/Content/Sound/polaritychange.wav b/SuperPolarity/Content/Sound/polaritychange.wav Binary files differnew file mode 100644 index 0000000..25b59a4 --- /dev/null +++ b/SuperPolarity/Content/Sound/polaritychange.wav diff --git a/SuperPolarity/Content/Sound/polaritytheme.wav b/SuperPolarity/Content/Sound/polaritytheme.wav Binary files differnew file mode 100644 index 0000000..28a6bce --- /dev/null +++ b/SuperPolarity/Content/Sound/polaritytheme.wav diff --git a/SuperPolarity/GameScreen.cs b/SuperPolarity/GameScreen.cs new file mode 100644 index 0000000..783e3c1 --- /dev/null +++ b/SuperPolarity/GameScreen.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Media; +using Microsoft.Xna.Framework.Input; + +namespace SuperPolarity +{ + class GameScreen : Screen + { + public GameScreen(SuperPolarity newGame) : base(newGame) {} + + protected List<BasicGenerator> Generators; + + protected int LivesRate; + protected int CurrentLivesRate; + protected int BombRate; + protected int CurrentBombRate; + protected SoundEffect BombSound; + protected SoundEffect LifeSound; + + protected bool Flashing; + + protected bool IsPaused; + protected Texture2D PauseScreen; + + public override void Initialize() + { + Generators = new List<BasicGenerator>(); + + CurrentBombRate = 1; + BombRate = 6000; + + LivesRate = 10000; + CurrentLivesRate = 1; + + InputController.RegisterEventForButton("changePolarity", Buttons.A); + InputController.RegisterEventForKey("changePolarity", Keys.Z); + + InputController.RegisterEventForButton("shoot", Buttons.X); + InputController.RegisterEventForKey("shoot", Keys.X); + + InputController.Bind("pause", HandlePause); + + PauseScreen = Game.Content.Load<Texture2D>("Graphics\\pause-screen"); + } + + protected void HandlePause(float value) + { + Console.WriteLine("Paused"); + IsPaused = !IsPaused; + + if (IsPaused) + { + MediaPlayer.Volume = 0.05f; + } + else + { + MediaPlayer.Volume = 1; + } + } + + public override void LoadContent() + { + CreateGenerators(); + + Vector2 playerPosition = new Vector2(Game.GraphicsDevice.Viewport.TitleSafeArea.X + Game.GraphicsDevice.Viewport.Width / 2, Game.GraphicsDevice.Viewport.TitleSafeArea.Y + Game.GraphicsDevice.Viewport.TitleSafeArea.Height / 2); + + BombSound = Game.Content.Load<SoundEffect>("Sound\\bomb"); + LifeSound = Game.Content.Load<SoundEffect>("Sound\\life"); + + Renderer.CheckIn(ActorFactory.CreateMainShip(playerPosition)); + + Game.PlaySong("game"); + } + + protected void CalculateBomb() + { + if (Game.Player.Score >= BombRate * CurrentBombRate) + { + ActorManager.Bomb(); + Flashing = true; + BombSound.Play(); + CurrentBombRate = CurrentBombRate + 1; + } + } + + protected void CalculateLife() + { + if (Game.Player.Score >= LivesRate * CurrentLivesRate) + { + Game.Player.Lives = Game.Player.Lives + 1; + LifeSound.Play(); + CurrentLivesRate = CurrentLivesRate + 1; + } + } + + public override void Update(GameTime gameTime) + { + CalculateBomb(); + CalculateLife(); + InputController.UpdateInput(IsPaused); + if (IsPaused) + { + return; + } + ActorManager.Update(gameTime); + + foreach (BasicGenerator generator in Generators) + { + generator.Update(gameTime); + } + } + + public override void Draw(SpriteBatch spriteBatch) + { + Renderer.Draw(spriteBatch); + Game.Player.Draw(spriteBatch); + + if (IsPaused) + { + spriteBatch.Draw(PauseScreen, new Vector2(0, 0), Color.White); + } + + if (Flashing) + { + Game.GraphicsDevice.Clear(Color.Black); + Flashing = false; + } + } + + protected void CreateGenerators() + { + // The basic ship generators. + var gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(-50, -50), BasicGenerator.Ships.Ship, 3000, 0); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(-50, Game.GraphicsDevice.Viewport.Height + 50), BasicGenerator.Ships.Ship, 3000, 0); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width + 50, -50), BasicGenerator.Ships.Ship, 3000, 0); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width + 50, Game.GraphicsDevice.Viewport.Height + 50), BasicGenerator.Ships.Ship, 3000, 0); + Generators.Add(gen); + + // After 1.5k liberate some sporadic Scouts, and add two more ship generators. + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width / 2, -50), BasicGenerator.Ships.Ship, 3000, 1500); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width / 2, Game.GraphicsDevice.Viewport.Height + 50), BasicGenerator.Ships.Ship, 3000, 1500); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(-50, Game.GraphicsDevice.Viewport.Height / 2), BasicGenerator.Ships.Scout, 6000, 1500); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width + 50, Game.GraphicsDevice.Viewport.Height / 2), BasicGenerator.Ships.Scout, 6000, 1500); + Generators.Add(gen); + + + // After 3k add more scouts. + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width / 2, -50), BasicGenerator.Ships.Scout, 3000, 3000); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width / 2, Game.GraphicsDevice.Viewport.Height + 50), BasicGenerator.Ships.Scout, 3000, 5000); + Generators.Add(gen); + + // After 5k release more ships and a cruiser. + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width / 2, -50), BasicGenerator.Ships.Ship, 1500, 5000); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width / 2, Game.GraphicsDevice.Viewport.Height + 50), BasicGenerator.Ships.Ship, 1500, 5000); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(-50, Game.GraphicsDevice.Viewport.Height / 2), BasicGenerator.Ships.Battlecruiser, 10000, 5000); + Generators.Add(gen); + + gen = new BasicGenerator(); + gen.Initialize(Game, new Vector2(Game.GraphicsDevice.Viewport.Width + 50, Game.GraphicsDevice.Viewport.Height / 2), BasicGenerator.Ships.Battlecruiser, 10000, 5000); + Generators.Add(gen); + } + + public override void CleanUp() + { + base.CleanUp(); + Generators.Clear(); + InputController.Unbind("pause", HandlePause); + Renderer.Empty(); + ActorManager.Empty(); + } + } +} diff --git a/SuperPolarity/Icon.ico b/SuperPolarity/Icon.ico Binary files differnew file mode 100644 index 0000000..13be62a --- /dev/null +++ b/SuperPolarity/Icon.ico diff --git a/SuperPolarity/InputController.cs b/SuperPolarity/InputController.cs new file mode 100644 index 0000000..c92bb9c --- /dev/null +++ b/SuperPolarity/InputController.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework.Input; + +namespace SuperPolarity +{ + static class InputController + { + static Dictionary<string, List<Action<float>>> Listeners; + static Dictionary<string, List<Keys>> RegisteredKeys; + static Dictionary<string, List<Buttons>> RegisteredButtons; + static List<string> BlockedKeys; + static List<string> BlockedButtons; + + static GamePadState InputGamePadState; + static KeyboardState InputKeyboardState; + + /* + * Registered Events. + * + * You register: name of the event (ie. attack) and a key associated with it. + * or button... Left Stick /always/ dispatches move event. + */ + + static InputController() + { + Listeners = new Dictionary<string,List<Action<float>>>(); + RegisteredButtons = new Dictionary<string, List<Buttons>>(); + RegisteredKeys = new Dictionary<string, List<Keys>>(); + BlockedKeys = new List<string>(); + BlockedButtons = new List<string>(); + InputKeyboardState = new KeyboardState(); + InputGamePadState = new GamePadState(); + } + + public static void UpdateInput() + { + DispatchMoveEvents(); + DispatchRegisteredEvents(); + } + + public static void UpdateInput(bool highPriorityOnly) + { + Poll(); + DispatchPauseEvent(); + if (!highPriorityOnly) + { + UpdateInput(); + } + } + + public static void DispatchPauseEvent() + { + // OK THIS IS ALL KINDS OF WRONG. THIS IS A PLACEHOLDER BECAUSE DEMO! + var keyPressed = false; + if ((InputKeyboardState.IsKeyDown(Keys.Enter) || InputGamePadState.IsButtonDown(Buttons.Start))) { + keyPressed = true; + if(!BlockedButtons.Contains("pause") && !BlockedKeys.Contains("pause")) + { + BlockedButtons.Add("pause"); + BlockedKeys.Add("pause"); + Console.WriteLine("Dispatch"); + Dispatch("pause", 0); + } + } + + if (!keyPressed) + { + BlockedButtons.Remove("pause"); + BlockedKeys.Remove("pause"); + } + } + + private static void Poll() + { + InputGamePadState = GamePad.GetState(Microsoft.Xna.Framework.PlayerIndex.One); + InputKeyboardState = Keyboard.GetState(); + } + + public static void RegisterEventForKey(string eventName, Keys key) + { + List<Keys> newKeyList; + if (!RegisteredKeys.ContainsKey(eventName)) + { + newKeyList = new List<Keys>(); + RegisteredKeys.Add(eventName, newKeyList); + } + + RegisteredKeys.TryGetValue(eventName, out newKeyList); + + newKeyList.Add(key); + } + + public static void RegisterEventForButton(string eventName, Buttons button) + { + List<Buttons> newButtonList; + if (!RegisteredButtons.ContainsKey(eventName)) + { + newButtonList = new List<Buttons>(); + RegisteredButtons.Add(eventName, newButtonList); + } + + RegisteredButtons.TryGetValue(eventName, out newButtonList); + + newButtonList.Add(button); + } + + private static void DispatchRegisteredEvents() + { + var keyFired = false; + + foreach (KeyValuePair<string,List<Keys>> entry in RegisteredKeys) { + keyFired = false; + foreach (Keys key in entry.Value) + { + if (InputKeyboardState.IsKeyDown(key)) + { + if (!BlockedKeys.Contains(entry.Key)) + { + BlockedKeys.Add(entry.Key); + Dispatch(entry.Key, 1); + } + keyFired = true; + break; + } + } + + if (!keyFired) + { + BlockedKeys.Remove(entry.Key); + } + } + + foreach (KeyValuePair<string, List<Buttons>> entry in RegisteredButtons) + { + keyFired = false; + foreach (Buttons button in entry.Value) + { + if (InputGamePadState.IsButtonDown(button)) + { + if (!BlockedButtons.Contains(entry.Key)) + { + BlockedButtons.Add(entry.Key); + Dispatch(entry.Key, 1); + } + keyFired = true; + break; + }; + } + + if (!keyFired) + { + BlockedButtons.Remove(entry.Key); + } + } + } + + private static void DispatchMoveEvents() + { + float xMovement = 0.0f; + float yMovement = 0.0f; + // Dispatch the moveX / MoveY events every frame. + + xMovement = InputGamePadState.ThumbSticks.Left.X; + yMovement = -InputGamePadState.ThumbSticks.Left.Y; + + if (InputKeyboardState.IsKeyDown(Keys.Left)) + { + xMovement = -1.0f; + } + + if (InputKeyboardState.IsKeyDown(Keys.Right)) + { + xMovement = 1.0f; + } + + if (InputKeyboardState.IsKeyDown(Keys.Up)) + { + yMovement = -1.0f; + } + + if (InputKeyboardState.IsKeyDown(Keys.Down)) + { + yMovement = 1.0f; + } + + Dispatch("moveX", xMovement); + Dispatch("moveY", yMovement); + } + + public static void Bind(string eventName, Action<float> listener) + { + List<Action<float>> newListenerList; + List<Action<float>> listenerList; + bool foundListeners; + + if (!Listeners.ContainsKey(eventName)) { + newListenerList = new List<Action<float>>(); + Listeners.Add(eventName, newListenerList); + } + + foundListeners = Listeners.TryGetValue(eventName, out listenerList); + + listenerList.Add(listener); + } + + public static void Unbind(string eventName, Action<float> listener) + { + List<Action<float>> listenerList; + bool foundListeners; + + if (!Listeners.ContainsKey(eventName)) + { + return; + } + + foundListeners = Listeners.TryGetValue(eventName, out listenerList); + + listenerList.Remove(listener); + } + + public static void Dispatch(string eventName, float value) + { + List<Action<float>> listenerList; + bool foundListeners; + + foundListeners = Listeners.TryGetValue(eventName, out listenerList); + + if (!foundListeners) + { + return; + } + + for (var i = listenerList.Count - 1; i >= 0; i--) + { + listenerList[i](value); + } + } + + public static void Unlock(string eventName) + { + BlockedButtons.Remove(eventName); + BlockedKeys.Remove(eventName); + } + } +} diff --git a/SuperPolarity/LetterChooseWidget.cs b/SuperPolarity/LetterChooseWidget.cs new file mode 100644 index 0000000..e52733f --- /dev/null +++ b/SuperPolarity/LetterChooseWidget.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class LetterChooseWidget : Widget + { + int CurrentChar; + bool Locked; + int LockRate; + int CurrentTime; + + SpriteFont Font; + + public LetterChooseWidget(SuperPolarity game, Vector2 position) : base(game, position) + { + Active = false; + CurrentChar = 65; + Font = game.Content.Load<SpriteFont>("Fonts\\bigfont"); + LockRate = 300; + CurrentTime = 0; + + InputController.Bind("moveY", HandleMovement); + } + + public void HandleMovement(float value) + { + if (!Active) { return; } + + if (value > 0.8 && !Locked) { + CurrentChar = CurrentChar + 1; + + if (CurrentChar > 90) + { + CurrentChar = 32; + } + + Locked = true; + } + + if (value < -0.8 && !Locked) { + CurrentChar = CurrentChar - 1; + + if (CurrentChar < 32) + { + CurrentChar = 90; + } + + Locked = true; + } + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + + CurrentTime = CurrentTime + gameTime.ElapsedGameTime.Milliseconds; + if (CurrentTime > LockRate) + { + CurrentTime = 0; + Locked = false; + } + } + + public string Value() + { + return char.ConvertFromUtf32(CurrentChar); + } + + public override void Draw(SpriteBatch spriteBatch) + { + var color = new Color(0, 0, 0, 128); + if (Active) + { + color = new Color(201, 0, 68, 255); + } + spriteBatch.DrawString(Font, Value(), Position, color); + } + } +} diff --git a/SuperPolarity/MenuItem.cs b/SuperPolarity/MenuItem.cs new file mode 100644 index 0000000..8e24c97 --- /dev/null +++ b/SuperPolarity/MenuItem.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SuperPolarity +{ + class MenuItem + { + } +} diff --git a/SuperPolarity/MenuWidget.cs b/SuperPolarity/MenuWidget.cs new file mode 100644 index 0000000..992ef43 --- /dev/null +++ b/SuperPolarity/MenuWidget.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SuperPolarity +{ + class MenuWidget + { + } +} diff --git a/SuperPolarity/NameChooserWidget.cs b/SuperPolarity/NameChooserWidget.cs new file mode 100644 index 0000000..ce7c149 --- /dev/null +++ b/SuperPolarity/NameChooserWidget.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class NameChooserWidget : Widget + { + int CurrentIndex; + bool Lock; + int LockRate; + int CurrentTime; + + public NameChooserWidget(SuperPolarity game, Vector2 position) + : base(game, position) + { + AppendChild(new LetterChooseWidget(game, new Vector2(position.X, position.Y))); + AppendChild(new LetterChooseWidget(game, new Vector2(position.X + 32, position.Y))); + AppendChild(new LetterChooseWidget(game, new Vector2(position.X + 64, position.Y))); + CurrentIndex = 0; + Children[CurrentIndex].Activate(); + LockRate = 300; + CurrentTime = 0; + + InputController.Bind("moveX", HandleMovement); + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + + CurrentTime = CurrentTime + gameTime.ElapsedGameTime.Milliseconds; + if (CurrentTime > LockRate) + { + CurrentTime = 0; + Lock = false; + } + + foreach (LetterChooseWidget widget in Children) + { + widget.Update(gameTime); + } + } + + public void HandleMovement(float value) + { + if (value > 0.8 && !Lock) + { + Children[CurrentIndex].Deactivate(); + CurrentIndex = CurrentIndex + 1; + + if (CurrentIndex > Children.Count - 1) + { + CurrentIndex = 0; + } + + Lock = true; + } + + if (value < -0.8 && !Lock) + { + Children[CurrentIndex].Deactivate(); + CurrentIndex = CurrentIndex - 1; + + if (CurrentIndex < 0) + { + CurrentIndex = Children.Count - 1; + } + + Lock = true; + } + + Children[CurrentIndex].Activate(); + } + + public string Value() + { + var name = ""; + + foreach (LetterChooseWidget letter in Children) + { + name = name + letter.Value(); + } + + return name; + } + + public override void Draw(SpriteBatch spriteBatch) + { + foreach (LetterChooseWidget widget in Children) + { + widget.Draw(spriteBatch); + } + } + } +} diff --git a/SuperPolarity/Particle.cs b/SuperPolarity/Particle.cs new file mode 100644 index 0000000..d65bac6 --- /dev/null +++ b/SuperPolarity/Particle.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class Particle + { + public Texture2D Texture { get; set; } + public Vector2 Position { get; set; } + public Vector2 Velocity { get; set; } + public float Angle { get; set; } + public float AngularVelocity { get; set; } + public Color Color { get; set; } + public float Size { get; set; } + public int TTL { get; set; } + + public Particle(Texture2D texture, Vector2 position, Vector2 velocity, + float angle, float angularVelocity, Color color, float size, int ttl) + { + Texture = texture; + Position = position; + Velocity = velocity; + Angle = angle; + AngularVelocity = angularVelocity; + Color = color; + Size = size; + TTL = ttl; + } + + public void Update() + { + TTL--; + Position += Velocity; + Angle += AngularVelocity; + } + + public void Draw(SpriteBatch spriteBatch) + { + Rectangle sourceRectangle = new Rectangle(0, 0, Texture.Width, Texture.Height); + Vector2 origin = new Vector2(Texture.Width / 2, Texture.Height / 2); + + spriteBatch.Draw(Texture, Position, sourceRectangle, Color, + Angle, origin, Size, SpriteEffects.None, 0f); + } + + } +} diff --git a/SuperPolarity/ParticleEffectFactory.cs b/SuperPolarity/ParticleEffectFactory.cs new file mode 100644 index 0000000..0cd9ed3 --- /dev/null +++ b/SuperPolarity/ParticleEffectFactory.cs @@ -0,0 +1,66 @@ +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 ParticleEffectFactory + { + static Game Game; + static Random random; + + static ParticleEffectFactory() + { + random = new Random(); + } + + public static ParticleEngine CreatePolarCircle(Vector2 location) + { + List<Texture2D> texturesList = new List<Texture2D>(); + + //texturesList.Add(Game.Content.Load<Texture2D>("Graphics\\circle")); + texturesList.Add(Game.Content.Load<Texture2D>("Graphics\\diamond")); + texturesList.Add(Game.Content.Load<Texture2D>("Graphics\\square")); + + ParticleEngine particleEngine = new ParticleEngine(texturesList, location); + + particleEngine.Color = new Color(239, 203, 204); + particleEngine.TTL = 10; + particleEngine.TTLRandomFactor = 5; + particleEngine.ScatterFactor = 40; + particleEngine.ParticleCount = 50; + particleEngine.StretchFactor = 2.8f; + + + return particleEngine; + } + + public static ParticleEngine CreateBullet(Vector2 location) + { + List<Texture2D> texturesList = new List<Texture2D>(); + + texturesList.Add(Game.Content.Load<Texture2D>("Graphics\\circle")); + //texturesList.Add(Game.Content.Load<Texture2D>("Graphics\\diamond")); + texturesList.Add(Game.Content.Load<Texture2D>("Graphics\\square")); + + ParticleEngine particleEngine = new ParticleEngine(texturesList, location); + + particleEngine.Color = Color.Gray; + particleEngine.TTL = 5; + particleEngine.TTLRandomFactor = 5; + particleEngine.ScatterFactor = 5; + particleEngine.ParticleCount = 10; + particleEngine.StretchFactor = 1; + + return particleEngine; + } + + internal static void SetGame(Game game) + { + ParticleEffectFactory.Game = game; + } + } +} diff --git a/SuperPolarity/ParticleEngine.cs b/SuperPolarity/ParticleEngine.cs new file mode 100644 index 0000000..51188ae --- /dev/null +++ b/SuperPolarity/ParticleEngine.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class ParticleEngine + { + private Random random; + public Vector2 EmitterLocation { get; set; } + public Color Color; //TODO: Color list for random colors. + public int TTL; + public int TTLRandomFactor; + public int ScatterFactor; + public int ParticleCount; + public float StretchFactor; + private List<Particle> particles; + private List<Texture2D> textures; + + public ParticleEngine(List<Texture2D> textures, Vector2 location) + { + EmitterLocation = location; + this.textures = textures; + this.particles = new List<Particle>(); + random = new Random(); + Color = Color.Red; + TTL = 20; + TTLRandomFactor = 40; + StretchFactor = 1; + } + + private Particle GenerateNewParticle() + { + Texture2D texture = textures[random.Next(textures.Count)]; + Vector2 position = EmitterLocation; + Vector2 velocity = new Vector2( + 1f * (float)(random.NextDouble() * 2 - 1), + 1f * (float)(random.NextDouble() * 2 - 1)); + + float angle = 0; + float angularVelocity = 0.1f * (float)(random.NextDouble() * 2 - 1); + Color color = Color; + float size = (float)random.NextDouble() * StretchFactor; + + position.X += random.Next(-ScatterFactor, ScatterFactor); + position.Y += random.Next(-ScatterFactor, ScatterFactor); + + int ttl = TTL + random.Next(TTLRandomFactor); + + return new Particle(texture, position, velocity, angle, angularVelocity, color, size, ttl); + } + + public void Update() + { + int total = 10; + + for (int i = 0; i < total; i++) + { + particles.Add(GenerateNewParticle()); + } + + for (int particle = 0; particle < particles.Count; particle++) + { + particles[particle].Update(); + if (particles[particle].TTL <= 0) + { + particles.RemoveAt(particle); + particle--; + } + } + } + + public void Draw(SpriteBatch spriteBatch) + { + //spriteBatch.Begin(); + for (int index = 0; index < particles.Count; index++) + { + particles[index].Draw(spriteBatch); + } + //spriteBatch.End(); + } + } +} diff --git a/SuperPolarity/Player.cs b/SuperPolarity/Player.cs new file mode 100644 index 0000000..184abdd --- /dev/null +++ b/SuperPolarity/Player.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + public class Player + { + public int Score; + public int Multiplier; + public int Lives; + + + SpriteFont DebugFont; + SuperPolarity Game; + + Texture2D LifeSprite; + + public Player(SuperPolarity game) + { + Score = 0; + Multiplier = 1; + Lives = 3; + Game = game; + DebugFont = Game.Content.Load<SpriteFont>("Fonts\\bigfont"); + LifeSprite = Game.Content.Load<Texture2D>("Graphics\\neutral-ship"); + } + + public void AddScore(int value) + { + Score = Score + (value * Multiplier); + } + + public void AddMultiplier(int value) + { + Multiplier = Multiplier + 1; + } + + public void ResetMultiplier() + { + Multiplier = 1; + } + + public void Draw(SpriteBatch spriteBatch) + { + var UiColor = new Color(0, 0, 0, 200); + var lightColor = new Color(0, 0, 0, 128); + spriteBatch.DrawString(DebugFont, Score.ToString(), new Vector2(40, 30), UiColor); + spriteBatch.DrawString(DebugFont, "x" + Multiplier.ToString(), new Vector2(40, 50), lightColor); + + var lifePosition = new Vector2(Game.GraphicsDevice.Viewport.Width - 140, 30); + if (Lives > 4) + { + spriteBatch.Draw(LifeSprite, lifePosition, null, UiColor, (float)(Math.PI / 2), Vector2.Zero, 0.5f, SpriteEffects.None, 0f); + spriteBatch.DrawString(DebugFont, "x " + Lives.ToString(), new Vector2(lifePosition.X + 8, lifePosition.Y + 5), UiColor); + } + else + { + for (var i = 0; i < Lives; i++) + { + spriteBatch.Draw(LifeSprite, new Vector2(lifePosition.X + (i * 28), lifePosition.Y), null, UiColor, (float)(Math.PI / 2), Vector2.Zero, 0.5f, SpriteEffects.None, 0f); + } + } + } + + public void Update() + { + + } + + public void Reset() + { + Score = 0; + Multiplier = 1; + Lives = 3; + } + } +} diff --git a/SuperPolarity/Program.cs b/SuperPolarity/Program.cs new file mode 100644 index 0000000..6c3f614 --- /dev/null +++ b/SuperPolarity/Program.cs @@ -0,0 +1,26 @@ +#region Using Statements +using System; +using System.Collections.Generic; +using System.Linq; +#endregion + +namespace SuperPolarity +{ +#if WINDOWS || LINUX + /// <summary> + /// The main class. + /// </summary> + public static class Program + { + /// <summary> + /// The main entry point for the application. + /// </summary> + [STAThread] + static void Main() + { + using (var superPolarity = new SuperPolarity()) + superPolarity.Run(); + } + } +#endif +} diff --git a/SuperPolarity/Properties/AssemblyInfo.cs b/SuperPolarity/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..bd24ce8 --- /dev/null +++ b/SuperPolarity/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SuperPolarity")] +[assembly: AssemblyProduct("SuperPolarity")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7f0aa81c-c9ab-4b87-97eb-3b788199ed3e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SuperPolarity/Renderer.cs b/SuperPolarity/Renderer.cs new file mode 100644 index 0000000..7ca8158 --- /dev/null +++ b/SuperPolarity/Renderer.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class Renderer + { + + static List<Actor> Actors; + + static Renderer() + { + Actors = new List<Actor>(); + } + + static public void CheckIn(Actor actor) + { + Actors.Add(actor); + } + + static public void CheckOut(Actor actor) + { + Actors.Remove(actor); + } + + static public void Draw(SpriteBatch spriteBatch) + { + foreach (Actor actor in Actors) + { + actor.Draw(spriteBatch); + } + } + + static public void Empty() + { + Actors.Clear(); + } + } +} diff --git a/SuperPolarity/ScoreScreen.cs b/SuperPolarity/ScoreScreen.cs new file mode 100644 index 0000000..bf43275 --- /dev/null +++ b/SuperPolarity/ScoreScreen.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; + +namespace SuperPolarity +{ + class ScoreScreen : Screen + { + protected SpriteFont Font; + protected NameChooserWidget nameChooser; + protected Dictionary<string, int> Scores; + + public ScoreScreen(SuperPolarity newGame) : base(newGame) { } + + public override void Initialize() + { + base.Initialize(); + nameChooser = new NameChooserWidget(Game, new Vector2(40, Game.GraphicsDevice.Viewport.Height / 4)); + InputController.RegisterEventForButton("OK", Buttons.A); + InputController.RegisterEventForKey("OK", Keys.Z); + Scores = new Dictionary<string, int>(); + ReadScore(); + } + + public override void LoadContent() + { + base.LoadContent(); + Font = Game.Content.Load<SpriteFont>("Fonts\\bigfont"); + InputController.Bind("OK", HandleNext); + } + + public void HandleNext(float value) + { + if (!Active) { return; } + WriteScore(); + ScreenManager.Pop(); + } + + public void WriteScore() + { + using (StreamWriter swriter = new StreamWriter("scores.txt", true)) + { + swriter.WriteLine(nameChooser.Value() + "," + Game.Player.Score.ToString()); + } + } + + public void ReadScore() + { + try + { + using (StreamReader sreader = new StreamReader("scores.txt")) + { + string line = null; + while ((line = sreader.ReadLine()) != null) + { + string[] parts = line.Split(','); + Scores.Add(parts[0], int.Parse(parts[1])); + } + } + } + catch (FileNotFoundException) + { + } + } + + public override void CleanUp() + { + base.CleanUp(); + Font = null; + } + + public override void Draw(SpriteBatch spriteBatch) + { + base.Draw(spriteBatch); + spriteBatch.DrawString(Font, "YOUR SCORE WAS: " + Game.Player.Score.ToString(), new Vector2(40, Game.GraphicsDevice.Viewport.Height / 2), Color.Black); + spriteBatch.DrawString(Font, "Use Left Stick or Arrows to Choose Name Press A when done", new Vector2(40, Game.GraphicsDevice.Viewport.Height / 2 + 40), new Color(0, 0, 0, 128)); + nameChooser.Draw(spriteBatch); + DrawScores(spriteBatch); + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + InputController.UpdateInput(false); + nameChooser.Update(gameTime); + } + + protected void DrawScores(SpriteBatch spriteBatch) + { + var sortedDict = (from entry in Scores orderby entry.Value descending select entry) + .Take(5) + .ToDictionary(pair => pair.Key, pair => pair.Value); + + var i = 0; + + foreach (KeyValuePair<string, int> entry in sortedDict) { + i++; + spriteBatch.DrawString(Font, entry.Key + " " + entry.Value, new Vector2(40, Game.GraphicsDevice.Viewport.Height / 2 + 100 + (32 * i)), new Color(0, 0, 0, 64)); + } + + } + } +} diff --git a/SuperPolarity/Screen.cs b/SuperPolarity/Screen.cs new file mode 100644 index 0000000..006b047 --- /dev/null +++ b/SuperPolarity/Screen.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class Screen + { + protected SuperPolarity Game; + public bool Active; + public Screen(SuperPolarity game) + { + Active = false; + Game = game; + } + + public virtual void Update(GameTime gameTime) + { + } + + public virtual void Draw(SpriteBatch spriteBatch) + { + } + + public virtual void LoadContent() + { + } + + public virtual void Initialize() + { + } + + public virtual void CleanUp() + { + } + } +} diff --git a/SuperPolarity/ScreenManager.cs b/SuperPolarity/ScreenManager.cs new file mode 100644 index 0000000..b88741b --- /dev/null +++ b/SuperPolarity/ScreenManager.cs @@ -0,0 +1,55 @@ +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 ScreenManager + { + static Stack<Screen> Screens; + static SuperPolarity Game; + + static ScreenManager() + { + Screens = new Stack<Screen>(); + } + + static public void Push(Screen screen) + { + if (Screens.Count > 0) + { + Screens.Peek().Active = false; + } + + screen.LoadContent(); + screen.Active = true; + Screens.Push(screen); + } + + static public void Pop() + { + var screen = Screens.Pop(); + screen.Active = false; + screen.CleanUp(); + Screens.Peek().Active = true; + } + + static public void Update(GameTime gameTime) + { + Screens.Peek().Update(gameTime); + } + + static public void Draw(SpriteBatch spriteBatch) + { + Screens.Peek().Draw(spriteBatch); + } + + internal static void SetGame(SuperPolarity game) + { + Game = game; + } + } +} diff --git a/SuperPolarity/SuperPolarity.cs b/SuperPolarity/SuperPolarity.cs new file mode 100644 index 0000000..9311d53 --- /dev/null +++ b/SuperPolarity/SuperPolarity.cs @@ -0,0 +1,161 @@ +#region Using Statements +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Storage; +using Microsoft.Xna.Framework.GamerServices; +using Microsoft.Xna.Framework.Media; +using Microsoft.Xna.Framework.Audio; +using SuperPolarity; +#endregion + +namespace SuperPolarity +{ + /// <summary> + /// This is the main type for your game + /// </summary> + public class SuperPolarity : Game + { + public GraphicsDeviceManager graphics; + SpriteBatch spriteBatch; + + public static int OutlierBounds; + + public Player Player; + + Screen EntryScreen; + + protected Song TitleSong; + protected Song GameSong; + protected SoundEffect GameOverSound; + + public SuperPolarity() + : base() + { + graphics = new GraphicsDeviceManager(this); + Components.Add(new GamerServicesComponent(this)); + + graphics.PreferMultiSampling = true; + graphics.PreferredBackBufferWidth = 1280; + graphics.PreferredBackBufferHeight = 720; + graphics.ToggleFullScreen(); + + Content.RootDirectory = "Content"; + ActorFactory.SetGame(this); + ParticleEffectFactory.SetGame(this); + ActorManager.SetGame(this); + ScreenManager.SetGame(this); + + EntryScreen = (Screen)new TitleScreen(this); + } + + /// <summary> + /// Allows the game to perform any initialization it needs to before starting to run. + /// This is where it can query for any required services and load any non-graphic + /// related content. Calling base.Initialize will enumerate through any components + /// and initialize them as well. + /// </summary> + protected override void Initialize() + { + base.Initialize(); + + InputController.RegisterEventForKey("fullScreenToggle", Keys.F11); + InputController.Bind("fullScreenToggle", HandleFullScreenToggle); + + EntryScreen.Initialize(); + + OutlierBounds = 100; + } + + protected void HandleFullScreenToggle(float value) + { + graphics.ToggleFullScreen(); + graphics.ApplyChanges(); + } + + /// <summary> + /// LoadContent will be called once per game and is the place to load + /// all of your content. + /// </summary> + protected override void LoadContent() + { + + MediaPlayer.IsRepeating = true; + GameSong = Content.Load<Song>("Sound\\polaritytheme.wav"); + GameOverSound = Content.Load<SoundEffect>("Sound\\gameover"); + + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + + ScreenManager.Push(EntryScreen); + + Player = new Player(this); + } + + /// <summary> + /// UnloadContent will be called once per game and is the place to unload + /// all content. + /// </summary> + protected override void UnloadContent() + { + // TODO: Unload any non ContentManager content here + } + + /// <summary> + /// Allows the game to run logic such as updating the world, + /// checking for collisions, gathering input, and playing audio. + /// </summary> + /// <param name="gameTime">Provides a snapshot of timing values.</param> + protected override void Update(GameTime gameTime) + { + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) + Exit(); + + ScreenManager.Update(gameTime); + + Player.Update(); + + base.Update(gameTime); + } + + /// <summary> + /// This is called when the game should draw itself. + /// </summary> + /// <param name="gameTime">Provides a snapshot of timing values.</param> + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.White); + + spriteBatch.Begin(); + + ScreenManager.Draw(spriteBatch); + + spriteBatch.End(); + + base.Draw(gameTime); + } + + public void PlaySong(string songName) + { + // temp stuff before media manager is in + if (songName == "game") + { + MediaPlayer.Play(GameSong); + } + } + + public void GameOver() + { + var scoreScreen = new ScoreScreen(this); + scoreScreen.Initialize(); + + MediaPlayer.Stop(); + GameOverSound.Play(); + ScreenManager.Pop(); + ScreenManager.Push(scoreScreen); + } + } +} diff --git a/SuperPolarity/SuperPolarity.csproj b/SuperPolarity/SuperPolarity.csproj new file mode 100644 index 0000000..76124b7 --- /dev/null +++ b/SuperPolarity/SuperPolarity.csproj @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">x86</Platform> + <ProductVersion>8.0.30703</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{2585188B-339D-44CD-9599-1A80AA30DE13}</ProjectGuid> + <OutputType>WinExe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>SuperPolarity</RootNamespace> + <AssemblyName>SuperPolarity</AssemblyName> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> + <PlatformTarget>x86</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\WindowsGL\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> + <PlatformTarget>x86</PlatformTarget> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\WindowsGL\Release\</OutputPath> + <DefineConstants>TRACE;WINDOWS</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup> + <ApplicationIcon>Icon.ico</ApplicationIcon> + </PropertyGroup> + <ItemGroup> + <Compile Include="ActorFactory.cs" /> + <Compile Include="ActorManager.cs" /> + <Compile Include="Actors\StandardShip.cs" /> + <Compile Include="Actors\Bullet.cs" /> + <Compile Include="BasicGenerator.cs" /> + <Compile Include="GameScreen.cs" /> + <Compile Include="InputController.cs" /> + <Compile Include="Actors\MainShip.cs" /> + <Compile Include="LetterChooseWidget.cs" /> + <Compile Include="MenuItem.cs" /> + <Compile Include="MenuWidget.cs" /> + <Compile Include="NameChooserWidget.cs" /> + <Compile Include="Particle.cs" /> + <Compile Include="ParticleEffectFactory.cs" /> + <Compile Include="ParticleEngine.cs" /> + <Compile Include="Actors\Actor.cs" /> + <Compile Include="Actors\Ship.cs" /> + <Compile Include="Player.cs" /> + <Compile Include="Renderer.cs" /> + <Compile Include="ScoreScreen.cs" /> + <Compile Include="Screen.cs" /> + <Compile Include="ScreenManager.cs" /> + <Compile Include="SuperPolarity.cs" /> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="TitleScreen.cs" /> + <Compile Include="Widget.cs" /> + </ItemGroup> + <ItemGroup> + <Reference Include="OpenTK"> + <HintPath>..\..\..\..\..\..\..\Program Files (x86)\MSBuild\..\MonoGame\v3.0\Assemblies\WindowsGL\OpenTK.dll</HintPath> + </Reference> + <Reference Include="MonoGame.Framework"> + <HintPath>..\..\..\..\..\..\..\Program Files (x86)\MSBuild\..\MonoGame\v3.0\Assemblies\WindowsGL\MonoGame.Framework.dll</HintPath> + </Reference> + <Reference Include="Lidgren.Network"> + <HintPath>..\..\..\..\..\..\..\Program Files (x86)\MSBuild\..\MonoGame\v3.0\Assemblies\WindowsGL\Lidgren.Network.dll</HintPath> + </Reference> + <Reference Include="Tao.Sdl"> + <HintPath>..\..\..\..\..\..\..\Program Files (x86)\MSBuild\..\MonoGame\v3.0\Assemblies\WindowsGL\Tao.Sdl.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Content Include="..\..\..\..\..\..\..\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsGL\SDL.dll"> + <Link>SDL.dll</Link> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Content\Sound\bomb.wav"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Content\Sound\bullet.wav"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Content\Sound\gameover.wav"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Content\Sound\hit.wav"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Content\Sound\life.wav"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Content\Sound\polaritychange.wav"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Content\Sound\polaritytheme.wav"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="Icon.ico" /> + </ItemGroup> + <ItemGroup /> + <ItemGroup> + <None Include="Content\Fonts\bigfont.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Fonts\SegoeUIMono14.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Fonts\smallfont.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\circle.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\diamond.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\main-ship.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\negative-cruiser.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\negative-destroyer.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\negative-scout.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\negative-ship.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\negative-supercruiser.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\neutral-cruiser.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\neutral-destroyer.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\neutral-scout.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\neutral-ship.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\pause-screen.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\polaritydemotitle.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="neutral-supercruiser.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\positive-cruiser.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\positive-destroyer.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\positive-scout.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\positive-ship.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\positive-supercruiser.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\square.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + <None Include="Content\Graphics\star.xnb"> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </None> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/SuperPolarity/TitleScreen.cs b/SuperPolarity/TitleScreen.cs new file mode 100644 index 0000000..a953f27 --- /dev/null +++ b/SuperPolarity/TitleScreen.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class TitleScreen : Screen + { + protected Texture2D TitleImage; + + public TitleScreen(SuperPolarity newGame) : base(newGame) {} + + public override void LoadContent() + { + base.LoadContent(); + TitleImage = Game.Content.Load<Texture2D>("Graphics\\polaritydemotitle"); + InputController.Bind("pause", HandleStart); + } + + public void HandleStart(float value) + { + if (!Active) { return; } + Game.Player.Reset(); + var gameScreen = new GameScreen(Game); + gameScreen.Initialize(); + ScreenManager.Push(gameScreen); + } + + public override void CleanUp() + { + base.CleanUp(); + TitleImage = null; + } + + public override void Draw(SpriteBatch spriteBatch) + { + base.Draw(spriteBatch); + spriteBatch.Draw(TitleImage, new Vector2(0, 0), Color.White); + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + InputController.UpdateInput(false); + } + } +} diff --git a/SuperPolarity/Widget.cs b/SuperPolarity/Widget.cs new file mode 100644 index 0000000..ea92cfd --- /dev/null +++ b/SuperPolarity/Widget.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SuperPolarity +{ + class Widget + { + public List<Widget> Children; + public Dictionary<string, List<Action<float>>> Listeners; + + public Vector2 Position; + public SuperPolarity Game; + + protected bool Active; + + public Widget(SuperPolarity game, Vector2 position) + { + Game = game; + Position = position; + Active = false; + Children = new List<Widget>(); + Listeners = new Dictionary<string, List<Action<float>>>(); + } + + public void Activate() + { + Active = true; + } + + public void Deactivate() + { + Active = false; + } + + public virtual void AppendChild(Widget widget) + { + Children.Add(widget); + } + + public virtual void Bind(string eventName, Action<float> eventListener) + { + List<Action<float>> newListenerList; + List<Action<float>> listenerList; + bool foundListeners; + + if (!Listeners.ContainsKey(eventName)) + { + newListenerList = new List<Action<float>>(); + Listeners.Add(eventName, newListenerList); + } + + foundListeners = Listeners.TryGetValue(eventName, out listenerList); + + listenerList.Add(eventListener); + } + + public virtual void Unbind(string eventName, Action<float> eventListener) + { + // NOT YET IMPLEMENTED; + } + + public virtual void Dispatch(string eventName, float value) + { + List<Action<float>> listenerList; + bool foundListeners; + + foundListeners = Listeners.TryGetValue(eventName, out listenerList); + + if (!foundListeners) + { + return; + } + + foreach (Action<float> method in listenerList) + { + method(value); + } + } + + public virtual void Update(GameTime gameTime) + { + } + + public virtual void Draw(SpriteBatch spriteBatch) + { + } + } +} diff --git a/SuperPolarity/neutral-supercruiser.xnb b/SuperPolarity/neutral-supercruiser.xnb Binary files differnew file mode 100644 index 0000000..1389842 --- /dev/null +++ b/SuperPolarity/neutral-supercruiser.xnb diff --git a/SuperPolarity/scores.txt b/SuperPolarity/scores.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/SuperPolarity/scores.txt |