Commits

Carolyn Van Slyck committed 895f357

* Created MiniGameManager which allows loading and switching between mini-games
* Added StartScreen

  • Participants
  • Parent commits d818f4d

Comments (0)

Files changed (23)

File OMG.Content/Fonts/DialogOption.spritefont

+<?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>&#32;</Start>
+        <End>&#126;</End>
+      </CharacterRegion>
+    </CharacterRegions>
+  </Asset>
+</XnaContent>

File OMG.Content/Fonts/Standard.spritefont

+<?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>&#32;</Start>
+        <End>&#126;</End>
+      </CharacterRegion>
+    </CharacterRegions>
+  </Asset>
+</XnaContent>

File OMG.Content/Fonts/Title.spritefont

+<?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>26</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>&#32;</Start>
+        <End>&#126;</End>
+      </CharacterRegion>
+    </CharacterRegions>
+  </Asset>
+</XnaContent>

File OMG.Content/OMG.Content.contentproj

     </Compile>
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Title.spritefont">
+    <Compile Include="Fonts\DialogOption.spritefont">
+      <Name>DialogOption</Name>
+      <Importer>FontDescriptionImporter</Importer>
+      <Processor>FontDescriptionProcessor</Processor>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Images\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Obstacle-StoneFence.png">
+      <Name>Obstacle-StoneFence</Name>
+      <Importer>TextureImporter</Importer>
+      <Processor>TextureProcessor</Processor>
+    </Compile>
+    <Compile Include="Obstacle-WhiteFence.png">
+      <Name>Obstacle-WhiteFence</Name>
+      <Importer>TextureImporter</Importer>
+      <Processor>TextureProcessor</Processor>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Fonts\Standard.spritefont">
+      <Name>Standard</Name>
+      <Importer>FontDescriptionImporter</Importer>
+      <Processor>FontDescriptionProcessor</Processor>
+    </Compile>
+    <Compile Include="Fonts\Title.spritefont">
       <Name>Title</Name>
       <Importer>FontDescriptionImporter</Importer>
       <Processor>FontDescriptionProcessor</Processor>

File OMG.Content/OMG.Content.contentproj.user

 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <ProjectView>ProjectFiles</ProjectView>
+    <ProjectView>ShowAllFiles</ProjectView>
   </PropertyGroup>
 </Project>

File OMG.Content/Obstacle-StoneFence.png

Added
New image

File OMG.Content/Obstacle-WhiteFence.png

Added
New image

File OMG.Content/Title.spritefont

-<?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>&#32;</Start>
-        <End>&#126;</End>
-      </CharacterRegion>
-    </CharacterRegions>
-  </Asset>
-</XnaContent>
 # Visual Studio 2010
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OMG.Windows", "OMG\OMG.Windows.csproj", "{F95EBB11-67CA-4826-BC97-B08BD15D7B25}"
 EndProject
-Project("{96E2B04D-8817-42C6-938A-82C39BA4D311}") = "OMG.Content", "OMG.Content\OMG.Content.contentproj", "{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OMG.Content", "OMG.Content\OMG.Content.contentproj", "{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OMG.Xbox", "OMG\OMG.Xbox.csproj", "{7D7B175C-E7C8-48A4-A929-82B1563C1C51}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
 		Debug|Mixed Platforms = Debug|Mixed Platforms
 		Debug|x86 = Debug|x86
 		Debug|Xbox 360 = Debug|Xbox 360
+		Release|Any CPU = Release|Any CPU
 		Release|Mixed Platforms = Release|Mixed Platforms
 		Release|x86 = Release|x86
 		Release|Xbox 360 = Release|Xbox 360
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Debug|Any CPU.ActiveCfg = Debug|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Debug|Mixed Platforms.Build.0 = Debug|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Debug|x86.ActiveCfg = Debug|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Debug|x86.Build.0 = Debug|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Debug|Xbox 360.ActiveCfg = Debug|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Debug|Xbox 360.Build.0 = Debug|x86
+		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Release|Any CPU.ActiveCfg = Release|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Release|Mixed Platforms.ActiveCfg = Release|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Release|Mixed Platforms.Build.0 = Release|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Release|x86.ActiveCfg = Release|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Release|x86.Build.0 = Release|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Release|Xbox 360.ActiveCfg = Release|x86
 		{F95EBB11-67CA-4826-BC97-B08BD15D7B25}.Release|Xbox 360.Build.0 = Release|x86
