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>();
27 public IPlayer[] mCharacters = new IPlayer[4];
28 public Display mDisplay;
33 #region Public Methods
36 /// Construct a game state container with the number of players.
38 /// <param name="numPlayers">Number of players.</param>
39 public GameState(int numPlayers)
41 mNumberOfPlayers = numPlayers;
44 mIsGameOver = new bool[numPlayers];
45 mIsTerminated = new bool[numPlayers];
47 mMouseLocation = new Point[numPlayers];
48 mMouseButton = new bool[numPlayers];
49 mKeysDown = new List<Keys>[numPlayers];
50 for (int i = 0; i < numPlayers; i++) mKeysDown[i] = new List<Keys>();
52 mKeypressCount = new int[numPlayers];
59 /// Should be called by the Game class to advance the state
60 /// to the next frame.
62 /// <param name="inputs">The inputs that occurred to be
63 /// applied this coming frame.</param>
64 /// <param name="milliseconds">Milliseconds; used for the checksum.</param>
65 public void AdvanceFrame(NextInputs inputs, long milliseconds)
68 mElapsedTime += milliseconds;
70 for (int player = 0; player < NumberOfPlayers; player++)
72 if (inputs.IsMousePressedChanged[player])
74 mMouseButton[player] = inputs.MousePressed[player];
77 if (inputs.IsMouseLocationChanged[player])
79 mMouseLocation[player] = inputs.MouseLocation[player];
82 foreach (Keys k in inputs.KeysPressed[player])
84 if (!mKeysDown[player].Contains(k))
86 mKeysDown[player].Add(k);
87 mKeypressCount[player]++;
91 foreach (Keys k in inputs.KeysReleased[player]) mKeysDown[player].Remove(k);
99 /// Get the mouse location for a player.
101 /// <param name="playerNum">Player Number.</param>
102 /// <returns>Mouse location.</returns>
103 public Point GetMouseLocation(int playerNum)
105 return mMouseLocation[playerNum];
109 /// Get the mouse button state for a player.
111 /// <param name="playerNum">Player number.</param>
112 /// <returns>Mouse button state..</returns>
113 public bool GetMouseButton(int playerNum)
115 return mMouseButton[playerNum];
119 /// Get the keyboard state for a player.
121 /// <param name="playerNum">Player number.</param>
122 /// <returns>Keyboard state.</returns>
123 public List<Keys> GetKeysDown(int playerNum)
125 return mKeysDown[playerNum];
131 #region Private Methods
133 // Calculates a checksum for debugging network synchronization issues.
134 long ComputeChecksum()
136 mChecksum += FrameNumber;
137 for (int i = 0; i < NumberOfPlayers; i++)
139 mChecksum = mChecksum + mKeypressCount[i];
140 mChecksum = mChecksum * 3 + (mIsGameOver[i] ? 1 : 2);
141 mChecksum = mChecksum * 3 + (mIsTerminated[i] ? 1 : 2);
142 foreach (Keys k in mKeysDown[i])
143 mChecksum = mChecksum * 257 + (int)k;
144 mChecksum = mChecksum * 25789 + mMouseLocation[i].X * 259 + mMouseLocation[i].Y + 375;
145 mChecksum = mChecksum * 3 + (mMouseButton[i] ? 1 : 2);
148 mChecksum += mElapsedTime;
156 #region Private Variables
158 int mNumberOfPlayers;
159 public Point[] mMouseLocation;
160 public bool[] mMouseButton;
161 public List<Keys>[] mKeysDown;
166 bool[] mIsTerminated;
168 int[] mKeypressCount;
176 /// Container class for all the inputs for a single frame.
178 public class NextInputs
180 public List<Keys>[] KeysPressed;
181 public List<Keys>[] KeysReleased;
182 public Point[] MouseLocation;
183 public bool[] IsMouseLocationChanged;
184 public bool[] MousePressed;
185 public bool[] IsMousePressedChanged;
187 public NextInputs(int numPlayers)
189 KeysPressed = new List<Keys>[numPlayers];
190 KeysReleased = new List<Keys>[numPlayers];
191 IsMouseLocationChanged = new bool[numPlayers];
192 MousePressed = new bool[numPlayers];
193 IsMousePressedChanged = new bool[numPlayers];
194 for (int i = 0; i < numPlayers; i++) KeysPressed[i] = new List<Keys>();
195 for (int i = 0; i < numPlayers; i++) KeysReleased[i] = new List<Keys>();
203 public class Game : IDeterministicGame
205 #region Public Properties
208 /// Get the content manager associated with this game.
210 public ContentManager ContentManager { get { return mContentManager; } }
215 public GameState State;
221 bool[,] grid = State.Map.Grid;
222 foreach (IEntity entity in State.Entities)
224 Point coordinates = entity.Coordinates;
225 grid[coordinates.X, coordinates.Y] = true;
234 #region Public Methods
236 public bool IsCellOpen(Point point)
238 if (!State.Map.IsCellOpen(point)) return false;
239 foreach (IEntity entity in State.Entities)
241 if (entity.Coordinates == point) return false;
250 public void LoadContent(ContentManager contentManager)
252 mContentManager = contentManager;
256 public void UnloadContent()
260 private int GetPlayerNumber(Object playerIdentifier)
262 for (int i = 0; i < mPlayerIdentifiers.Length; i++)
264 if (mPlayerIdentifiers[i] == playerIdentifier) return i;
266 throw new Exception("Illegal player identifier" + playerIdentifier);
269 public Vector2 PreferredScreenSize
271 get { return new Vector2(800, 600); }
274 public int MinimumSupportedPlayers
279 public int MaximumSupportedPlayers
284 public void ResetGame(object[] playerIdentifiers, object thisPlayer)
286 int numPlayers = playerIdentifiers.Count();
288 mPlayerIdentifiers = new object[numPlayers];
289 for (int i = 0; i < numPlayers; i++) mPlayerIdentifiers[i] = playerIdentifiers[i];
291 mThisPlayerID = GetPlayerNumber(thisPlayer);
293 State = new GameState(numPlayers);
294 mInputs = new NextInputs(numPlayers);
295 State.mDisplay = new Display(this);
296 State.mDisplay.LoadContent(mContentManager);
298 State.Map = mContentManager.Load<Map>("Maps/stable");
299 State.Map.Game = this;
300 State.Entities = State.Map.GetAllEntities();
301 Map.DefaultTile = mContentManager.Load<Texture2D>("default");
305 for (int i = 0; i < PlayerIdentifiers.Length; i++)
307 Human player = new Human(mMap, "");
308 mPlayers.Add(player);
309 mDisplay.AddCharacters(player);
310 mPlayers.Add(player);
311 mDisplay.AddCharacters(player);
313 this.playerIdentifiers = PlayerIdentifiers;
314 for (int i = 0; i < mPlayers.Count; i++)
316 Point starting = mMap.GetStartingPositionForPlayer(i + 1);
317 mPlayers[i].Spawn(new Vector2(starting.X, starting.Y));
322 public long CurrentFrameNumber
324 get { return State.FrameNumber; }
327 public long CurrentChecksum
332 public void ApplyKeyInput(object playerIdentifier, Keys key, bool isKeyPressed)
334 //code from Prof Jensen's TestHarness
335 int player = GetPlayerNumber(playerIdentifier);
337 if (isKeyPressed && !mInputs.KeysPressed[player].Contains(key))
338 mInputs.KeysPressed[player].Add(key);
340 if (!isKeyPressed && !mInputs.KeysReleased[player].Contains(key))
341 mInputs.KeysReleased[player].Add(key);
345 public void ApplyMouseLocationInput(object playerIdentifier, int x, int y)
350 public void ApplyMouseButtonInput(object playerIdentifier, bool isButtonPressed)
355 public bool IsGameOver(object playerIdentifier)
360 public bool IsTerminated(object playerIdentifier)
365 public long Update(TimeSpan elapsedTime)
367 State.AdvanceFrame(mInputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state.
368 State.mDisplay.Update(elapsedTime, State, mThisPlayerID);
369 State.Entities.ForEach(delegate(IEntity e) { e.Update(elapsedTime); });
370 mInputs = new NextInputs(State.NumberOfPlayers); // Start with inputs cleared on the next frame.
371 //mDisplay.Update(elapsedTime);
372 return State.FrameNumber;
376 public long Draw(SpriteBatch spriteBatch)
378 bool allCharactersSelected = true;
379 for (int i = 0; i < State.NumberOfPlayers; i++)
381 //If player has not selected a player yet let them select one.
382 if (State.mCharacters[i] == null)
384 allCharactersSelected = false;
385 if (State.GetKeysDown(i).Contains(Keys.Enter))
387 State.mCharacters[i] = new Human(this, "", State.Map.GetStartingPositionForPlayer(i + 1));
388 State.mCharacters[i].LoadContent(mContentManager);
392 if (allCharactersSelected)
394 State.mDisplay.Draw(spriteBatch);
396 return CurrentFrameNumber;
402 #region Private Variables
406 ContentManager mContentManager;
409 Object[] mPlayerIdentifiers;