From: brady Date: Sat, 13 Mar 2010 18:38:41 +0000 (+0000) Subject: initial upload X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=42efba22e3fea35522ba3d65d830b2d15718e699;p=chaz%2Fcarfire initial upload git-svn-id: https://bd85.net/svn/cs3505_group@3 92bb83a3-7c8f-8a45-bc97-515c4e399668 --- 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 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 index 0000000..4bba2f0 --- /dev/null +++ b/Project06/CS 3505 Project 06/CS 3505 Project 06/Content/CS 3505/GameFont.spritefont @@ -0,0 +1,60 @@ + + + + + + + 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 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 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 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 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")]