+		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Debug|Any CPU.ActiveCfg = Debug|x86
 		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
 		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Debug|x86.ActiveCfg = Debug|x86
 		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Debug|Xbox 360.ActiveCfg = Debug|x86
+		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Release|Any CPU.ActiveCfg = Release|x86
 		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Release|Mixed Platforms.ActiveCfg = Release|x86
 		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Release|x86.ActiveCfg = Release|x86
 		{9FBD1C0F-2D08-48E1-B0A0-23B1D4639A76}.Release|Xbox 360.ActiveCfg = Release|x86
+		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Debug|Any CPU.ActiveCfg = Debug|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Debug|Mixed Platforms.ActiveCfg = Debug|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Debug|Mixed Platforms.Build.0 = Debug|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Debug|Mixed Platforms.Deploy.0 = Debug|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Debug|Xbox 360.ActiveCfg = Debug|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Debug|Xbox 360.Build.0 = Debug|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Debug|Xbox 360.Deploy.0 = Debug|Xbox 360
+		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Release|Any CPU.ActiveCfg = Release|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Release|Mixed Platforms.ActiveCfg = Release|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Release|Mixed Platforms.Build.0 = Release|Xbox 360
 		{7D7B175C-E7C8-48A4-A929-82B1563C1C51}.Release|Mixed Platforms.Deploy.0 = Release|Xbox 360

File OMG/GameFont.cs

+namespace OMG
+{
+    public enum GameFont
+    {
+        Title,
+        DialogOption,
+        Standard
+    }
+
+    public static class GameFontExtension
+    {
+        public static string Location(this GameFont font)
+        {
+            return "Fonts\\" + font;
+        }
+    }
+}

File OMG/MiniGame/IMiniGame.cs

+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using OMG.GameController;
+
+namespace OMG.MiniGame
+{
+    public interface IMiniGame : IDisposable
+    {
+        event GameComplete GameComplete;
+        void Initialize(GraphicsDeviceManager graphics, ContentManager content);
+        void LoadContent();
+        void Update(GameControllerState gameControllerState, GameTime gameTime);
+        void Draw(GameTime gameTime);
+    }
+
+    public delegate void GameComplete(GameCompleteEventArguments e);
+
+    public class GameCompleteEventArguments
+    {
+        public IMiniGame CurrentGame;
+        public IMiniGame NextGame;
+    }
+}

File OMG/MiniGame/MiniGameBase.cs

 using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Content;
 using OMG.GameController;
 using OMG.Sprite;
 
 namespace OMG.MiniGame
 {
-    public abstract class MiniGameBase : Game
+    public abstract class MiniGameBase : IMiniGame
     {
-        private GraphicsDeviceManager _graphics;
-        private SpriteBatch _spriteBatch;
-
+        protected GraphicsDeviceManager Graphics;
+        protected ContentManager Content;
         protected SpriteManager Sprites { get; set; }
 
-        protected MiniGameBase()
-        {
-            _graphics = new GraphicsDeviceManager(this);
-            Content.RootDirectory = "Content";
-            Sprites = new SpriteManager();
-        }
-
         /// <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()
+        public void Initialize(GraphicsDeviceManager graphics, ContentManager content)
         {
+            Graphics = graphics;
+            Content = content;
+
+            GameScreen.SafeArea = Graphics.GraphicsDevice.Viewport.TitleSafeArea;
+            GameCursor.Location = new Vector2(GameScreen.SafeArea.X / 2, GameScreen.SafeArea.Y / 2);
+
+            Sprites = new SpriteManager(Graphics.GraphicsDevice);
             InitializeSprites();
-
-            base.Initialize();
         }
 
         protected abstract void InitializeSprites();
         /// LoadContent will be called once per game and is the place to load
         /// all of your content.
         /// </summary>
-        protected override void LoadContent()
+        public virtual void LoadContent()
         {
-            // Create a new SpriteBatch, which can be used to draw textures.
-            _spriteBatch = new SpriteBatch(GraphicsDevice);
-
-            GameScreen.SafeArea = _graphics.GraphicsDevice.Viewport.TitleSafeArea;
-            GameCursor.Location = new Vector2(GameScreen.SafeArea.X / 2, GameScreen.SafeArea.Y / 2);
-
             Sprites.LoadContent(Content);
         }
 
         /// 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)
+        public void Update(GameControllerState gameControllerState, GameTime gameTime)
         {
-            var gameControllerState = GameControllerState.GetState(gameTime);
-            if (gameControllerState.HasAction(GameControllerAction.Quit))
-                Exit();
-
             Sprites.Update(gameTime, gameControllerState);
-
-            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)
+        public void Draw(GameTime gameTime)
         {
-            GraphicsDevice.Clear(Color.CornflowerBlue);
+            Graphics.GraphicsDevice.Clear(Color.Black);
+            Sprites.Draw();
+        }
 
-            _spriteBatch.Begin();
+        public event GameComplete GameComplete;
 
-            Sprites.Draw(_spriteBatch);
+        public void NotifyGameComplete(IMiniGame nextGame)
+        {
+            if(GameComplete != null)
+            {
+                var e = new GameCompleteEventArguments
+                            {
+                                CurrentGame = this,
+                                NextGame = nextGame
+                            };
+                GameComplete(e);
+            }
+        }
 
-            _spriteBatch.End();
-
-            base.Draw(gameTime);
+        public void Dispose()
+        {
+            Sprites.Dispose();
         }
     }
 }

