2 using System.Collections.Generic;
5 using Microsoft.Xna.Framework;
6 using Microsoft.Xna.Framework.Content;
7 using Microsoft.Xna.Framework.Graphics;
8 using Microsoft.Xna.Framework.Input;
12 // Everything in objects built from this class represent the critical game state
13 public class GameState
15 public long frameNumber;
17 private long checksum;
18 public long Checksum { get { return checksum; } }
20 public bool[] isGameOver;
21 public bool[] isTerminated;
23 // Since this is not a game, I'll just keep track of the user inputs as the game state.
25 public int[] mouseLocationX;
26 public int[] mouseLocationY;
27 public bool[] mouseButton;
28 public List<Keys>[] keysDown;
29 public int[] keypressCount;
31 public long elapsedTime;
39 isGameOver = new bool[4];
40 isTerminated = new bool[4];
42 mouseLocationX = new int[4];
43 mouseLocationY = new int[4];
44 mouseButton = new bool[4];
45 keysDown = new List<Keys>[4];
46 for (int i = 0; i < 4; i++)
47 keysDown[i] = new List<Keys>();
48 keypressCount = new int[4];
55 /* The game engine! */
56 public void advanceFrame(NextInputs inputs, long milliseconds)
58 // Advance frame number
61 // Advance game - for the test harness, just record statistics and input states.
63 elapsedTime += milliseconds;
65 for (int player = 0; player < 4; player++)
68 //if (isGameOver[player])
71 if (inputs.mousePressedChanged[player])
72 mouseButton[player] = inputs.mousePressed[player];
74 if (inputs.mouseLocationChanged[player])
76 mouseLocationX[player] = inputs.mouseLocationX[player];
77 mouseLocationY[player] = inputs.mouseLocationY[player];
80 foreach (Keys k in inputs.keysPressed[player])
81 if (!keysDown[player].Contains(k))
83 keysDown[player].Add(k);
84 keypressCount[player]++;
87 foreach (Keys k in inputs.keysReleased[player])
88 keysDown[player].Remove(k);
90 // If the mouse was pressed for a certain player, activate game over or terminated states as appropriate
92 if (inputs.mousePressed[player])
93 for (int p = 0; p < 4; p++)
98 if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&
99 mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)
101 isGameOver[p] = true;
104 if (mouseLocationX[player] >= x && mouseLocationY[player] >= y &&
105 mouseLocationX[player] < x + 25 && mouseLocationY[player] < y + 25)
107 isGameOver[p] = true;
108 isTerminated[p] = true;
115 // Advance the checksum.
121 /* Just hash the values */
122 private long computeChecksum()
124 checksum += frameNumber;
125 for (int i = 0; i < 4; i++)
127 checksum = checksum + keypressCount[i];
128 checksum = checksum * 3 + (isGameOver[i] ? 1 : 2);
129 checksum = checksum * 3 + (isTerminated[i] ? 1 : 2);
130 foreach (Keys k in keysDown[i])
131 checksum = checksum * 257 + (int)k;
132 checksum = checksum * 25789 + mouseLocationX[i] * 259 + mouseLocationY[i] + 375;
133 checksum = checksum * 3 + (mouseButton[i] ? 1 : 2);
136 checksum += elapsedTime;
141 //code from Prof Jensen's TestHarness
142 // This class encapsulates inputs from the players.
143 public class NextInputs
145 public List<Keys>[] keysPressed;
146 public List<Keys>[] keysReleased;
147 public int[] mouseLocationX;
148 public int[] mouseLocationY;
149 public bool[] mouseLocationChanged;
150 public bool[] mousePressed;
151 public bool[] mousePressedChanged;
155 keysPressed = new List<Keys>[4];
156 keysReleased = new List<Keys>[4];
157 mouseLocationX = new int[4];
158 mouseLocationY = new int[4];
159 mouseLocationChanged = new bool[4];
160 mousePressed = new bool[4];
161 mousePressedChanged = new bool[4];
162 for (int i = 0; i < 4; i++)
163 keysPressed[i] = new List<Keys>();
164 for (int i = 0; i < 4; i++)
165 keysReleased[i] = new List<Keys>();
170 public class Game : IDeterministicGame
172 #region IDeterministicGame Members
173 List<IPlayer> mPlayers;
175 Object[] playerIdentifiers;
184 mDisplay = new Display();
185 mPlayers = new List<IPlayer>();
186 playerIdentifiers = new Object[4];
188 public void LoadContent(ContentManager contentManager)
190 //Texture2D everything = contentManager.Load<Texture2D>("default");
191 mDisplay.LoadContent(contentManager);
192 int currentCenterX = 5; //Creates a map like the one in Display
193 int currentCenterY = 5;
194 mMap = contentManager.Load<Map>("Maps/stable");
195 Map.DefaultTile = contentManager.Load<Texture2D>("default");
196 mMap.CenterCell = new Vector2(currentCenterX, currentCenterY);
200 public void UnloadContent()
204 private int idPlayer(Object playerIdentifier)
206 for (int i = 0; i < playerIdentifiers.Length; i++)
207 if (playerIdentifiers[i] == playerIdentifier)
209 throw new Exception("Illegal player identifier" + playerIdentifier);
212 public Vector2 PreferredScreenSize
214 get { return new Vector2(800, 600); }
217 public int MinimumSupportedPlayers
222 public int MaximumSupportedPlayers
227 public void ResetGame(object[] PlayerIdentifiers, object thisPlayer)
229 // Now the test harness will at least run with less than 4 players...
230 int numPlayers = PlayerIdentifiers.Count();
231 for (int i = 0; i < numPlayers; i++)
232 this.playerIdentifiers[i] = PlayerIdentifiers[i];
234 // Create new game state and inputs objects.
236 state = new GameState();
237 inputs = new NextInputs();
239 // Record 'this' player.
241 this.thisPlayerID = idPlayer(thisPlayer);
244 for (int i = 0; i < PlayerIdentifiers.Length; i++)
246 Human player = new Human(mMap, "");
247 mPlayers.Add(player);
248 mDisplay.AddCharacters(player);
249 mPlayers.Add(player);
250 mDisplay.AddCharacters(player);
252 this.playerIdentifiers = PlayerIdentifiers;
253 for (int i = 0; i < mPlayers.Count; i++)
255 Point starting = mMap.GetStartingPositionForPlayer(i + 1);
256 mPlayers[i].Spawn(new Vector2(starting.X, starting.Y));
262 public long CurrentFrameNumber
264 get { return state.frameNumber; }
267 public long CurrentChecksum
272 public void ApplyKeyInput(object playerIdentifier, Keys key, bool isKeyPressed)
274 //code from Prof Jensen's TestHarness
275 int player = idPlayer(playerIdentifier);
277 if (isKeyPressed && !inputs.keysPressed[player].Contains(key))
278 inputs.keysPressed[player].Add(key);
280 if (!isKeyPressed && !inputs.keysReleased[player].Contains(key))
281 inputs.keysReleased[player].Add(key);
285 public void ApplyMouseLocationInput(object playerIdentifier, int x, int y)
290 public void ApplyMouseButtonInput(object playerIdentifier, bool isButtonPressed)
295 public bool IsGameOver(object playerIdentifier)
300 public bool IsTerminated(object playerIdentifier)
305 public long Update(TimeSpan elapsedTime)
307 state.advanceFrame(inputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state.
308 mDisplay.Update(elapsedTime, state);
309 inputs = new NextInputs(); // Start with inputs cleared on the next frame.
310 //mDisplay.Update(elapsedTime);
311 return state.frameNumber;
315 public long Draw(SpriteBatch spriteBatch)
317 mDisplay.Draw(spriteBatch);
318 return CurrentFrameNumber;