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;
13 /// Container class for the whole state of the game.
15 public class GameState
17 #region Public Properties
19 public long FrameNumber { get { return mFrameNumber; } }
21 public long Checksum { get { return mChecksum; } }
23 public int NumberOfPlayers { get { return mNumberOfPlayers; } }
26 public List<IEntity> Entities = new List<IEntity>();
31 #region Public Methods
34 /// Construct a game state container with the number of players.
36 /// <param name="numPlayers">Number of players.</param>
37 public GameState(int numPlayers)
39 mNumberOfPlayers = numPlayers;
42 mIsGameOver = new bool[numPlayers];
43 mIsTerminated = new bool[numPlayers];
45 mMouseLocation = new Point[numPlayers];
46 mMouseButton = new bool[numPlayers];
47 mKeysDown = new List<Keys>[numPlayers];
48 for (int i = 0; i < numPlayers; i++) mKeysDown[i] = new List<Keys>();
50 mKeypressCount = new int[numPlayers];
57 /// Should be called by the Game class to advance the state
58 /// to the next frame.
60 /// <param name="inputs">The inputs that occurred to be
61 /// applied this coming frame.</param>
62 /// <param name="milliseconds">Milliseconds; used for the checksum.</param>
63 public void AdvanceFrame(NextInputs inputs, long milliseconds)
66 mElapsedTime += milliseconds;
68 for (int player = 0; player < NumberOfPlayers; player++)
70 if (inputs.IsMousePressedChanged[player])
72 mMouseButton[player] = inputs.MousePressed[player];
75 if (inputs.IsMouseLocationChanged[player])
77 mMouseLocation[player] = inputs.MouseLocation[player];
80 foreach (Keys k in inputs.KeysPressed[player])
82 if (!mKeysDown[player].Contains(k))
84 mKeysDown[player].Add(k);
85 mKeypressCount[player]++;
89 foreach (Keys k in inputs.KeysReleased[player]) mKeysDown[player].Remove(k);
97 /// Get the mouse location for a player.
99 /// <param name="playerNum">Player Number.</param>
100 /// <returns>Mouse location.</returns>
101 public Point GetMouseLocation(int playerNum)
103 return mMouseLocation[playerNum];
107 /// Get the mouse button state for a player.
109 /// <param name="playerNum">Player number.</param>
110 /// <returns>Mouse button state..</returns>
111 public bool GetMouseButton(int playerNum)
113 return mMouseButton[playerNum];
117 /// Get the keyboard state for a player.
119 /// <param name="playerNum">Player number.</param>
120 /// <returns>Keyboard state.</returns>
121 public List<Keys> GetKeysDown(int playerNum)
123 return mKeysDown[playerNum];
129 #region Private Methods
131 // Calculates a checksum for debugging network synchronization issues.
132 long ComputeChecksum()
134 mChecksum += FrameNumber;
135 for (int i = 0; i < NumberOfPlayers; i++)
137 mChecksum = mChecksum + mKeypressCount[i];
138 mChecksum = mChecksum * 3 + (mIsGameOver[i] ? 1 : 2);
139 mChecksum = mChecksum * 3 + (mIsTerminated[i] ? 1 : 2);
140 foreach (Keys k in mKeysDown[i])
141 mChecksum = mChecksum * 257 + (int)k;
142 mChecksum = mChecksum * 25789 + mMouseLocation[i].X * 259 + mMouseLocation[i].Y + 375;
143 mChecksum = mChecksum * 3 + (mMouseButton[i] ? 1 : 2);
146 mChecksum += mElapsedTime;
154 #region Private Variables
156 int mNumberOfPlayers;
157 public Point[] mMouseLocation;
158 public bool[] mMouseButton;
159 public List<Keys>[] mKeysDown;
164 bool[] mIsTerminated;
166 int[] mKeypressCount;
174 /// Container class for all the inputs for a single frame.
176 public class NextInputs
178 public List<Keys>[] KeysPressed;
179 public List<Keys>[] KeysReleased;
180 public Point[] MouseLocation;
181 public bool[] IsMouseLocationChanged;
182 public bool[] MousePressed;
183 public bool[] IsMousePressedChanged;
185 public NextInputs(int numPlayers)
187 KeysPressed = new List<Keys>[numPlayers];
188 KeysReleased = new List<Keys>[numPlayers];
189 IsMouseLocationChanged = new bool[numPlayers];
190 MousePressed = new bool[numPlayers];
191 IsMousePressedChanged = new bool[numPlayers];
192 for (int i = 0; i < numPlayers; i++) KeysPressed[i] = new List<Keys>();
193 for (int i = 0; i < numPlayers; i++) KeysReleased[i] = new List<Keys>();
201 public class Game : IDeterministicGame
203 #region Public Properties
206 /// Get the content manager associated with this game.
208 public ContentManager ContentManager { get { return mContentManager; } }
213 public GameState State;
219 bool[,] grid = State.Map.Grid;
220 foreach (IEntity entity in State.Entities)
222 Point coordinates = entity.Coordinates;
223 grid[coordinates.X, coordinates.Y] = true;
232 #region Public Methods
234 public bool IsCellOpen(Point point)
236 if (!State.Map.IsCellOpen(point)) return false;
237 foreach (IEntity entity in State.Entities)
239 if (entity.Coordinates == point) return false;
246 mDisplay = new Display(this);
248 public void LoadContent(ContentManager contentManager)
250 mContentManager = contentManager;
251 mDisplay.LoadContent(contentManager);
254 public void UnloadContent()
258 private int GetPlayerNumber(Object playerIdentifier)
260 for (int i = 0; i < mPlayerIdentifiers.Length; i++)
262 if (mPlayerIdentifiers[i] == playerIdentifier) return i;
264 throw new Exception("Illegal player identifier" + playerIdentifier);
267 public Vector2 PreferredScreenSize
269 get { return new Vector2(800, 600); }
272 public int MinimumSupportedPlayers
277 public int MaximumSupportedPlayers
282 public void ResetGame(object[] playerIdentifiers, object thisPlayer)
284 int numPlayers = playerIdentifiers.Count();
286 mPlayerIdentifiers = new object[numPlayers];
287 for (int i = 0; i < numPlayers; i++) mPlayerIdentifiers[i] = playerIdentifiers[i];
289 mThisPlayerID = GetPlayerNumber(thisPlayer);
291 State = new GameState(numPlayers);
292 mInputs = new NextInputs(numPlayers);
294 State.Map = mContentManager.Load<Map>("Maps/stable");
295 State.Map.Game = this;
296 State.Entities = State.Map.GetAllEntities();
297 Map.DefaultTile = mContentManager.Load<Texture2D>("default");
301 for (int i = 0; i < PlayerIdentifiers.Length; i++)
303 Human player = new Human(mMap, "");
304 mPlayers.Add(player);
305 mDisplay.AddCharacters(player);
306 mPlayers.Add(player);
307 mDisplay.AddCharacters(player);
309 this.playerIdentifiers = PlayerIdentifiers;
310 for (int i = 0; i < mPlayers.Count; i++)
312 Point starting = mMap.GetStartingPositionForPlayer(i + 1);
313 mPlayers[i].Spawn(new Vector2(starting.X, starting.Y));
318 public long CurrentFrameNumber
320 get { return State.FrameNumber; }
323 public long CurrentChecksum
328 public void ApplyKeyInput(object playerIdentifier, Keys key, bool isKeyPressed)
330 //code from Prof Jensen's TestHarness
331 int player = GetPlayerNumber(playerIdentifier);
333 if (isKeyPressed && !mInputs.KeysPressed[player].Contains(key))
334 mInputs.KeysPressed[player].Add(key);
336 if (!isKeyPressed && !mInputs.KeysReleased[player].Contains(key))
337 mInputs.KeysReleased[player].Add(key);
341 public void ApplyMouseLocationInput(object playerIdentifier, int x, int y)
346 public void ApplyMouseButtonInput(object playerIdentifier, bool isButtonPressed)
351 public bool IsGameOver(object playerIdentifier)
356 public bool IsTerminated(object playerIdentifier)
361 public long Update(TimeSpan elapsedTime)
363 State.AdvanceFrame(mInputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state.
364 mDisplay.Update(elapsedTime, State, mThisPlayerID);
365 State.Entities.ForEach(delegate(IEntity e) { e.Update(elapsedTime); });
366 mInputs = new NextInputs(State.NumberOfPlayers); // Start with inputs cleared on the next frame.
367 //mDisplay.Update(elapsedTime);
368 return State.FrameNumber;
372 public long Draw(SpriteBatch spriteBatch)
374 mDisplay.Draw(spriteBatch);
375 return CurrentFrameNumber;
381 #region Private Variables
385 ContentManager mContentManager;
388 Object[] mPlayerIdentifiers;