File OMG/MiniGame/MiniGameManager.cs

+using Microsoft.Xna.Framework;
+using OMG.GameController;
+
+namespace OMG.MiniGame
+{
+    public class MiniGameManager : Game
+    {
+        public MiniGameManager()
+        {
+            _graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+        }
+
+        private readonly GraphicsDeviceManager _graphics;
+        public IMiniGame CurrentGame;
+        private bool _loaded;
+
+        public void SetInitialGame(IMiniGame game)
+        {
+            CurrentGame = game;
+            game.GameComplete += OnGameComplete;
+        }
+
+        public void ChangeGame(IMiniGame game)
+        {
+            if(CurrentGame != null)
+            {
+                CurrentGame.Dispose();    
+            }
+
+            CurrentGame = game;
+            game.GameComplete += OnGameComplete;
+
+            if (_loaded)
+            {
+                CurrentGame.Initialize(_graphics, Content);
+                CurrentGame.LoadContent();
+            }
+        }
+
+        protected virtual void OnGameComplete(GameCompleteEventArguments e)
+        {
+            if (e.NextGame == null)
+                return;
+
+            ChangeGame(e.NextGame);
+        }
+
+        protected override void Initialize()
+        {
+            if(CurrentGame != null)
+            {
+                CurrentGame.Initialize(_graphics, Content);
+            }
+
+            base.Initialize();
+        }
+
+        protected override void LoadContent()
+        {
+            if(CurrentGame != null)
+            {
+                CurrentGame.LoadContent();
+            }
+
+            base.LoadContent();
+
+            _loaded = true;
+        }
+
+        protected override void Update(GameTime gameTime)
+        {
+            var gameControllerState = GameControllerState.GetState(gameTime);
+            if (gameControllerState.HasAction(GameControllerAction.Quit))
+                Exit();
+
+            CurrentGame.Update(gameControllerState, gameTime);
+
+            base.Update(gameTime);
+        }
+
+        protected override void Draw(GameTime gameTime)
+        {
+            CurrentGame.Draw(gameTime);
+
+            base.Draw(gameTime);
+        }
+    }
+}

File OMG/OMG.Windows.csproj

     <Compile Include="GameController\XboxController.cs" />
     <Compile Include="GameController\XboxControllerAction.cs" />
     <Compile Include="GameCursor.cs" />
+    <Compile Include="GameFont.cs" />
     <Compile Include="GameScreen.cs" />
     <Compile Include="MiniGame\AgilityCourse\AgilityCourseGame.cs" />
+    <Compile Include="MiniGame\IMiniGame.cs" />
     <Compile Include="MiniGame\MiniGameBase.cs" />
+    <Compile Include="MiniGame\MiniGameManager.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Sprite\Cursor.cs" />
+    <Compile Include="Sprite\DialogOption.cs" />
     <Compile Include="Sprite\ISprite.cs" />
     <Compile Include="Sprite\Monkey.cs" />
     <Compile Include="Sprite\ScrollingBackground.cs" />

File OMG/OMG.Xbox.csproj

     <Compile Include="GameController\XboxController.cs" />
     <Compile Include="GameController\XboxControllerAction.cs" />
     <Compile Include="GameCursor.cs" />
+    <Compile Include="GameFont.cs" />
     <Compile Include="GameScreen.cs" />
     <Compile Include="MiniGame\AgilityCourse\AgilityCourseGame.cs" />
+    <Compile Include="MiniGame\IMiniGame.cs" />
     <Compile Include="MiniGame\MiniGameBase.cs" />
