From 42efba22e3fea35522ba3d65d830b2d15718e699 Mon Sep 17 00:00:00 2001 From: brady Date: Sat, 13 Mar 2010 18:38:41 +0000 Subject: [PATCH] initial upload git-svn-id: https://bd85.net/svn/cs3505_group@3 92bb83a3-7c8f-8a45-bc97-515c4e399668 --- .../CS 3505 Project 06/CS 3505 Project 06.sln | 26 ++ .../CS 3505 Project 06.csproj | 149 +++++++ .../CS 3505/IDeterministicGame.cs | 157 +++++++ .../CS 3505 Project 06/CS 3505/TestHarness.cs | 416 ++++++++++++++++++ .../Content/CS 3505/Crosshair.png | Bin 0 -> 2858 bytes .../Content/CS 3505/GameFont.spritefont | 60 +++ .../Content/Content.contentproj | 66 +++ .../Content/InstructionFont.spritefont | 60 +++ .../CS 3505 Project 06/Game.ico | Bin 0 -> 4286 bytes .../CS 3505 Project 06/Game06.cs | 230 ++++++++++ .../CS 3505 Project 06/GameThumbnail.png | Bin 0 -> 5734 bytes .../CS 3505 Project 06/Program.cs | 19 + .../Properties/AssemblyInfo.cs | 33 ++ 13 files changed, 1216 insertions(+) create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06.sln create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505 Project 06.csproj create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/IDeterministicGame.cs create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/Crosshair.png create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/GameFont.spritefont create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Content/Content.contentproj create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Content/InstructionFont.spritefont create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Game.ico create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Game06.cs create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/GameThumbnail.png create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Program.cs create mode 100644 Project06/CS 3505 Project 06/CS 3505 Project 06/Properties/AssemblyInfo.cs 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 index 0000000..9c0c7c9 --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS 3505 Project 06", "CS 3505 Project 06\CS 3505 Project 06.csproj", "{0C08A79E-3951-4C7F-A554-32468808F00D}" +EndProject +Global + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0C08A79E-3951-4C7F-A554-32468808F00D}.Debug|x86.ActiveCfg = Debug|x86 + {0C08A79E-3951-4C7F-A554-32468808F00D}.Debug|x86.Build.0 = Debug|x86 + {0C08A79E-3951-4C7F-A554-32468808F00D}.Release|x86.ActiveCfg = Release|x86 + {0C08A79E-3951-4C7F-A554-32468808F00D}.Release|x86.Build.0 = Release|x86 + {56086477-A1FB-4593-8868-2B41D8719294}.Debug|x86.ActiveCfg = Debug|x86 + {56086477-A1FB-4593-8868-2B41D8719294}.Release|x86.ActiveCfg = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal 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 index 0000000..41013cd --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505 Project 06.csproj @@ -0,0 +1,149 @@ + + + {0C08A79E-3951-4C7F-A554-32468808F00D} + {6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Debug + x86 + WinExe + Properties + CS_3505_Project_06 + CS 3505 Project 06 + v3.5 + v3.0 + Windows + 4c8ffe57-5280-4c98-91c6-e0b1fcc90362 + Game.ico + GameThumbnail.png + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\x86\Debug + DEBUG;TRACE;WINDOWS + prompt + 4 + true + false + x86 + false + + + pdbonly + true + bin\x86\Release + TRACE;WINDOWS + prompt + 4 + true + false + x86 + true + + + + False + True + + + False + True + + + False + + + False + + + + False + + + 3.5 + False + + + 3.5 + False + + + + + + + + + + + + + + + + 56086477-a1fb-4593-8868-2b41d8719294 + False + + + + + False + .NET Framework Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + false + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + False + Microsoft XNA Framework Redistributable 3.0 + true + + + + + + \ 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 index 0000000..45c93ce --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/IDeterministicGame.cs @@ -0,0 +1,157 @@ +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; +using Microsoft.Xna.Framework.Content; + +namespace CS_3505_Project_06 +{ + /// + /// A DeterministicGame object is a full XNA game, except that it does not + /// extend the Microsoft.Xna.Framework.Game class. It supports content loading + /// and unloading, as well as modified Update and Draw functionality. + /// + /// DeterministicGame objects are intented to be incorporated inside of an + /// existing game. By simply calling update and draw at the appropriate times, + /// and by supplying user inputs, the game will play just like any other game. + /// + /// It is intended that a DeterministicGame be a multiplayer game, and support for + /// this is listed in the interface below. Each player is identified by a unique object + /// reference (of the caller's choice, not a struct). The game supports the notion of a + /// current 'frame', or state. The enclosing code supplies the user inputs for the + /// next frame by calling methods. The enclosing code then should call the update + /// method to advance the game to the next frame. Finally, the enclosing code + /// calls the draw method to render the game state. Note that the game state can + /// be drawn multiple times without updating the game, thus allowing the game + /// to be paused or stalled. + /// + public interface IDeterministicGame + { + /// + /// Call this method to give the game a chance to load its content. + /// + /// A valid content manager pointing to the root of the content tree + void LoadContent (ContentManager contentManager); + + /// + /// Call this method to give the game a chance to unload its content. + /// + void UnloadContent(); + + /// + /// Returns the preferred screen size for this game. + /// + /// + Vector2 PreferredScreenSize { get; } + + /// + /// Returns the minimum number of players this game can support. + /// + /// the minimum player count + int MinimumSupportedPlayers { get; } + + /// + /// Returns the maximum number of players this game can support. + /// + /// the maximum player count + int MaximumSupportedPlayers { get; } + + /// + /// Call this method to reset the game state, to set the current frame at 0, and + /// to supply identifiers for each player in the game. Player identifiers should + /// be unique object references (not structs) that the caller will use later + /// to identify each player. (It is important that these not be 'boxed' object + /// references or the reference will not be preserved.) + /// + /// Since, in theory, there will be four copies of the game running, a second + /// parameter identifies the player that is running this copy of the game. + /// + /// An array of objects (references) that will identify each player + /// An object identifier for the player whose machine is displaying this game + void ResetGame(Object[] playerIdentifiers, Object thisPlayer); + + /// + /// Returns the current frame number. This corresponds to the current state + /// of the game world. + /// + /// the current frame number + long CurrentFrameNumber { get; } + + /// + /// Returns a checksum of all of the game world state. This checksum can be used + /// to ensure that multiple players at some frame all share the same state. It is + /// guaranteed that identical states will produce identical checksums. + /// + /// the current game state checksum + long CurrentChecksum { get; } + + /// + /// Call this method to report changes in keypresses to the game. You should call this method + /// to report any changes in keyboard state for a player. The keyboard state will be + /// applied to the next game state (not the current state). + /// + /// An object (reference) that was registered for a player in the game + /// A key identifier + /// The key state - true means pressed, false means released + void ApplyKeyInput (Object playerIdentifier, Keys key, bool isKeyPressed); + + /// + /// Call this method to report changes in mouse locations to the game. You should call this method + /// any time the mouse coordinates for a player changes. The mouse information will + /// be applied to the next game state (not the current state). + /// + /// an object (reference) that was registered for a player in the game + /// the mouse x location + /// the mouse y location + void ApplyMouseLocationInput (Object playerIdentifier, int x, int y); + + /// + /// Call this method to report changes in mouse button state to the game. Note that only one + /// mouse button is supported in game. You should call this method to report any + /// changes in mouse button state for a player. The mouse button state will be + /// applied to the next game state (not the current state). + /// + /// an object (reference) that was registered for a player in the game + /// the mouse button state + void ApplyMouseButtonInput (Object playerIdentifier, bool isButtonPressed); + + /// + /// Returns true if the specified player's game is over. They can be safely disconnected from the game + /// when this flag is true, their inputs do not affect game state. (You can continue to report inputs, + /// to allow the player to view a game over screen, but no game state action is taken.) + /// + /// an object (reference) that was registered for a player in the game + /// true if the game is over + bool IsGameOver(Object playerIdentifier); + + /// + /// Returns true if the specified player's game is over, and the player has clicked on something indicating + /// they wish to leave the game over screen. (This only becomes true if inputs are reported + /// even after the game is over.) + /// + /// an object (reference) that was registered for a player in the game + /// true if the player has terminated the game + bool IsTerminated(Object playerIdentifier); + + /// + /// Call this method to advance the game state. Previously sent inputs are applied + /// to the game state and the frame number is advanced and returned. Caution should be used when + /// supplying the seconds parameter - it can affect game state. All players in a game + /// should advance their game time by the same amount. + /// + /// The elapsed game time + /// the frame number of the new game state (now the current state) + long Update(TimeSpan timespan); + + /// + /// Draws the current game state. This does not affect the game state - it may be called + /// repeatedly to redraw the current game state if needed. + /// + /// a SpriteBatch object that has begun a batch + /// the current game state frame number + long Draw(SpriteBatch spriteBatch); + } +} 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 index 0000000..76bc066 --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/CS 3505/TestHarness.cs @@ -0,0 +1,416 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace CS_3505_Project_06.CS_3505 +{ + // Everything in objects built from this class represent the critical game state + public class GameState + { + public long frameNumber; + + private long checksum; + public long Checksum { get { return checksum; } } + + public bool[] isGameOver; + public bool[] isTerminated; + + // Since this is not a game, I'll just keep track of the user inputs as the game state. + + public int[] mouseLocationX; + public int[] mouseLocationY; + public bool[] mouseButton; + public List[] keysDown; + public int[] keypressCount; + + public long elapsedTime; + + /* Constructor */ + public GameState() + { + frameNumber = 0; + checksum = 0; + + isGameOver = new bool[4]; + isTerminated = new bool[4]; + + mouseLocationX = new int[4]; + mouseLocationY = new int[4]; + mouseButton = new bool[4]; + keysDown = new List[4]; + for (int i = 0; i < 4; i++) + keysDown[i] = new List(); + keypressCount = new int[4]; + + elapsedTime = 0; + + checksum = 0; + } + + /* The game engine! */ + public void advanceFrame(NextInputs inputs, long milliseconds) + { + // Advance frame number + frameNumber++; + + // Advance game - for the test harness, just record statistics and input states. + + elapsedTime += milliseconds; + + for (int player = 0; player < 4; player++) + { + if (isGameOver[player]) + continue; + + if (inputs.mousePressedChanged[player]) + mouseButton[player] = inputs.mousePressed[player]; + + if (inputs.mouseLocationChanged[player]) + { + mouseLocationX[player] = inputs.mouseLocationX[player]; + mouseLocationY[player] = inputs.mouseLocationY[player]; + } + + foreach (Keys k in inputs.keysPressed[player]) + if (!keysDown[player].Contains(k)) + { + keysDown[player].Add(k); + keypressCount[player]++; + } + + foreach (Keys k in inputs.keysReleased[player]) + keysDown[player].Remove(k); + + // If the mouse was pressed for a certain player, activate game over or terminated states as appropriate + + if (inputs.mousePressed[player]) + for (int p = 0; p < 4; p++) + { + int x = 200 * p + 10; + int y = 220; + + if (mouseLocationX[player] >= x && mouseLocationY[player] >= y && + mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25) + { + isGameOver[p] = true; + } + y += 25; + if (mouseLocationX[player] >= x && mouseLocationY[player] >= y && + mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25) + { + isGameOver[p] = true; + isTerminated[p] = true; + } + } + + } + + // Advance the checksum. + + computeChecksum(); + + } + + /* Just hash the values */ + private long computeChecksum() + { + checksum += frameNumber; + for (int i = 0; i < 4; i++) + { + checksum = checksum + keypressCount[i]; + checksum = checksum * 3 + (isGameOver[i] ? 1 : 2); + checksum = checksum * 3 + (isTerminated[i] ? 1 : 2); + foreach (Keys k in keysDown[i]) + checksum = checksum * 257 + (int) k; + checksum = checksum * 25789 + mouseLocationX[i] * 259 + mouseLocationY[i] + 375; + checksum = checksum * 3 + (mouseButton[i] ? 1 : 2); + + } + checksum += elapsedTime; + + return checksum; + } + } + + // This class encapsulates inputs from the players. + public class NextInputs + { + public List[] keysPressed; + public List[] keysReleased; + public int[] mouseLocationX; + public int[] mouseLocationY; + public bool[] mouseLocationChanged; + public bool[] mousePressed; + public bool[] mousePressedChanged; + + public NextInputs() + { + keysPressed = new List[4]; + keysReleased = new List[4]; + mouseLocationX = new int[4]; + mouseLocationY = new int[4]; + mouseLocationChanged = new bool[4]; + mousePressed = new bool[4]; + mousePressedChanged = new bool[4]; + for (int i = 0; i < 4; i++) + keysPressed[i] = new List(); + for (int i = 0; i < 4; i++) + keysReleased[i] = new List(); + } + } + + public class TestHarness : IDeterministicGame + { + GameState state; + NextInputs inputs; + Object[] playerIdentifiers; + int thisPlayerID; + + // Instance variables here contribute to the display, but not the game state + + Texture2D crosshair; + SpriteFont font; + + // Constructor + + public TestHarness() + { + playerIdentifiers = new Object[4]; + } + + // Helper methods + + private int idPlayer(Object playerIdentifier) + { + for (int i = 0; i < playerIdentifiers.Length; i++) + if (playerIdentifiers[i] == playerIdentifier) + return i; + throw new Exception("Illegal player identifier" + playerIdentifier); + } + + // Implementation of the DeterministicGame interface + #region IDeterministicGame Members + + public void LoadContent(ContentManager contentManager) + { + crosshair = contentManager.Load("CS 3505/Crosshair"); + font = contentManager.Load("CS 3505/GameFont"); + } + + public void UnloadContent() + { + // Nothing to do - the content manager will take care of it. + } + + public Vector2 PreferredScreenSize + { + get { return new Vector2(800, 600); } + } + + public int MinimumSupportedPlayers + { + get { return 4; } + } + + public int MaximumSupportedPlayers + { + get { return 4; } + } + + public void ResetGame(Object[] playerIdentifiers, Object thisPlayer) + { + if (playerIdentifiers.Length != 4) + throw new Exception("This game requires four players."); + + // Copy the player identifiers - do not rely on the array parameter not changing. + + for (int i = 0; i < 4; i++) + this.playerIdentifiers[i] = playerIdentifiers[i]; + + // Create new game state and inputs objects. + + state = new GameState(); + inputs = new NextInputs(); + + // Record 'this' player. + + this.thisPlayerID = idPlayer(thisPlayer); + } + + public long CurrentFrameNumber + { + get { return state.frameNumber; } + } + + public long CurrentChecksum + { + get { return state.Checksum; } + } + + public void ApplyKeyInput(Object playerIdentifier, Keys key, bool isKeyPressed) + { + int player = idPlayer(playerIdentifier); + + if (isKeyPressed && !inputs.keysPressed[player].Contains(key)) + inputs.keysPressed[player].Add(key); + + if (!isKeyPressed && !inputs.keysReleased[player].Contains(key)) + inputs.keysReleased[player].Add(key); + } + + public void ApplyMouseLocationInput(Object playerIdentifier, int x, int y) + { + int player = idPlayer(playerIdentifier); + inputs.mouseLocationX[player] = x; + inputs.mouseLocationY[player] = y; + inputs.mouseLocationChanged[player] = true; + } + + public void ApplyMouseButtonInput(Object playerIdentifier, bool isButtonPressed) + { + int player = idPlayer(playerIdentifier); + inputs.mousePressed[player] = isButtonPressed; + inputs.mousePressedChanged[player] = true; + } + + public bool IsGameOver(Object playerIdentifier) + { + int player = idPlayer(playerIdentifier); + return state.isGameOver[player] ; + } + + public bool IsTerminated(object playerIdentifier) + { + int player = idPlayer(playerIdentifier); + return state.isTerminated[player]; + } + + public long Update(TimeSpan elapsedTime) + { + state.advanceFrame(inputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state. + + inputs = new NextInputs(); // Start with inputs cleared on the next frame. + + return state.frameNumber; + } + + public long Draw(SpriteBatch spriteBatch) + { + centerString(spriteBatch, Color.White, "CS 3505 - Software Practice 2", 0, 800, 0); + centerString(spriteBatch, Color.White, "Test Harness", 0, 800, 25); + centerString(spriteBatch, Color.White, "Debug output", 0, 800, 50); + + nameIntPair(spriteBatch, Color.White, "Frame:", state.frameNumber, 10, 150, 100); + nameHexPair(spriteBatch, Color.White, "Checksum:", state.Checksum, 215, 515, 100); + nameDecPair(spriteBatch, Color.White, "Elapsed Time:", state.elapsedTime / 1000.0f, 570, 790, 100); + + printPlayer(spriteBatch, Color.Turquoise, 0, 10, 190, 170); + printPlayer(spriteBatch, Color.Wheat, 1, 210, 390, 170); + printPlayer(spriteBatch, Color.Tomato, 2, 410, 590, 170); + printPlayer(spriteBatch, Color.Violet, 3, 610, 790, 170); + + if (!state.isGameOver[0]) + spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[0] - 5, state.mouseLocationY[0] - 5), Color.Turquoise); + if (!state.isGameOver[1]) + spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[1] - 5, state.mouseLocationY[1] - 5), Color.Wheat); + if (!state.isGameOver[2]) + spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[2] - 5, state.mouseLocationY[2] - 5), Color.Tomato); + if (!state.isGameOver[3]) + spriteBatch.Draw(crosshair, new Vector2(state.mouseLocationX[3] - 5, state.mouseLocationY[3] - 5), Color.Violet); + + spriteBatch.Draw(crosshair, new Vector2(Mouse.GetState().X - 5, Mouse.GetState().Y - 5), Color.White); + + return state.frameNumber; + } + + #endregion + + void printPlayer(SpriteBatch spriteBatch, Color c, int player, float left, float right, float top) + { + leftJustify(spriteBatch, c, String.Format("Player {0}", player+1), left, top); + top += 10; + leftJustify(spriteBatch, c, "_________", left, top); + top += 40; + nameIntPair(spriteBatch, c, "[X] Game Over", state.isGameOver[player]?1:0, left, right, top); + top += 25; + nameIntPair(spriteBatch, c, "[X] Terminated", state.isTerminated[player] ? 1 : 0, left, right, top); + top += 40; + nameIntPair(spriteBatch, c, "Mouse X", (int)state.mouseLocationX[player], left, right, top); + top += 25; + nameIntPair(spriteBatch, c, "Mouse Y", (int)state.mouseLocationY[player], left, right, top); + top += 40; + leftJustify(spriteBatch, c, "Mouse", left, top); + rightJustify(spriteBatch, c, state.mouseButton[player]?"Pressed":"Released", right, top); + top += 40; + nameIntPair(spriteBatch, c, "Key count", (int)state.keypressCount[player], left, right, top); + top += 25; + leftJustify(spriteBatch, c, "Keys", left, top); + if (state.keysDown[player].Count == 0) + rightJustify(spriteBatch, c, "None", right, top); + else + foreach (Keys k in state.keysDown[player]) + { + rightJustify(spriteBatch, c, k.ToString(), right, top); + top += 25; + } + + } + + void centerString(SpriteBatch spriteBatch, Color c, String s, float left, float right, float top) + { + Vector2 v = font.MeasureString(s); + float x = left + (right-left - v.X) / 2; + float y = top; + spriteBatch.DrawString(font, s, new Vector2(x, y), c); + } + + void centerString(SpriteBatch spriteBatch, Color c, String s, Rectangle r) + { + Vector2 v = font.MeasureString(s); + float x = r.Left + (r.Width - v.X) / 2; + float y = r.Top + (r.Height - v.Y) / 2; + spriteBatch.DrawString(font, s, new Vector2(x, y), c); + } + + void leftJustify(SpriteBatch spriteBatch, Color c, String s, float left, float top) + { + float x = left; + float y = top; + spriteBatch.DrawString(font, s, new Vector2(x, y), c); + } + + void rightJustify(SpriteBatch spriteBatch, Color c, String s, float right, float top) + { + Vector2 v = font.MeasureString(s); + float x = right - v.X; + float y = top; + spriteBatch.DrawString(font, s, new Vector2(x, y), c); + } + + void nameDecPair(SpriteBatch spriteBatch, Color c, String name, float number, float left, float right, float top) + { + String num = String.Format("{0:.00}", number); + leftJustify(spriteBatch, c, name, left, top); + rightJustify(spriteBatch, c, num, right, top); + } + + void nameIntPair(SpriteBatch spriteBatch, Color c, String name, long number, float left, float right, float top) + { + String num = String.Format("{0}", number); + leftJustify(spriteBatch, c, name, left, top); + rightJustify(spriteBatch, c, num, right, top); + } + + void nameHexPair(SpriteBatch spriteBatch, Color c, String name, long number, float left, float right, float top) + { + String num = String.Format("{0:x}", number); + leftJustify(spriteBatch, c, name, left, top); + rightJustify(spriteBatch, c, num, right, top); + } + } +} 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 index 0000000000000000000000000000000000000000..1d5f20d72fc6e912261d751b0de866b39976b7bb GIT binary patch literal 2858 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 + + + + + + Kootenay + + + 16 + + + 0 + + + true + + + + + + + + + + + + ~ + + + + 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 index 0000000..04a7389 --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/Content.contentproj @@ -0,0 +1,66 @@ + + + 56086477-a1fb-4593-8868-2b41d8719294 + {96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Debug + x86 + Library + Properties + v3.5 + v3.0 + x86 + bin\$(Platform)\$(Configuration) + + + Windows + + + Windows + + + + False + + + False + + + False + + + False + + + False + + + + + GameFont + FontDescriptionImporter + FontDescriptionProcessor + + + + + Crosshair + TextureImporter + TextureProcessor + + + + + InstructionFont + FontDescriptionImporter + FontDescriptionProcessor + + + + + \ 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 index 0000000..bc2c05b --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/InstructionFont.spritefont @@ -0,0 +1,60 @@ + + + + + + + Pescadero + + + 14 + + + 0 + + + true + + + + + + + + + + + + ~ + + + + 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 index 0000000000000000000000000000000000000000..8cff41eab28dc99e31a693a39d399f9eb05f1cce GIT binary patch literal 4286 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 literal 0 HcmV?d00001 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 index 0000000..0a4a228 --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/Game06.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.GamerServices; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Media; +using Microsoft.Xna.Framework.Net; +using Microsoft.Xna.Framework.Storage; +using CS_3505_Project_06.CS_3505; + +namespace CS_3505_Project_06 +{ + /// + /// A game outline for testing network communications + /// + public class Game06 : Microsoft.Xna.Framework.Game + { + GraphicsDeviceManager graphics; + SpriteBatch spriteBatch; + SpriteFont font; + + IDeterministicGame deterministicGame; + TimeSpan targetTimeSpan; + Object[] playerIdentifiers = { "One", "Two", "Three", "Four" }; // Any objects will do, strings are easy to debug. + + // For debugging + + List lastPressedKeys; + bool lastButtonPressed; + Object activePlayer; + bool paused; + long lastAutoPause; + + // Constructor + + public Game06() + { + graphics = new GraphicsDeviceManager(this); + Content.RootDirectory = "Content"; + + // Make the game object. The game is currently called 'testHarness'. + + deterministicGame = new TestHarness(); + + // Debugging setup + + lastPressedKeys = new List(); + activePlayer = playerIdentifiers[0]; + paused = false; + } + + /// + /// 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. + /// + protected override void Initialize() + { + // Set a fixed time span of 1/60th of a second. + + targetTimeSpan = new TimeSpan(166666); // In 100 nanosecond units = 16 666 600 nanoseconds + IsFixedTimeStep = true; + TargetElapsedTime = targetTimeSpan; + + // Reset the game - indicate that player #1 (player 0) owns this instance of the game. + + deterministicGame.ResetGame(playerIdentifiers, playerIdentifiers[0]); + + // For debugging - reset the mouse position to the center of the window. + + Mouse.SetPosition(400, 300); + + // Allow the base class to initialize. + + base.Initialize(); + } + + /// + /// LoadContent will be called once per game and is the place to load + /// all of your content. + /// + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + + spriteBatch = new SpriteBatch(GraphicsDevice); + + // Let the game load its content. + + font = Content.Load("InstructionFont"); + + deterministicGame.LoadContent(Content); + } + + /// + /// UnloadContent will be called once per game and is the place to unload + /// all content. + /// + protected override void UnloadContent() + { + deterministicGame.UnloadContent(); + } + + /// + /// Allows the game to run logic such as updating the world, + /// checking for collisions, gathering input, and playing audio. + /// + /// Provides a snapshot of timing values. + protected override void Update(GameTime gameTime) + { + // Get user's input state. + + KeyboardState keyState = Keyboard.GetState(); + MouseState mouseState = Mouse.GetState(); + + // Make a list of the keys pressed or released this frame. + + List pressedKeys = new List(); + List releasedKeys = new List(); + + Keys[] pressedKeysArray = keyState.GetPressedKeys(); + foreach (Keys k in pressedKeysArray) + if (!lastPressedKeys.Contains(k)) + pressedKeys.Add(k); + else + lastPressedKeys.Remove(k); + + releasedKeys = lastPressedKeys; + lastPressedKeys = new List(pressedKeysArray); + + // Get mouse button state. + + bool buttonPressed = mouseState.LeftButton == ButtonState.Pressed; + + /***** Begining of game logic. *****/ + + // Debug - allow user to exit. + + if (pressedKeys.Contains(Keys.Escape)) + this.Exit(); + + // Debug - allow user on this machine to direct input to any player's state in the game. + + if (pressedKeys.Contains(Keys.F1)) activePlayer = playerIdentifiers[0]; + if (pressedKeys.Contains(Keys.F2)) activePlayer = playerIdentifiers[1]; + if (pressedKeys.Contains(Keys.F3)) activePlayer = playerIdentifiers[2]; + if (pressedKeys.Contains(Keys.F4)) activePlayer = playerIdentifiers[3]; + + // Debug - allow user on this machine to pause/resume game state advances. + + if (pressedKeys.Contains(Keys.F12) || + pressedKeys.Contains(Keys.P) && (keyState.IsKeyDown(Keys.LeftControl) || keyState.IsKeyDown(Keys.RightControl))) + { + paused = !paused; + return; // Don't update on pause start or stop + } + + // Debug - automatically pause every 1000 frames. + + if (deterministicGame.CurrentFrameNumber % 1000 == 0 && deterministicGame.CurrentFrameNumber != lastAutoPause) + { + paused = true; + lastAutoPause = deterministicGame.CurrentFrameNumber; + } + + // Game update + + // Direct inputs to the game engine - only report changes. + + foreach (Keys k in pressedKeys) + deterministicGame.ApplyKeyInput(activePlayer, k, true); + + foreach (Keys k in releasedKeys) + deterministicGame.ApplyKeyInput(activePlayer, k, false); + + deterministicGame.ApplyMouseLocationInput(activePlayer, mouseState.X, mouseState.Y); + + if (lastButtonPressed != buttonPressed) + deterministicGame.ApplyMouseButtonInput(activePlayer, buttonPressed); + + lastButtonPressed = buttonPressed; + + if (!paused) + { + // Advance the game engine. + + deterministicGame.Update(targetTimeSpan); + } + + /***** End of game logic. *****/ + + // Allow the superclass to do any needed updates (unknown purpose). + + base.Update(gameTime); + } + + /// + /// This is called when the game should draw itself. + /// + /// Provides a snapshot of timing values. + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(new Color(16, 16, 16, 255)); // Needed by the test harness, should be removed for the real game. + + spriteBatch.Begin(); + + // Draw a few instructions. + + if (paused && gameTime.TotalRealTime.Milliseconds < 500) + spriteBatch.DrawString(font, "-=> Paused <=-", new Vector2(10, 130), Color.White); + + 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); + spriteBatch.DrawString(font, "Press [ESC] to exit and [F12] to pause/unpause. Game auto-pauses every 1000 frames.", new Vector2(10, 570), Color.White); + + // Let the game draw itself. + + deterministicGame.Draw(spriteBatch); + + + spriteBatch.End(); + + base.Draw(gameTime); + } + } +} 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 index 0000000000000000000000000000000000000000..462311aba2cd09de3992129ca43564755249ef09 GIT binary patch literal 5734 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 Y0L3g3-xp*i%>V!Z07*qoM6N<$f>>Wb>;M1& literal 0 HcmV?d00001 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 index 0000000..e43cc08 --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/Program.cs @@ -0,0 +1,19 @@ +using System; + +namespace CS_3505_Project_06 +{ + static class Program + { + /// + /// The main entry point for the application. + /// + static void Main(string[] args) + { + using (Game06 game = new Game06()) + { + game.Run(); + } + } + } +} + 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 index 0000000..a97a1bc --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CS 3505 Project 06")] +[assembly: AssemblyProduct("CS 3505 Project 06")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("Microsoft")] + +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("654b7ae7-964e-40c4-b040-f46b7bec42bb")] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] -- 2.43.0