\r
namespace CarFire\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
+\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
+\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
//code from Prof Jensen's TestHarness\r
// This class encapsulates inputs from the players.\r
public class NextInputs\r
for (int i = 0; i < 4; i++)\r
keysReleased[i] = new List<Keys>();\r
}\r
+ \r
}\r
\r
public class Game : IDeterministicGame\r
Display mDisplay;\r
Map mMap;\r
\r
+ GameState state;\r
+ int thisPlayerID;\r
+\r
public Game()\r
{\r
mDisplay = new Display();\r
mPlayers = new List<IPlayer>();\r
+ playerIdentifiers = new Object[4];\r
}\r
public void LoadContent(ContentManager contentManager)\r
{\r
mMap = contentManager.Load<Map>("Maps/stable");\r
Map.DefaultTile = contentManager.Load<Texture2D>("default");\r
mMap.CenterCell = new Vector2(currentCenterX, currentCenterY);\r
-\r
- Human player = new Human(mMap, "");\r
- player.LoadContent(contentManager);\r
- mPlayers.Add(player);\r
- mDisplay.AddCharacters(player);\r
+ \r
}\r
\r
public void UnloadContent()\r
get { return 4; }\r
}\r
\r
- public void ResetGame(object[] playerIdentifiers, object thisPlayer)\r
+ public void ResetGame(object[] PlayerIdentifiers, object thisPlayer)\r
{\r
- foreach (IPlayer player in mPlayers)\r
+ // Now the test harness will at least run with less than 4 players...\r
+ int numPlayers = PlayerIdentifiers.Count();\r
+ for (int i = 0; i < numPlayers; 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
+ mPlayers.Clear();\r
+ for (int i = 0; i < PlayerIdentifiers.Length; i++)\r
{\r
- player.Spawn(mMap.CenterCell);\r
+ Human player = new Human(mMap, "");\r
+ mPlayers.Add(player);\r
+ mDisplay.AddCharacters(player);\r
+ mPlayers.Add(player);\r
+ mDisplay.AddCharacters(player);\r
}\r
+ this.playerIdentifiers = PlayerIdentifiers;\r
+ for (int i = 0; i < mPlayers.Count; i++) \r
+ {\r
+ Point starting = mMap.GetStartingPositionForPlayer(i + 1);\r
+ mPlayers[i].Spawn(new Vector2(starting.X, starting.Y));\r
+ }\r
+ */\r
+ \r
}\r
\r
public long CurrentFrameNumber\r
{\r
- get { return 0; }\r
+ get { return state.frameNumber; }\r
}\r
\r
public long CurrentChecksum\r
\r
if (!isKeyPressed && !inputs.keysReleased[player].Contains(key))\r
inputs.keysReleased[player].Add(key);\r
+ \r
}\r
\r
public void ApplyMouseLocationInput(object playerIdentifier, int x, int y)\r
return false;\r
}\r
\r
- public long Update(TimeSpan timespan)\r
+ public long Update(TimeSpan elapsedTime)\r
{\r
- mDisplay.Update(timespan);\r
- return CurrentFrameNumber;\r
+ state.advanceFrame(inputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state.\r
+ mDisplay.Update(elapsedTime, state);\r
+ inputs = new NextInputs(); // Start with inputs cleared on the next frame.\r
+ //mDisplay.Update(elapsedTime);\r
+ return state.frameNumber;\r
+ \r
}\r
\r
public long Draw(SpriteBatch spriteBatch)\r