+    <Compile Include="MiniGame\MiniGameManager.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Sprite\Cursor.cs" />
+    <Compile Include="Sprite\DialogOption.cs" />
     <Compile Include="Sprite\ISprite.cs" />
     <Compile Include="Sprite\Monkey.cs" />
     <Compile Include="Sprite\ScrollingBackground.cs" />

File OMG/Program.cs

+using OMG.MiniGame;
 using OMG.MiniGame.AgilityCourse;
 
 namespace OMG
         /// </summary>
         static void Main(string[] args)
         {
-            using(var game = new AgilityCourseGame())
-            {
-                game.Run();
-            }
+            var miniGameMgr = new MiniGameManager();
+            miniGameMgr.SetInitialGame(new StartScreen());
+            miniGameMgr.Run();
         }
     }
 #endif

File OMG/Sprite/Cursor.cs

 
         public Cursor() : base(AssetName)
         {
-            
+            DrawOrder = int.MaxValue;
         }
 
         protected bool Selected;
         private Color? _lastTint;
         public override void Update(GameTime gameTime, GameControllerState gameControllerState)
         {
+            base.Update(gameTime, gameControllerState);
+
             Position = gameControllerState.GameCursorLocation;
 
             if (!Selected && gameControllerState.HasAction(GameControllerAction.Select))

File OMG/Sprite/DialogOption.cs

+namespace OMG.Sprite
+{
+    public delegate void DialogOptionSelected(DialogOption option);
+
+    public class DialogOption : TextSprite
+    {
+        public const GameFont Font = GameFont.DialogOption;
+
+        public DialogOption(string text) : base(Font)
+        {
+            Text = text;
+        }
+
+        public event DialogOptionSelected DialogOptionSelected;
+        
+        protected void NotifyDialogOptionSelected()
+        {
+            if(DialogOptionSelected != null)
+            {
+                DialogOptionSelected(this);
+            }
+        }
+
+        public override void Update(Microsoft.Xna.Framework.GameTime gameTime, GameController.GameControllerState gameControllerState)
+        {
+            base.Update(gameTime, gameControllerState);
+
+            if(Selected)
+            {
+                NotifyDialogOptionSelected();
+            }
+        }
+    }
+}

File OMG/Sprite/Sprite.cs

             }
         }
 
+        public bool Selected;
+
         public event SpritePositionChanging PositionChanging;
 
         public virtual bool AllowCollide(ISprite sprite)
             
         }
 
-        public Rectangle Size { get; private set; }
+        public Rectangle Size { get; protected set; }
 
         public Rectangle Border
         {
             UpdateSize();
         }
 
-        private void UpdateSize()
+        protected virtual void UpdateSize()
         {
             if (_spriteTexture == null)
                 return;
 
         public virtual void Update(GameTime gameTime, GameControllerState gameControllerState)
         {
-            
+            var isInBorder = Border.Contains(GameCursor.Location.ToPoint());
+            var clicked = gameControllerState.HasAction(GameControllerAction.Select);
+            Selected = isInBorder && clicked;
         }
 
         public virtual void Free(ISprite sprite)

File OMG/Sprite/SpriteManager.cs

-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Linq;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
 
 namespace OMG.Sprite
 {
-    public class SpriteManager : List<ISprite>
+    public class SpriteManager : List<ISprite>, IDisposable
     {
+        private SpriteBatch _spriteBatch;
+        private bool _collisionDetectionOn;
+
+        protected Dictionary<ISprite, IEnumerable<ISprite>> CollidedSprites = new Dictionary<ISprite, IEnumerable<ISprite>>();
+
+        public SpriteManager(GraphicsDevice graphicsDevice)
+        {
+            _spriteBatch = new SpriteBatch(graphicsDevice);
+        }
+
         public new void Add(ISprite sprite)
         {
             base.Add(sprite);
             CollidedSprites.Add(sprite, new List<ISprite>());
         }
 
-        private bool _collisionDetectionOn = false;
-        protected Dictionary<ISprite, IEnumerable<ISprite>> CollidedSprites = new Dictionary<ISprite, IEnumerable<ISprite>>();
-
         private void SpritePositionChanging(ISprite movingSprite, SpritePositionChangingEventArguments e)
         {
             if (!_collisionDetectionOn)
             _collisionDetectionOn = true;
         }
 
-        public void Draw(SpriteBatch spriteBatch)
+        public void Draw()
         {
+            _spriteBatch.Begin();
             foreach (var sprite in this.OrderBy(sprite => sprite.DrawOrder))
             {
-                sprite.Draw(spriteBatch);
+                sprite.Draw(_spriteBatch);
             }
+            _spriteBatch.End();
         }
 
         public void Update(GameTime gameTime, GameControllerState gameControllerState)
                 sprite.Update(gameTime, gameControllerState);
             }
         }
+
+        public void Dispose()
+        {
+            _spriteBatch.Dispose();
+        }
     }
 }

