]> Dogcows Code - chaz/carfire/commitdiff
initial upload
authorbrady <brady@92bb83a3-7c8f-8a45-bc97-515c4e399668>
Sat, 13 Mar 2010 18:38:41 +0000 (18:38 +0000)
committerbrady <brady@92bb83a3-7c8f-8a45-bc97-515c4e399668>
Sat, 13 Mar 2010 18:38:41 +0000 (18:38 +0000)
git-svn-id: https://bd85.net/svn/cs3505_group@3 92bb83a3-7c8f-8a45-bc97-515c4e399668

13 files changed:
Project06/CS 3505 Project 06/CS 3505 Project 06.sln [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505 Project 06.csproj [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/IDeterministicGame.cs [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/Crosshair.png [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/GameFont.spritefont [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Content/Content.contentproj [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Content/InstructionFont.spritefont [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Game.ico [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Game06.cs [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/GameThumbnail.png [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Program.cs [new file with mode: 0644]
Project06/CS 3505 Project 06/CS 3505 Project 06/Properties/AssemblyInfo.cs [new file with mode: 0644]

diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06.sln b/Project06/CS 3505 Project 06/CS 3505 Project 06.sln
new file mode 100644 (file)
index 0000000..9c0c7c9
--- /dev/null
@@ -0,0 +1,26 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 10.00\r
+# Visual Studio 2008\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS 3505 Project 06", "CS 3505 Project 06\CS 3505 Project 06.csproj", "{0C08A79E-3951-4C7F-A554-32468808F00D}"\r
+EndProject\r
+Global\r
+       GlobalSection(SubversionScc) = preSolution\r
+               Svn-Managed = True\r
+               Manager = AnkhSVN - Subversion Support for Visual Studio\r
+       EndGlobalSection\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|x86 = Debug|x86\r
+               Release|x86 = Release|x86\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {0C08A79E-3951-4C7F-A554-32468808F00D}.Debug|x86.ActiveCfg = Debug|x86\r
+               {0C08A79E-3951-4C7F-A554-32468808F00D}.Debug|x86.Build.0 = Debug|x86\r
+               {0C08A79E-3951-4C7F-A554-32468808F00D}.Release|x86.ActiveCfg = Release|x86\r
+               {0C08A79E-3951-4C7F-A554-32468808F00D}.Release|x86.Build.0 = Release|x86\r
+               {56086477-A1FB-4593-8868-2B41D8719294}.Debug|x86.ActiveCfg = Debug|x86\r
+               {56086477-A1FB-4593-8868-2B41D8719294}.Release|x86.ActiveCfg = Release|x86\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505 Project 06.csproj b/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505 Project 06.csproj
new file mode 100644 (file)
index 0000000..41013cd
--- /dev/null
@@ -0,0 +1,149 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">\r
+  <PropertyGroup>\r
+    <ProjectGuid>{0C08A79E-3951-4C7F-A554-32468808F00D}</ProjectGuid>\r
+    <ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>\r
+    <OutputType>WinExe</OutputType>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <RootNamespace>CS_3505_Project_06</RootNamespace>\r
+    <AssemblyName>CS 3505 Project 06</AssemblyName>\r
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r
+    <XnaFrameworkVersion>v3.0</XnaFrameworkVersion>\r
+    <XnaPlatform>Windows</XnaPlatform>\r
+    <XnaCrossPlatformGroupID>4c8ffe57-5280-4c98-91c6-e0b1fcc90362</XnaCrossPlatformGroupID>\r
+    <ApplicationIcon>Game.ico</ApplicationIcon>\r
+    <Thumbnail>GameThumbnail.png</Thumbnail>\r
+    <PublishUrl>publish\</PublishUrl>\r
+    <Install>true</Install>\r
+    <InstallFrom>Disk</InstallFrom>\r
+    <UpdateEnabled>false</UpdateEnabled>\r
+    <UpdateMode>Foreground</UpdateMode>\r
+    <UpdateInterval>7</UpdateInterval>\r
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>\r
+    <UpdatePeriodically>false</UpdatePeriodically>\r
+    <UpdateRequired>false</UpdateRequired>\r
+    <MapFileExtensions>true</MapFileExtensions>\r
+    <ApplicationRevision>0</ApplicationRevision>\r
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>\r
+    <IsWebBootstrapper>false</IsWebBootstrapper>\r
+    <UseApplicationTrust>false</UseApplicationTrust>\r
+    <BootstrapperEnabled>true</BootstrapperEnabled>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <OutputPath>bin\x86\Debug</OutputPath>\r
+    <DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+    <NoStdLib>true</NoStdLib>\r
+    <UseVSHostingProcess>false</UseVSHostingProcess>\r
+    <PlatformTarget>x86</PlatformTarget>\r
+    <XnaCompressContent>false</XnaCompressContent>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <OutputPath>bin\x86\Release</OutputPath>\r
+    <DefineConstants>TRACE;WINDOWS</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+    <NoStdLib>true</NoStdLib>\r
+    <UseVSHostingProcess>false</UseVSHostingProcess>\r
+    <PlatformTarget>x86</PlatformTarget>\r
+    <XnaCompressContent>true</XnaCompressContent>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=x86">\r
+      <Private>False</Private>\r
+      <SpecificVersion>True</SpecificVersion>\r
+    </Reference>\r
+    <Reference Include="Microsoft.Xna.Framework.Game, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">\r
+      <Private>False</Private>\r
+      <SpecificVersion>True</SpecificVersion>\r
+    </Reference>\r
+    <Reference Include="mscorlib">\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="System">\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="System.Data" />\r
+    <Reference Include="System.Xml">\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="System.Core">\r
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="System.Xml.Linq">\r
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>\r
+      <Private>False</Private>\r
+    </Reference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="CS 3505\IDeterministicGame.cs" />\r
+    <Compile Include="CS 3505\TestHarness.cs" />\r
+    <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="Program.cs" />\r
+    <Compile Include="Game06.cs" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Content Include="Game.ico" />\r
+    <Content Include="GameThumbnail.png" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <NestedContentProject Include="Content\Content.contentproj">\r
+      <Project>56086477-a1fb-4593-8868-2b41d8719294</Project>\r
+      <Visible>False</Visible>\r
+    </NestedContentProject>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">\r
+      <Visible>False</Visible>\r
+      <ProductName>.NET Framework Client Profile</ProductName>\r
+      <Install>false</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">\r
+      <Visible>False</Visible>\r
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>\r
+      <Install>false</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">\r
+      <Visible>False</Visible>\r
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>\r
+      <Install>false</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">\r
+      <Visible>False</Visible>\r
+      <ProductName>.NET Framework 3.5</ProductName>\r
+      <Install>false</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">\r
+      <Visible>False</Visible>\r
+      <ProductName>.NET Framework 3.5 SP1</ProductName>\r
+      <Install>true</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">\r
+      <Visible>False</Visible>\r
+      <ProductName>Windows Installer 3.1</ProductName>\r
+      <Install>true</Install>\r
+    </BootstrapperPackage>\r
+    <BootstrapperPackage Include="Microsoft.Xna.Framework.3.0">\r
+      <Visible>False</Visible>\r
+      <ProductName>Microsoft XNA Framework Redistributable 3.0</ProductName>\r
+      <Install>true</Install>\r
+    </BootstrapperPackage>\r
+  </ItemGroup>\r
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />\r
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+</Project>
\ No newline at end of file
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/IDeterministicGame.cs b/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/IDeterministicGame.cs
new file mode 100644 (file)
index 0000000..45c93ce
--- /dev/null
@@ -0,0 +1,157 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Graphics;\r
+using Microsoft.Xna.Framework.Input;\r
+using Microsoft.Xna.Framework.Content;\r
+\r
+namespace CS_3505_Project_06\r
+{\r
+    /// <summary>\r
+    /// A DeterministicGame object is a full XNA game, except that it does not\r
+    /// extend the Microsoft.Xna.Framework.Game class.  It supports content loading\r
+    /// and unloading, as well as modified Update and Draw functionality.\r
+    /// \r
+    /// DeterministicGame objects are intented to be incorporated inside of an \r
+    /// existing game.  By simply calling update and draw at the appropriate times,\r
+    /// and by supplying user inputs, the game will play just like any other game.\r
+    /// \r
+    /// It is intended that a DeterministicGame be a multiplayer game, and support for\r
+    /// this is listed in the interface below.  Each player is identified by a unique object\r
+    /// reference (of the caller's choice, not a struct).  The game supports the notion of a\r
+    /// current 'frame', or state.  The enclosing code supplies the user inputs for the\r
+    /// next frame by calling methods.  The enclosing code then should call the update\r
+    /// method to advance the game to the next frame.  Finally, the enclosing code\r
+    /// calls the draw method to render the game state.  Note that the game state can\r
+    /// be drawn multiple times without updating the game, thus allowing the game\r
+    /// to be paused or stalled.\r
+    /// </summary>\r
+    public interface IDeterministicGame\r
+    {\r
+        /// <summary>\r
+        /// Call this method to give the game a chance to load its content.\r
+        /// </summary>\r
+        /// <param name="contentManager">A valid content manager pointing to the root of the content tree</param>\r
+        void LoadContent (ContentManager contentManager);\r
+\r
+        /// <summary>\r
+        /// Call this method to give the game a chance to unload its content.\r
+        /// </summary>\r
+        void UnloadContent();\r
+\r
+        /// <summary>\r
+        /// Returns the preferred screen size for this game.\r
+        /// </summary>\r
+        /// <returns></returns>\r
+        Vector2 PreferredScreenSize { get; }\r
+\r
+        /// <summary>\r
+        /// Returns the minimum number of players this game can support.\r
+        /// </summary>\r
+        /// <returns>the minimum player count</returns>\r
+        int MinimumSupportedPlayers { get; }\r
+\r
+        /// <summary>\r
+        /// Returns the maximum number of players this game can support.\r
+        /// </summary>\r
+        /// <returns>the maximum player count</returns>\r
+        int MaximumSupportedPlayers { get; }\r
+\r
+        /// <summary>\r
+        /// Call this method to reset the game state, to set the current frame at 0, and\r
+        /// to supply identifiers for each player in the game.  Player identifiers should\r
+        /// be unique object references (not structs) that the caller will use later\r
+        /// to identify each player.  (It is important that these not be 'boxed' object\r
+        /// references or the reference will not be preserved.)\r
+        /// \r
+        /// Since, in theory, there will be four copies of the game running, a second\r
+        /// parameter identifies the player that is running this copy of the game.\r
+        /// </summary>\r
+        /// <param name="playerIdentifiers">An array of objects (references) that will identify each player</param>\r
+        /// <param name="playerIdentifiers">An object identifier for the player whose machine is displaying this game</param>\r
+        void ResetGame(Object[] playerIdentifiers, Object thisPlayer);\r
+\r
+        /// <summary>\r
+        /// Returns the current frame number.  This corresponds to the current state\r
+        /// of the game world.\r
+        /// </summary>\r
+        /// <returns>the current frame number</returns>\r
+        long CurrentFrameNumber { get; }\r
+\r
+        /// <summary>\r
+        /// Returns a checksum of all of the game world state.  This checksum can be used\r
+        /// to ensure that multiple players at some frame all share the same state.  It is\r
+        /// guaranteed that identical states will produce identical checksums.\r
+        /// </summary>\r
+        /// <returns>the current game state checksum</returns>\r
+        long CurrentChecksum { get; }\r
+\r
+        /// <summary>\r
+        /// Call this method to report changes in keypresses to the game.  You should call this method\r
+        /// to report any changes in keyboard state for a player.  The keyboard state will be\r
+        /// applied to the next game state (not the current state).\r
+        /// </summary>\r
+        /// <param name="playerIdentifier">An object (reference) that was registered for a player in the game</param>\r
+        /// <param name="key">A key identifier</param>\r
+        /// <param name="isKeyPressed">The key state - true means pressed, false means released</param>\r
+        void ApplyKeyInput (Object playerIdentifier, Keys key, bool isKeyPressed);\r
+\r
+        /// <summary>\r
+        /// Call this method to report changes in mouse locations to the game.  You should call this method\r
+        /// any time the mouse coordinates for a player changes.  The mouse information will\r
+        /// be applied to the next game state (not the current state).\r
+        /// </summary>\r
+        /// <param name="playerIdentifier">an object (reference) that was registered for a player in the game</param>\r
+        /// <param name="x">the mouse x location</param>\r
+        /// <param name="y">the mouse y location</param>\r
+        void ApplyMouseLocationInput (Object playerIdentifier, int x, int y);\r
+\r
+        /// <summary>\r
+        /// Call this method to report changes in mouse button state to the game.  Note that only one\r
+        /// mouse button is supported in game.  You should call this method to report any\r
+        /// changes in mouse button state for a player.  The mouse button state will be\r
+        /// applied to the next game state (not the current state).\r
+        /// </summary>\r
+        /// <param name="playerIdentifier">an object (reference) that was registered for a player in the game</param>\r
+        /// <param name="isButtonPressed">the mouse button state</param>\r
+        void ApplyMouseButtonInput (Object playerIdentifier, bool isButtonPressed);\r
+\r
+        /// <summary>\r
+        /// Returns true if the specified player's game is over.  They can be safely disconnected from the game\r
+        /// when this flag is true, their inputs do not affect game state.  (You can continue to report inputs,\r
+        /// to allow the player to view a game over screen, but no game state action is taken.)\r
+        /// </summary>\r
+        /// <param name="playerIdentifier">an object (reference) that was registered for a player in the game</param>\r
+        /// <returns>true if the game is over</returns>\r
+        bool IsGameOver(Object playerIdentifier);\r
+\r
+        /// <summary>\r
+        /// Returns true if the specified player's game is over, and the player has clicked on something indicating\r
+        /// they wish to leave the game over screen.  (This only becomes true if inputs are reported\r
+        /// even after the game is over.)\r
+        /// </summary>\r
+        /// <param name="playerIdentifier">an object (reference) that was registered for a player in the game</param>\r
+        /// <returns>true if the player has terminated the game</returns>\r
+        bool IsTerminated(Object playerIdentifier);\r
+\r
+        /// <summary>\r
+        /// Call this method to advance the game state.  Previously sent inputs are applied\r
+        /// to the game state and the frame number is advanced and returned.  Caution should be used when\r
+        /// supplying the seconds parameter - it can affect game state.  All players in a game\r
+        /// should advance their game time by the same amount.\r
+        /// </summary>\r
+        /// <param name="timespan">The elapsed game time</param>\r
+        /// <returns>the frame number of the new game state (now the current state)</returns>\r
+        long Update(TimeSpan timespan);\r
+\r
+        /// <summary>\r
+        /// Draws the current game state.  This does not affect the game state - it may be called\r
+        /// repeatedly to redraw the current game state if needed.\r
+        /// </summary>\r
+        /// <param name="spriteBatch">a SpriteBatch object that has begun a batch</param>\r
+        /// <returns>the current game state frame number</returns>\r
+        long Draw(SpriteBatch spriteBatch);\r
+    }\r
+}\r
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs b/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs
new file mode 100644 (file)
index 0000000..76bc066
--- /dev/null
@@ -0,0 +1,416 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Input;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Graphics;\r
+\r
+namespace CS_3505_Project_06.CS_3505\r
+{\r
+    // Everything in objects built from this class represent the critical game state\r
+    public class GameState\r
+    {\r
+        public long frameNumber;\r
+\r
+        private long checksum;\r
+        public long Checksum { get { return checksum; } }\r
+\r
+        public bool[] isGameOver;\r
+        public bool[] isTerminated;\r
+\r
+        // Since this is not a game, I'll just keep track of the user inputs as the game state.\r
+\r
+        public int[] mouseLocationX;\r
+        public int[] mouseLocationY;\r
+        public bool[] mouseButton;\r
+        public List<Keys>[] keysDown;\r
+        public int[] keypressCount;\r
+\r
+        public long elapsedTime;\r
+\r
+        /* Constructor */\r
+        public GameState()\r
+        {\r
+            frameNumber = 0;\r
+            checksum = 0;\r
+\r
+            isGameOver = new bool[4];\r
+            isTerminated = new bool[4];\r
+\r
+            mouseLocationX = new int[4];\r
+            mouseLocationY = new int[4];\r
+            mouseButton = new bool[4];\r
+            keysDown = new List<Keys>[4];\r
+            for (int i = 0; i < 4; i++)\r
+                keysDown[i] = new List<Keys>();\r
+            keypressCount = new int[4];\r
+\r
+            elapsedTime = 0;\r
+\r
+            checksum = 0;\r
+        }\r
+\r
+        /* The game engine! */\r
+        public void advanceFrame(NextInputs inputs, long milliseconds)\r
+        {\r
+            // Advance frame number\r
+            frameNumber++;\r
+\r
+            // Advance game - for the test harness, just record statistics and input states.\r
+\r
+            elapsedTime += milliseconds;\r
+\r
+            for (int player = 0; player < 4; player++)\r
+            {\r
+                if (isGameOver[player])\r
+                    continue;\r
+\r
+                if (inputs.mousePressedChanged[player])\r
+                    mouseButton[player] = inputs.mousePressed[player];\r
+\r
+                if (inputs.mouseLocationChanged[player])\r
+                {\r
+                    mouseLocationX[player] = inputs.mouseLocationX[player];\r
+                    mouseLocationY[player] = inputs.mouseLocationY[player];\r
+                }\r
+\r
+                foreach (Keys k in inputs.keysPressed[player])\r
+                    if (!keysDown[player].Contains(k))\r
+                    {\r
+                        keysDown[player].Add(k);\r
+                        keypressCount[player]++;\r
+                    }\r
+\r
+                foreach (Keys k in inputs.keysReleased[player])\r
+                        keysDown[player].Remove(k);                 \r
+\r
+                // If the mouse was pressed for a certain player, activate game over or terminated states as appropriate\r
+\r
+                if (inputs.mousePressed[player])\r
+                    for (int p = 0; p < 4; p++)\r
+                    {\r
+                        int x = 200 * p + 10;\r
+                        int y = 220;\r
+\r
+                        if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&\r
+                            mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)\r
+                        {\r
+                            isGameOver[p] = true;\r
+                        }\r
+                        y += 25;\r
+                        if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&\r
+                            mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)\r
+                        {\r
+                            isGameOver[p] = true;\r
+                            isTerminated[p] = true;\r
+                        }\r
+                    }\r
+\r
+            }\r
+\r
+            // Advance the checksum.\r
+\r
+            computeChecksum();\r
+            \r
+        }\r
+\r
+        /* Just hash the values */\r
+        private long computeChecksum()\r
+        {\r
+            checksum += frameNumber;\r
+            for (int i = 0; i < 4; i++)\r
+            {\r
+                checksum = checksum + keypressCount[i];\r
+                checksum = checksum * 3 + (isGameOver[i] ? 1 : 2);\r
+                checksum = checksum * 3 + (isTerminated[i] ? 1 : 2);\r
+                foreach (Keys k in keysDown[i])\r
+                    checksum = checksum * 257 + (int) k;\r
+                checksum = checksum * 25789 + mouseLocationX[i] * 259 + mouseLocationY[i] + 375;\r
+                checksum = checksum * 3 + (mouseButton[i] ? 1 : 2);\r
+\r
+            }\r
+            checksum += elapsedTime;\r
+\r
+            return checksum;\r
+        }\r
+    }\r
+\r
+    // This class encapsulates inputs from the players.\r
+    public class NextInputs\r
+    {\r
+        public List<Keys>[] keysPressed;\r
+        public List<Keys>[] keysReleased;\r
+        public int[] mouseLocationX;\r
+        public int[] mouseLocationY;\r
+        public bool[] mouseLocationChanged;\r
+        public bool[] mousePressed;\r
+        public bool[] mousePressedChanged;\r
+\r
+        public NextInputs()\r
+        {\r
+            keysPressed = new List<Keys>[4];\r
+            keysReleased = new List<Keys>[4];\r
+            mouseLocationX = new int[4];\r
+            mouseLocationY = new int[4];\r
+            mouseLocationChanged = new bool[4];\r
+            mousePressed = new bool[4];\r
+            mousePressedChanged = new bool[4];\r
+            for (int i = 0; i < 4; i++)\r
+                keysPressed[i] = new List<Keys>();\r
+            for (int i = 0; i < 4; i++)\r
+                keysReleased[i] = new List<Keys>();\r
+        }\r
+    }\r
+\r
+    public class TestHarness : IDeterministicGame\r
+    {\r
+        GameState state;\r
+        NextInputs inputs;\r
+        Object[] playerIdentifiers;\r
+        int thisPlayerID;\r
+\r
+        // Instance variables here contribute to the display, but not the game state\r
+\r
+        Texture2D crosshair;\r
+        SpriteFont font;\r
+\r
+        // Constructor\r
+\r
+        public TestHarness()\r
+        {\r
+            playerIdentifiers = new Object[4];\r
+        }\r
+\r
+        // Helper methods\r
+\r
+        private int idPlayer(Object playerIdentifier)\r
+        {\r
+            for (int i = 0; i < playerIdentifiers.Length; i++)\r
+                if (playerIdentifiers[i] == playerIdentifier)\r
+                    return i;\r
+            throw new Exception("Illegal player identifier" + playerIdentifier);\r
+        }\r
+\r
+        // Implementation of the DeterministicGame interface\r
+        #region IDeterministicGame Members\r
+\r
+        public void LoadContent(ContentManager contentManager)\r
+        {\r
+            crosshair = contentManager.Load<Texture2D>("CS 3505/Crosshair");\r
+            font = contentManager.Load<SpriteFont>("CS 3505/GameFont");\r
+        }\r
+\r
+        public void UnloadContent()\r
+        {\r
+            // Nothing to do - the content manager will take care of it.\r
+        }\r
+\r
+        public Vector2 PreferredScreenSize\r
+        {\r
+            get { return new Vector2(800, 600); }\r
+        }\r
+\r
+        public int MinimumSupportedPlayers\r
+        {\r
+            get { return 4; }\r
+        }\r
+\r
+        public int MaximumSupportedPlayers\r
+        {\r
+            get { return 4; }\r
+        }\r
+\r
+        public void ResetGame(Object[] playerIdentifiers, Object thisPlayer)\r
+        {\r
+            if (playerIdentifiers.Length != 4)\r
+                throw new Exception("This game requires four players.");\r
+\r
+            // Copy the player identifiers - do not rely on the array parameter not changing.\r
+\r
+            for (int i = 0; i < 4; i++)\r
+                this.playerIdentifiers[i] = playerIdentifiers[i];\r
+\r
+            // Create new game state and inputs objects.\r
+\r
+            state = new GameState();\r
+            inputs = new NextInputs();\r
+\r
+            // Record 'this' player.\r
+\r
+            this.thisPlayerID = idPlayer(thisPlayer);\r
+        }\r
+\r
+        public long CurrentFrameNumber\r
+        {\r
+             get { return state.frameNumber; }\r
+        }\r
+\r
+        public long CurrentChecksum\r
+        {\r
+            get { return state.Checksum; }\r
+        }\r
+\r
+        public void ApplyKeyInput(Object playerIdentifier, Keys key, bool isKeyPressed)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+\r
+            if (isKeyPressed && !inputs.keysPressed[player].Contains(key))\r
+                inputs.keysPressed[player].Add(key);\r
+\r
+            if (!isKeyPressed && !inputs.keysReleased[player].Contains(key))\r
+                inputs.keysReleased[player].Add(key);\r
+        }\r
+\r
+        public void ApplyMouseLocationInput(Object playerIdentifier, int x, int y)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            inputs.mouseLocationX[player] = x;\r
+            inputs.mouseLocationY[player] = y;\r
+            inputs.mouseLocationChanged[player] = true;\r
+        }\r
+\r
+        public void ApplyMouseButtonInput(Object playerIdentifier, bool isButtonPressed)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            inputs.mousePressed[player] = isButtonPressed;\r
+            inputs.mousePressedChanged[player] = true;\r
+        }\r
+\r
+        public bool IsGameOver(Object playerIdentifier)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            return state.isGameOver[player] ;\r
+        }\r
+\r
+        public bool IsTerminated(object playerIdentifier)\r
+        {\r
+            int player = idPlayer(playerIdentifier);\r
+            return state.isTerminated[player];\r
+        }\r
+\r
+        public long Update(TimeSpan elapsedTime)\r
+        {\r
+            state.advanceFrame(inputs, elapsedTime.Milliseconds);  // Apply the inputs, advance game state.\r
+\r
+            inputs = new NextInputs();  // Start with inputs cleared on the next frame.\r
+\r
+            return state.frameNumber;\r
+        }\r
+\r
+        public long Draw(SpriteBatch spriteBatch)\r
+        {\r
+            centerString(spriteBatch, Color.White, "CS 3505 - Software Practice 2", 0, 800, 0);\r
+            centerString(spriteBatch, Color.White, "Test Harness", 0, 800, 25);\r
+            centerString(spriteBatch, Color.White, "Debug output", 0, 800, 50);\r
+\r
+            nameIntPair(spriteBatch, Color.White, "Frame:", state.frameNumber, 10, 150, 100);\r
+            nameHexPair(spriteBatch, Color.White, "Checksum:", state.Checksum, 215, 515, 100);\r
+            nameDecPair(spriteBatch, Color.White, "Elapsed Time:", state.elapsedTime / 1000.0f, 570, 790, 100);\r
+\r
+            printPlayer(spriteBatch, Color.Turquoise, 0,  10, 190, 170);\r
+            printPlayer(spriteBatch, Color.Wheat,     1, 210, 390, 170);\r
+            printPlayer(spriteBatch, Color.Tomato,    2, 410, 590, 170);\r
+            printPlayer(spriteBatch, Color.Violet,    3, 610, 790, 170);\r
+\r
+            if (!state.isGameOver[0])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[0] - 5, state.mouseLocationY[0] - 5), Color.Turquoise);\r
+            if (!state.isGameOver[1])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[1] - 5, state.mouseLocationY[1] - 5), Color.Wheat);\r
+            if (!state.isGameOver[2])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[2] - 5, state.mouseLocationY[2] - 5), Color.Tomato);\r
+            if (!state.isGameOver[3])\r
+                spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[3] - 5, state.mouseLocationY[3] - 5), Color.Violet);\r
+\r
+            spriteBatch.Draw(crosshair, new Vector2(Mouse.GetState().X - 5, Mouse.GetState().Y - 5), Color.White);\r
+\r
+            return state.frameNumber;\r
+        }\r
+\r
+        #endregion\r
+\r
+        void printPlayer(SpriteBatch spriteBatch, Color c, int player, float left, float right, float top)\r
+        {\r
+            leftJustify(spriteBatch, c, String.Format("Player {0}", player+1), left, top);\r
+            top += 10;\r
+            leftJustify(spriteBatch, c, "_________", left, top);\r
+            top += 40;\r
+            nameIntPair(spriteBatch, c, "[X] Game Over", state.isGameOver[player]?1:0, left, right, top);\r
+            top += 25;\r
+            nameIntPair(spriteBatch, c, "[X] Terminated", state.isTerminated[player] ? 1 : 0, left, right, top);\r
+            top += 40;\r
+            nameIntPair(spriteBatch, c, "Mouse X", (int)state.mouseLocationX[player], left, right, top);\r
+            top += 25;\r
+            nameIntPair(spriteBatch, c, "Mouse Y", (int)state.mouseLocationY[player], left, right, top);\r
+            top += 40;\r
+            leftJustify(spriteBatch, c, "Mouse", left, top);\r
+            rightJustify(spriteBatch, c, state.mouseButton[player]?"Pressed":"Released", right, top);\r
+            top += 40;\r
+            nameIntPair(spriteBatch, c, "Key count", (int)state.keypressCount[player], left, right, top);\r
+            top += 25;\r
+            leftJustify(spriteBatch, c, "Keys", left, top);\r
+            if (state.keysDown[player].Count == 0)\r
+                rightJustify(spriteBatch, c, "None", right, top);\r
+            else\r
+                foreach (Keys k in state.keysDown[player])\r
+                {\r
+                    rightJustify(spriteBatch, c, k.ToString(), right, top);\r
+                    top += 25;\r
+                }\r
+\r
+        }\r
+\r
+        void centerString(SpriteBatch spriteBatch, Color c, String s, float left, float right, float top)\r
+        {\r
+            Vector2 v = font.MeasureString(s);\r
+            float x = left + (right-left - v.X) / 2;\r
+            float y = top;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void centerString(SpriteBatch spriteBatch, Color c, String s, Rectangle r)\r
+        {\r
+            Vector2 v = font.MeasureString(s);\r
+            float x = r.Left + (r.Width - v.X) / 2;\r
+            float y = r.Top + (r.Height - v.Y) / 2;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void leftJustify(SpriteBatch spriteBatch, Color c, String s, float left, float top)\r
+        {\r
+            float x = left;\r
+            float y = top;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void rightJustify(SpriteBatch spriteBatch, Color c, String s, float right, float top)\r
+        {\r
+            Vector2 v = font.MeasureString(s);\r
+            float x = right - v.X;\r
+            float y = top;\r
+            spriteBatch.DrawString(font, s, new Vector2(x, y), c);\r
+        }\r
+\r
+        void nameDecPair(SpriteBatch spriteBatch, Color c, String name, float number, float left, float right, float top)\r
+        {\r
+            String num = String.Format("{0:.00}", number);\r
+            leftJustify(spriteBatch, c, name, left, top);\r
+            rightJustify(spriteBatch, c, num, right, top);\r
+        }\r
+\r
+        void nameIntPair(SpriteBatch spriteBatch, Color c, String name, long number, float left, float right, float top)\r
+        {\r
+            String num = String.Format("{0}", number);\r
+            leftJustify(spriteBatch, c, name, left, top);\r
+            rightJustify(spriteBatch, c, num, right, top);\r
+        }\r
+\r
+        void nameHexPair(SpriteBatch spriteBatch, Color c, String name, long number, float left, float right, float top)\r
+        {\r
+            String num = String.Format("{0:x}", number);\r
+            leftJustify(spriteBatch, c, name, left, top);\r
+            rightJustify(spriteBatch, c, num, right, top);\r
+        }\r
+    }\r
+}\r
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/Crosshair.png b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/Crosshair.png
new file mode 100644 (file)
index 0000000..1d5f20d
Binary files /dev/null and b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/Crosshair.png differ
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/GameFont.spritefont b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/GameFont.spritefont
new file mode 100644 (file)
index 0000000..4bba2f0
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!--\r
+This file contains an xml description of a font, and will be read by the XNA\r
+Framework Content Pipeline. Follow the comments to customize the appearance\r
+of the font in your game, and to change the characters which are available to draw\r
+with.\r
+-->\r
+<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">\r
+  <Asset Type="Graphics:FontDescription">\r
+\r
+    <!--\r
+    Modify this string to change the font that will be imported.\r
+    -->\r
+    <FontName>Kootenay</FontName>\r
+\r
+    <!--\r
+    Size is a float value, measured in points. Modify this value to change\r
+    the size of the font.\r
+    -->\r
+    <Size>16</Size>\r
+\r
+    <!--\r
+    Spacing is a float value, measured in pixels. Modify this value to change\r
+    the amount of spacing in between characters.\r
+    -->\r
+    <Spacing>0</Spacing>\r
+\r
+    <!--\r
+    UseKerning controls the layout of the font. If this value is true, kerning information\r
+    will be used when placing characters.\r
+    -->\r
+    <UseKerning>true</UseKerning>\r
+\r
+    <!--\r
+    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",\r
+    and "Bold, Italic", and are case sensitive.\r
+    -->\r
+    <Style>Regular</Style>\r
+\r
+    <!--\r
+    If you uncomment this line, the default character will be substituted if you draw\r
+    or measure text that contains characters which were not included in the font.\r
+    -->\r
+    <!-- <DefaultCharacter>*</DefaultCharacter> -->\r
+\r
+    <!--\r
+    CharacterRegions control what letters are available in the font. Every\r
+    character from Start to End will be built and made available for drawing. The\r
+    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin\r
+    character set. The characters are ordered according to the Unicode standard.\r
+    See the documentation for more information.\r
+    -->\r
+    <CharacterRegions>\r
+      <CharacterRegion>\r
+        <Start>&#32;</Start>\r
+        <End>&#126;</End>\r
+      </CharacterRegion>\r
+    </CharacterRegions>\r
+  </Asset>\r
+</XnaContent>\r
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/Content.contentproj b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/Content.contentproj
new file mode 100644 (file)
index 0000000..04a7389
--- /dev/null
@@ -0,0 +1,66 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">\r
+  <PropertyGroup>\r
+    <ProjectGuid>56086477-a1fb-4593-8868-2b41d8719294</ProjectGuid>\r
+    <ProjectTypeGuids>{96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>\r
+    <OutputType>Library</OutputType>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>\r
+    <XnaFrameworkVersion>v3.0</XnaFrameworkVersion>\r
+    <PlatformTarget>x86</PlatformTarget>\r
+    <OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">\r
+    <XnaPlatform>Windows</XnaPlatform>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">\r
+    <XnaPlatform>Windows</XnaPlatform>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.EffectImporter, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.FBXImporter, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.TextureImporter, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.XImporter, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">\r
+      <Private>False</Private>\r
+    </Reference>\r
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline.AudioImporters, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=MSIL">\r
+      <Private>False</Private>\r
+    </Reference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="CS 3505\GameFont.spritefont">\r
+      <Name>GameFont</Name>\r
+      <Importer>FontDescriptionImporter</Importer>\r
+      <Processor>FontDescriptionProcessor</Processor>\r
+    </Compile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="CS 3505\Crosshair.png">\r
+      <Name>Crosshair</Name>\r
+      <Importer>TextureImporter</Importer>\r
+      <Processor>TextureProcessor</Processor>\r
+    </Compile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="InstructionFont.spritefont">\r
+      <Name>InstructionFont</Name>\r
+      <Importer>FontDescriptionImporter</Importer>\r
+      <Processor>FontDescriptionProcessor</Processor>\r
+    </Compile>\r
+  </ItemGroup>\r
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\v3.0\Microsoft.Xna.GameStudio.ContentPipeline.targets" />\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+</Project>
\ No newline at end of file
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/InstructionFont.spritefont b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/InstructionFont.spritefont
new file mode 100644 (file)
index 0000000..bc2c05b
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!--\r
+This file contains an xml description of a font, and will be read by the XNA\r
+Framework Content Pipeline. Follow the comments to customize the appearance\r
+of the font in your game, and to change the characters which are available to draw\r
+with.\r
+-->\r
+<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">\r
+  <Asset Type="Graphics:FontDescription">\r
+\r
+    <!--\r
+    Modify this string to change the font that will be imported.\r
+    -->\r
+    <FontName>Pescadero</FontName>\r
+\r
+    <!--\r
+    Size is a float value, measured in points. Modify this value to change\r
+    the size of the font.\r
+    -->\r
+    <Size>14</Size>\r
+\r
+    <!--\r
+    Spacing is a float value, measured in pixels. Modify this value to change\r
+    the amount of spacing in between characters.\r
+    -->\r
+    <Spacing>0</Spacing>\r
+\r
+    <!--\r
+    UseKerning controls the layout of the font. If this value is true, kerning information\r
+    will be used when placing characters.\r
+    -->\r
+    <UseKerning>true</UseKerning>\r
+\r
+    <!--\r
+    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",\r
+    and "Bold, Italic", and are case sensitive.\r
+    -->\r
+    <Style>Regular</Style>\r
+\r
+    <!--\r
+    If you uncomment this line, the default character will be substituted if you draw\r
+    or measure text that contains characters which were not included in the font.\r
+    -->\r
+    <!-- <DefaultCharacter>*</DefaultCharacter> -->\r
+\r
+    <!--\r
+    CharacterRegions control what letters are available in the font. Every\r
+    character from Start to End will be built and made available for drawing. The\r
+    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin\r
+    character set. The characters are ordered according to the Unicode standard.\r
+    See the documentation for more information.\r
+    -->\r
+    <CharacterRegions>\r
+      <CharacterRegion>\r
+        <Start>&#32;</Start>\r
+        <End>&#126;</End>\r
+      </CharacterRegion>\r
+    </CharacterRegions>\r
+  </Asset>\r
+</XnaContent>\r
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Game.ico b/Project06/CS 3505 Project 06/CS 3505 Project 06/Game.ico
new file mode 100644 (file)
index 0000000..8cff41e
Binary files /dev/null and b/Project06/CS 3505 Project 06/CS 3505 Project 06/Game.ico differ
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Game06.cs b/Project06/CS 3505 Project 06/CS 3505 Project 06/Game06.cs
new file mode 100644 (file)
index 0000000..0a4a228
--- /dev/null
@@ -0,0 +1,230 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Audio;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.GamerServices;\r
+using Microsoft.Xna.Framework.Graphics;\r
+using Microsoft.Xna.Framework.Input;\r
+using Microsoft.Xna.Framework.Media;\r
+using Microsoft.Xna.Framework.Net;\r
+using Microsoft.Xna.Framework.Storage;\r
+using CS_3505_Project_06.CS_3505;\r
+\r
+namespace CS_3505_Project_06\r
+{\r
+    /// <summary>\r
+    /// A game outline for testing network communications\r
+    /// </summary>\r
+    public class Game06 : Microsoft.Xna.Framework.Game\r
+    {\r
+        GraphicsDeviceManager graphics;\r
+        SpriteBatch spriteBatch;\r
+        SpriteFont font;\r
+        \r
+        IDeterministicGame deterministicGame;\r
+        TimeSpan targetTimeSpan;\r
+        Object[] playerIdentifiers = { "One", "Two", "Three", "Four" };  // Any objects will do, strings are easy to debug.\r
+\r
+        // For debugging\r
+\r
+        List<Keys> lastPressedKeys;\r
+        bool lastButtonPressed;\r
+        Object activePlayer;\r
+        bool paused;\r
+        long lastAutoPause;\r
+\r
+        // Constructor\r
+\r
+        public Game06()\r
+        {\r
+            graphics = new GraphicsDeviceManager(this);\r
+            Content.RootDirectory = "Content";\r
+\r
+            // Make the game object.  The game is currently called 'testHarness'.\r
+\r
+            deterministicGame = new TestHarness();\r
+            \r
+            // Debugging setup\r
+\r
+            lastPressedKeys = new List<Keys>();\r
+            activePlayer = playerIdentifiers[0];\r
+            paused = false;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Allows the game to perform any initialization it needs to before starting to run.\r
+        /// This is where it can query for any required services and load any non-graphic\r
+        /// related content.  Calling base.Initialize will enumerate through any components\r
+        /// and initialize them as well.\r
+        /// </summary>\r
+        protected override void Initialize()\r
+        {\r
+            // Set a fixed time span of 1/60th of a second.\r
+\r
+            targetTimeSpan = new TimeSpan(166666); // In 100 nanosecond units = 16 666 600 nanoseconds\r
+            IsFixedTimeStep = true;\r
+            TargetElapsedTime = targetTimeSpan;\r
+\r
+            // Reset the game - indicate that player #1 (player 0) owns this instance of the game.\r
+\r
+            deterministicGame.ResetGame(playerIdentifiers, playerIdentifiers[0]);\r
+\r
+            // For debugging - reset the mouse position to the center of the window.\r
+\r
+            Mouse.SetPosition(400, 300);\r
+\r
+            // Allow the base class to initialize.\r
+\r
+            base.Initialize();\r
+        }\r
+\r
+        /// <summary>\r
+        /// LoadContent will be called once per game and is the place to load\r
+        /// all of your content.\r
+        /// </summary>\r
+        protected override void LoadContent()\r
+        {\r
+            // Create a new SpriteBatch, which can be used to draw textures.\r
+\r
+            spriteBatch = new SpriteBatch(GraphicsDevice);\r
+\r
+            // Let the game load its content.\r
+\r
+            font = Content.Load<SpriteFont>("InstructionFont");\r
+\r
+            deterministicGame.LoadContent(Content);\r
+        }\r
+\r
+        /// <summary>\r
+        /// UnloadContent will be called once per game and is the place to unload\r
+        /// all content.\r
+        /// </summary>\r
+        protected override void UnloadContent()\r
+        {\r
+            deterministicGame.UnloadContent();\r
+        }\r
+\r
+        /// <summary>\r
+        /// Allows the game to run logic such as updating the world,\r
+        /// checking for collisions, gathering input, and playing audio.\r
+        /// </summary>\r
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>\r
+        protected override void Update(GameTime gameTime)\r
+        {\r
+            // Get user's input state.\r
+\r
+            KeyboardState keyState = Keyboard.GetState();\r
+            MouseState mouseState = Mouse.GetState();\r
+\r
+            // Make a list of the keys pressed or released this frame.\r
+\r
+            List<Keys> pressedKeys = new List<Keys>();\r
+            List<Keys> releasedKeys = new List<Keys>();\r
+\r
+            Keys[] pressedKeysArray = keyState.GetPressedKeys();\r
+            foreach (Keys k in pressedKeysArray)\r
+                if (!lastPressedKeys.Contains(k))\r
+                    pressedKeys.Add(k);\r
+                else\r
+                    lastPressedKeys.Remove(k);\r
+\r
+            releasedKeys = lastPressedKeys;\r
+            lastPressedKeys = new List<Keys>(pressedKeysArray);\r
+\r
+            // Get mouse button state.\r
+\r
+            bool buttonPressed = mouseState.LeftButton == ButtonState.Pressed;\r
+\r
+            /***** Begining of game logic. *****/\r
+\r
+            // Debug - allow user to exit.\r
+\r
+            if (pressedKeys.Contains(Keys.Escape))\r
+                this.Exit();\r
+\r
+            // Debug - allow user on this machine to direct input to any player's state in the game.\r
+\r
+            if (pressedKeys.Contains(Keys.F1)) activePlayer = playerIdentifiers[0];\r
+            if (pressedKeys.Contains(Keys.F2)) activePlayer = playerIdentifiers[1];\r
+            if (pressedKeys.Contains(Keys.F3)) activePlayer = playerIdentifiers[2];\r
+            if (pressedKeys.Contains(Keys.F4)) activePlayer = playerIdentifiers[3];\r
+\r
+            // Debug - allow user on this machine to pause/resume game state advances.\r
+\r
+            if (pressedKeys.Contains(Keys.F12) ||\r
+                pressedKeys.Contains(Keys.P) && (keyState.IsKeyDown(Keys.LeftControl) || keyState.IsKeyDown(Keys.RightControl)))\r
+            {\r
+                paused = !paused;\r
+                return;  // Don't update on pause start or stop\r
+            }\r
+\r
+            // Debug - automatically pause every 1000 frames.\r
+\r
+            if (deterministicGame.CurrentFrameNumber % 1000 == 0 && deterministicGame.CurrentFrameNumber != lastAutoPause)\r
+            {\r
+                paused = true;\r
+                lastAutoPause = deterministicGame.CurrentFrameNumber;\r
+            }\r
+\r
+            // Game update\r
+\r
+            // Direct inputs to the game engine - only report changes.\r
+\r
+            foreach (Keys k in pressedKeys)\r
+                deterministicGame.ApplyKeyInput(activePlayer, k, true);\r
+\r
+            foreach (Keys k in releasedKeys)\r
+                deterministicGame.ApplyKeyInput(activePlayer, k, false);\r
+\r
+            deterministicGame.ApplyMouseLocationInput(activePlayer, mouseState.X, mouseState.Y);\r
+\r
+            if (lastButtonPressed != buttonPressed)\r
+                deterministicGame.ApplyMouseButtonInput(activePlayer, buttonPressed);\r
+\r
+            lastButtonPressed = buttonPressed;\r
+\r
+            if (!paused)\r
+            {\r
+                // Advance the game engine.\r
+\r
+                deterministicGame.Update(targetTimeSpan);\r
+            }\r
+\r
+            /***** End of game logic. *****/\r
+\r
+            // Allow the superclass to do any needed updates (unknown purpose).\r
+\r
+            base.Update(gameTime);\r
+        }\r
+\r
+        /// <summary>\r
+        /// This is called when the game should draw itself.\r
+        /// </summary>\r
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>\r
+        protected override void Draw(GameTime gameTime)\r
+        {\r
+            GraphicsDevice.Clear(new Color(16, 16, 16, 255));  // Needed by the test harness, should be removed for the real game.\r
+\r
+            spriteBatch.Begin();\r
+\r
+            // Draw a few instructions.\r
+\r
+            if (paused && gameTime.TotalRealTime.Milliseconds < 500)\r
+                spriteBatch.DrawString(font, "-=> Paused <=-", new Vector2(10, 130), Color.White);\r
+\r
+            spriteBatch.DrawString(font, "Press [F1]...[F4] to simulate input for each player.  Click X's to end game or terminate player.", new Vector2(10, 540), Color.White);\r
+            spriteBatch.DrawString(font, "Press [ESC] to exit and [F12] to pause/unpause.  Game auto-pauses every 1000 frames.", new Vector2(10, 570), Color.White);\r
+\r
+            // Let the game draw itself.\r
+\r
+            deterministicGame.Draw(spriteBatch);\r
+            \r
+\r
+            spriteBatch.End();\r
+\r
+            base.Draw(gameTime);\r
+        }\r
+    }\r
+}\r
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/GameThumbnail.png b/Project06/CS 3505 Project 06/CS 3505 Project 06/GameThumbnail.png
new file mode 100644 (file)
index 0000000..462311a
Binary files /dev/null and b/Project06/CS 3505 Project 06/CS 3505 Project 06/GameThumbnail.png differ
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Program.cs b/Project06/CS 3505 Project 06/CS 3505 Project 06/Program.cs
new file mode 100644 (file)
index 0000000..e43cc08
--- /dev/null
@@ -0,0 +1,19 @@
+using System;\r
+\r
+namespace CS_3505_Project_06\r
+{\r
+    static class Program\r
+    {\r
+        /// <summary>\r
+        /// The main entry point for the application.\r
+        /// </summary>\r
+        static void Main(string[] args)\r
+        {\r
+            using (Game06 game = new Game06())\r
+            {\r
+                game.Run();\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
diff --git a/Project06/CS 3505 Project 06/CS 3505 Project 06/Properties/AssemblyInfo.cs b/Project06/CS 3505 Project 06/CS 3505 Project 06/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..a97a1bc
--- /dev/null
@@ -0,0 +1,33 @@
+using System.Reflection;\r
+using System.Runtime.CompilerServices;\r
+using System.Runtime.InteropServices;\r
+\r
+// General Information about an assembly is controlled through the following \r
+// set of attributes. Change these attribute values to modify the information\r
+// associated with an assembly.\r
+[assembly: AssemblyTitle("CS 3505 Project 06")]\r
+[assembly: AssemblyProduct("CS 3505 Project 06")]\r
+[assembly: AssemblyDescription("")]\r
+[assembly: AssemblyCompany("Microsoft")]\r
+\r
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]\r
+[assembly: AssemblyTrademark("")]\r
+[assembly: AssemblyCulture("")]\r
+\r
+// Setting ComVisible to false makes the types in this assembly not visible \r
+// to COM components.  If you need to access a type in this assembly from \r
+// COM, set the ComVisible attribute to true on that type.\r
+[assembly: ComVisible(false)]\r
+\r
+// The following GUID is for the ID of the typelib if this project is exposed to COM\r
+[assembly: Guid("654b7ae7-964e-40c4-b040-f46b7bec42bb")]\r
+\r
+\r
+// Version information for an assembly consists of the following four values:\r
+//\r
+//      Major Version\r
+//      Minor Version \r
+//      Build Number\r
+//      Revision\r
+//\r
+[assembly: AssemblyVersion("1.0.0.0")]\r
This page took 0.052751 seconds and 4 git commands to generate.