--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This file contains an xml description of a font, and will be read by the XNA
+Framework Content Pipeline. Follow the comments to customize the appearance
+of the font in your game, and to change the characters which are available to draw
+with.
+-->
+<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
+ <Asset Type="Graphics:FontDescription">
+
+ <!--
+ Modify this string to change the font that will be imported.
+ -->
+ <FontName>Segoe UI Mono</FontName>
+
+ <!--
+ Size is a float value, measured in points. Modify this value to change
+ the size of the font.
+ -->
+ <Size>14</Size>
+
+ <!--
+ Spacing is a float value, measured in pixels. Modify this value to change
+ the amount of spacing in between characters.
+ -->
+ <Spacing>0</Spacing>
+
+ <!--
+ UseKerning controls the layout of the font. If this value is true, kerning information
+ will be used when placing characters.
+ -->
+ <UseKerning>true</UseKerning>
+
+ <!--
+ Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
+ and "Bold, Italic", and are case sensitive.
+ -->
+ <Style>Regular</Style>
+
+ <!--
+ If you uncomment this line, the default character will be substituted if you draw
+ or measure text that contains characters which were not included in the font.
+ -->
+ <!-- <DefaultCharacter>*</DefaultCharacter> -->
+
+ <!--
+ CharacterRegions control what letters are available in the font. Every
+ character from Start to End will be built and made available for drawing. The
+ default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
+ character set. The characters are ordered according to the Unicode standard.
+ See the documentation for more information.
+ -->
+ <CharacterRegions>
+ <CharacterRegion>
+ <Start> </Start>
+ <End>~</End>
+ </CharacterRegion>
+ </CharacterRegions>
+ </Asset>
+</XnaContent>
{
static class ActorFactory
{
- static internal Game Game;
+ static internal SuperPolarity Game;
static public MainShip CreateMainShip(Vector2 position)
{
return ship;
}
- internal static void SetGame(Game game)
+ internal static void SetGame(SuperPolarity game)
{
ActorFactory.Game = game;
}
static class ActorManager
{
- static Game Game;
+ static SuperPolarity Game;
static int OutlierBounds;
- static List<Actor> Actors;
+ static IList<Actor> Actors;
static ActorManager()
{
static void CheckActors()
{
- var i = 0;
- foreach (Actor actor in Actors)
+ for (var i = Actors.Count - 1; i >= 0; i--)
{
- i++;
- foreach (Actor other in Actors.Skip(i))
+ if (i >= Actors.Count) {
+ i = Actors.Count - 1;
+ }
+ 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)))
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);
+ }
}
}
}
- internal static void SetGame(Game game)
+ internal static void SetGame(SuperPolarity game)
{
Game = game;
}
{
class Actor
{
- protected Game game;
+ protected SuperPolarity game;
public List<Actor> Children;
protected Texture2D Texture;
protected Vector2 Origin;
public bool Active;
+ public Rectangle Box;
+ protected Vector4 BoxDimensions;
+ protected Texture2D BoxTexture;
// Physical Properties
public Vector2 Position;
// Constraints / Behavior
protected float MaxVelocity;
protected float AccelerationRate;
+ protected int HP;
+ protected bool Immortal;
+ public bool Dying;
+ public int Value;
+ protected Color Color;
+
+ public Actor Parent;
public int Width
{
get { return Texture.Height; }
}
- public Actor(Game newGame)
+ public Actor(SuperPolarity newGame)
{
game = newGame;
}
MaxVelocity = 5;
AccelerationRate = 10;
+
+ HP = 1;
+ Immortal = false;
+ BoxDimensions.X = 20;
+ BoxDimensions.Y = 20;
+ BoxDimensions.W = 20;
+ BoxDimensions.Z = 20;
+
+ 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.W), (int)(BoxDimensions.Y + BoxDimensions.Z));
}
public void AutoDeccelerate(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)
child.Draw(spriteBatch);
}
- spriteBatch.Draw(Texture, Position, null, Color.White, Angle, Origin, 1f, SpriteEffects.None, 0f);
+ spriteBatch.Draw(Texture, Position, null, Color, Angle, Origin, 1f, SpriteEffects.None, 0f);
+ spriteBatch.Draw(BoxTexture, Box, new Color(255, 0, 255, 25));
}
void CheckOutliers()
}
}
}
+
+ 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;
+ }
}
}
class Bullet : Actor
{
protected ParticleEngine particleEngine;
+ public int Power;
- public Bullet(Game newGame)
+ public Bullet(SuperPolarity newGame)
: base(newGame)
{
}
public override void Initialize(Texture2D texture, Vector2 position)
{
base.Initialize(texture, position);
+ BoxDimensions.X = 10;
+ BoxDimensions.Y = 10;
+ BoxDimensions.W = 10;
+ BoxDimensions.Z = 10;
+ InitBox();
particleEngine = ParticleEffectFactory.CreateBullet(position);
}
Velocity.X = (float)(MaxVelocity * Math.Cos(Angle));
Velocity.Y = (float)(MaxVelocity * Math.Sin(Angle));
+ Power = 1;
+
Position += Velocity;
+ UpdateBox();
particleEngine.Update();
particleEngine.EmitterLocation = Position;
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);
+ Parent.Children.Remove(this);
+ }
}
}
protected bool Shooting;
protected int ShotCooldown;
- public MainShip(Game newGame) : base(newGame) {}
+ protected float CurrentImmortalTime;
+ protected float MaxImmortalTime;
+ protected bool Flashing;
+
+ public MainShip(SuperPolarity newGame) : base(newGame) {}
~MainShip()
{
SetPolarity(Polarity.Positive);
ShotCooldown = 50;
+ MaxImmortalTime = 1500;
+
+ BoxDimensions.X = 2;
+ BoxDimensions.Y = 2;
+ BoxDimensions.W = 2;
+ BoxDimensions.Z = 2;
+ InitBox();
BindInput();
}
protected void HandleShot(float value)
{
- Children.Add(ActorFactory.CreateBullet(Position, Angle));
+ var bullet = ActorFactory.CreateBullet(Position, Angle);
+
+ Children.Add(bullet);
+ bullet.Parent = this;
+
Shooting = true;
Timer t = new Timer(new TimerCallback(UnlockShot));
t.Change(ShotCooldown, Timeout.Infinite);
{
base.SwitchPolarity();
SwitchParticleEngine(CurrentPolarity);
+ game.Player.ResetMultiplier();
}
public override void SetPolarity(Polarity newPolarity)
particleEngine.EmitterLocation = Position;
particleEngine.Update();
ConstrainToEdges();
+ UpdateImmortality(gameTime);
Shooting = false;
}
+ 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)
{
base.Move(gameTime);
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;
+ }
+ else {
+ Immortal = true;
+ CurrentImmortalTime = 0;
+ }
+ }
}
}
{
public enum Polarity : byte { Negative, Positive, Neutral };
- protected uint HP;
public Polarity CurrentPolarity;
public uint MagneticRadius;
protected bool Magnetizing;
- public Ship(Game newGame) : base(newGame) {
+ public Ship(SuperPolarity newGame) : base(newGame) {
MagneticRadius = 250;
RepelRadius = 100;
+ HP = 5;
+
FleeVelocity = 5;
ActVelocity = 2;
ChargeVelocity = 1.5f;
protected Random Random;
protected bool AddingAngle;
- public StandardShip(Game newGame) : base(newGame) {}
+ public StandardShip(SuperPolarity newGame) : base(newGame) {}
public override void Initialize(Texture2D texture, Vector2 position)
{
RotationFactor = (float) (3 * Math.PI / 180);
Random = new Random(BitConverter.ToInt32(cryptoResult, 0));
AddingAngle = true;
+
+ HP = 5;
}
public override void Magnetize(Ship ship, float distance, float angle)
}
ChangeAngle();
Position += Velocity;
+ UpdateBox();
Magnetizing = false;
}
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);
+ }
+ }
+
+ protected override void Die()
+ {
+ ActorManager.CheckOut(this);
+ Renderer.CheckOut(this);
+ game.Player.AddScore(Value);
+ game.Player.AddMultiplier(1);
+ }
}
}
--- /dev/null
+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.Input;
+
+namespace SuperPolarity
+{
+ class GameScreen : Screen
+ {
+ public GameScreen(SuperPolarity newGame) : base(newGame) {}
+
+ public override void Initialize()
+ {
+ InputController.RegisterEventForButton("changePolarity", Buttons.A);
+ InputController.RegisterEventForKey("changePolarity", Keys.Z);
+
+ InputController.RegisterEventForButton("shoot", Buttons.X);
+ InputController.RegisterEventForKey("shoot", Keys.X);
+ }
+
+ public override void LoadContent()
+ {
+ Vector2 playerPosition = new Vector2(Game.GraphicsDevice.Viewport.TitleSafeArea.X, Game.GraphicsDevice.Viewport.TitleSafeArea.Y + Game.GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
+
+ Renderer.CheckIn(ActorFactory.CreateMainShip(playerPosition));
+ Renderer.CheckIn(ActorFactory.CreateShip(Ship.Polarity.Positive, new Vector2(200, 200)));
+ Renderer.CheckIn(ActorFactory.CreateShip(Ship.Polarity.Negative, new Vector2(400, 200)));
+ }
+
+ public override void Update(GameTime gameTime)
+ {
+ InputController.UpdateInput();
+ ActorManager.Update(gameTime);
+ }
+
+ public override void Draw(SpriteBatch spriteBatch)
+ {
+ Renderer.Draw(spriteBatch);
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SuperPolarity
+{
+ class MenuItem : Widget
+ {
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SuperPolarity
+{
+ class MenuWidget : Widget
+ {
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SuperPolarity
+{
+ public class Player
+ {
+ public int Score;
+ public int Multiplier;
+ public int Lives;
+
+ public Player()
+ {
+ Score = 0;
+ Multiplier = 1;
+ Lives = 3;
+ }
+
+ 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()
+ {
+
+ }
+
+ public void Update()
+ {
+
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SuperPolarity
+{
+ class ScoreScreen : Screen
+ {
+ public ScoreScreen(SuperPolarity newGame) : base(newGame) {}
+
+ public override void Initialize()
+ {
+ }
+ }
+}
--- /dev/null
+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 Screen(SuperPolarity game)
+ {
+ 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()
+ {
+ }
+ }
+}
--- /dev/null
+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)
+ {
+ Screens.Push(screen);
+ }
+
+ static public void Pop()
+ {
+ Screens.Pop();
+ }
+
+ static public void Update(GameTime gameTime)
+ {
+ Screens.Peek().Update(gameTime);
+ }
+
+ static public void Draw(SpriteBatch spriteBatch)
+ {
+ foreach (Screen screen in Screens)
+ {
+ screen.Draw(spriteBatch);
+ }
+ }
+
+ internal static void SetGame(SuperPolarity game)
+ {
+ Game = game;
+ }
+ }
+}
<Compile Include="ActorManager.cs" />
<Compile Include="Actors\StandardShip.cs" />
<Compile Include="Actors\Bullet.cs" />
+ <Compile Include="GameScreen.cs" />
<Compile Include="InputController.cs" />
<Compile Include="Actors\MainShip.cs" />
+ <Compile Include="MenuItem.cs" />
+ <Compile Include="MenuWidget.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">
<Folder Include="Content\Sound\" />
</ItemGroup>
<ItemGroup>
+ <None Include="Content\Fonts\SegoeUIMono14.xnb">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
<None Include="Content\Graphics\circle.xnb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
/// </summary>
public class SuperPolarity : Game
{
- public static GraphicsDeviceManager graphics;
+ public GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public static int OutlierBounds;
+ public Player Player;
+
+ Screen EntryScreen;
+
+ SpriteFont DebugFont;
+
public SuperPolarity()
: base()
{
- SuperPolarity.graphics = new GraphicsDeviceManager(this);
- SuperPolarity.graphics.PreferMultiSampling = true;
+ graphics = new GraphicsDeviceManager(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 GameScreen(this);
}
/// <summary>
{
base.Initialize();
- OutlierBounds = 100;
+ InputController.RegisterEventForKey("fullScreenToggle", Keys.F11);
+ InputController.Bind("fullScreenToggle", HandleFullScreenToggle);
- InputController.RegisterEventForButton("changePolarity", Buttons.A);
- InputController.RegisterEventForKey("changePolarity", Keys.Z);
+ EntryScreen.Initialize();
+ ScreenManager.Push(EntryScreen);
- InputController.RegisterEventForButton("shoot", Buttons.X);
- InputController.RegisterEventForKey("shoot", Keys.X);
+ OutlierBounds = 100;
+ }
+
+ protected void HandleFullScreenToggle(float value)
+ {
+ graphics.ToggleFullScreen();
+ graphics.ApplyChanges();
}
/// <summary>
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
- Vector2 playerPosition = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y + GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
+ EntryScreen.LoadContent();
- Renderer.CheckIn(ActorFactory.CreateMainShip(playerPosition));
- Renderer.CheckIn(ActorFactory.CreateShip(Ship.Polarity.Positive, new Vector2(200, 200)));
- Renderer.CheckIn(ActorFactory.CreateShip(Ship.Polarity.Negative, new Vector2(400, 200)));
+ Player = new Player();
+ DebugFont = Content.Load<SpriteFont>("Fonts\\SegoeUIMono14");
}
/// <summary>
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
- // TODO: Add your update logic here
-
- InputController.UpdateInput();
- ActorManager.Update(gameTime);
+ ScreenManager.Update(gameTime);
base.Update(gameTime);
}
spriteBatch.Begin();
- Renderer.Draw(spriteBatch);
+ ScreenManager.Draw(spriteBatch);
+
+ spriteBatch.DrawString(DebugFont, "Score: " + Player.Score.ToString(), new Vector2(10, 10), Color.LightGray);
+ spriteBatch.DrawString(DebugFont, "Multiplier: " + Player.Multiplier.ToString(), new Vector2(10, 30), Color.LightGray);
+ spriteBatch.DrawString(DebugFont, "Lives: " + Player.Lives.ToString(), new Vector2(10, 50), Color.LightGray);
spriteBatch.End();
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SuperPolarity
+{
+ class TitleScreen : Screen
+ {
+ public TitleScreen(SuperPolarity newGame) : base(newGame) {}
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace SuperPolarity
+{
+ class Widget
+ {
+ public IList<Widget> Children;
+ public Dictionary<string, List<Action<float>>> Listeners;
+
+ 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);
+ }
+ }
+ }
+}
C:\Users\Miau\documents\visual studio 2010\Projects\Super Polarity\Super Polarity\bin\WindowsGL\Debug\Content\Graphics\star.xnb
C:\Users\Miau\documents\visual studio 2010\Projects\Super Polarity\Super Polarity\bin\WindowsGL\Debug\Content\Graphics\negative-ship.xnb
C:\Users\Miau\documents\visual studio 2010\Projects\Super Polarity\Super Polarity\bin\WindowsGL\Debug\Content\Graphics\square.xnb
+C:\Users\Miau\documents\visual studio 2010\Projects\Super Polarity\Super Polarity\bin\WindowsGL\Debug\Content\Fonts\SegoeUIMono14.xnb