File OMG/Sprite/TextSprite.cs

-using System;
-using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Content;
 using Microsoft.Xna.Framework.Graphics;
 using OMG.GameController;
 
 namespace OMG.Sprite
 {
-    public class TextSprite : ISprite
+    public class TextSprite : Sprite
     {
-        private readonly string _font;
+        private readonly GameFont _font;
         private SpriteFont _spriteFont;
 
-        public TextSprite(string font)
+        public TextSprite(string text) 
+            : base(GameFont.Standard.Location())
+        {
+            _font = GameFont.Standard;
+            Text = text;
+            DrawOrder = int.MaxValue-1;
+        }
+
+        public TextSprite(GameFont font)
+            : this(string.Empty)
         {
             _font = font;
-            DrawOrder = int.MaxValue;
+        } 
+
+        public TextSprite(GameFont font, string text)
+            : this(text)
+        {
+            _font = font;
         }
 
         public string Text;
         public Color TextColor = Color.White;
 
-        public Vector2 Position { get; set; }
-        public event SpritePositionChanging PositionChanging;
-
-        public bool AllowCollide(ISprite sprite)
+        public override void LoadContent(ContentManager contentManager)
         {
-            return true;
+            _spriteFont = contentManager.Load<SpriteFont>(_font.Location());
+            UpdateSize();
         }
 
-        public void Collide(ISprite sprite)
+        protected override void UpdateSize()
         {
-            
+            if (_spriteFont == null)
+                return;
+
+            Vector2 fontSize = _spriteFont.MeasureString(Text);
+
+            Size = new Rectangle(0, 0, (int)(fontSize.X * Scale), (int)(fontSize.Y * Scale));
         }
 
-        public Rectangle Size { get; private set; }
-        public Rectangle Border { get; private set; }
-        public float Scale { get; set; }
-        public int DrawOrder { get; set; }
-
-        public void LoadContent(ContentManager contentManager)
-        {
-            _spriteFont = contentManager.Load<SpriteFont>(_font);
-        }
-
-        public void Draw(SpriteBatch spriteBatch)
+        public override void Draw(SpriteBatch spriteBatch)
         {
             spriteBatch.DrawString(_spriteFont, Text, Position, TextColor);
         }
-
-        public void Update(GameTime gameTime, GameControllerState gameControllerState)
-        {
-            
-        }
-
-        public void Free(ISprite sprite)
-        {
-            
-        }
     }
 }

File OMG/StartScreen.cs

-using System;
+using Microsoft.Xna.Framework;
 using OMG.MiniGame;
+using OMG.MiniGame.AgilityCourse;
+using OMG.Sprite;
 
 namespace OMG
 {
     public class StartScreen : MiniGameBase
     {
+        private TextSprite _title;
+        private DialogOption _startGameOption;
+        private Cursor _cursor;
+
         protected override void InitializeSprites()
         {
+            _title = new TextSprite(GameFont.Title, "OMG Ponies, Puppies and Kitties");
+
+            _startGameOption = new DialogOption("Start");
+            _startGameOption.DialogOptionSelected += delegate { StartGame(); };
             
+            _cursor = new Cursor();
+
+            Sprites.Add(_title);
+            Sprites.Add(_startGameOption);
+            Sprites.Add(_cursor);
         }
 
-        protected override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
+        public override void LoadContent()
         {
+            base.LoadContent();
 
+            _startGameOption.Position = new Vector2(GameScreen.SafeArea.Width / 2, GameScreen.SafeArea.Height / 2);
+        }
+
+        private void StartGame()
+        {
+            NotifyGameComplete(new AgilityCourseGame());
         }
     }
 }

File OMG/XnaExtensions.cs

         {
             return currentPosition + direction*speed*(float) gameTime.ElapsedGameTime.TotalSeconds;
         }
+
+        public static Point ToPoint(this Vector2 vector)
+        {
+            return new Point((int)vector.X, (int)vector.Y);
+        }
     }
 }