]> Dogcows Code - chaz/carfire/blob - CarFire/CarFire/CarFire/Game.cs
SaberMonster loads from map file and walks around using the path finder, and a lot...
[chaz/carfire] / CarFire / CarFire / CarFire / Game.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using Microsoft.Xna.Framework;
6 using Microsoft.Xna.Framework.Content;
7 using Microsoft.Xna.Framework.Graphics;
8 using Microsoft.Xna.Framework.Input;
9
10 namespace CarFire
11 {
12 /// <summary>
13 /// Container class for the whole state of the game.
14 /// </summary>
15 public class GameState
16 {
17 #region Public Properties
18
19 public long FrameNumber { get { return mFrameNumber; } }
20
21 public long Checksum { get { return mChecksum; } }
22
23 public int NumberOfPlayers { get { return mNumberOfPlayers; } }
24
25 public Map Map;
26 public List<IEntity> Entities = new List<IEntity>();
27
28 #endregion
29
30
31 #region Public Methods
32
33 /// <summary>
34 /// Construct a game state container with the number of players.
35 /// </summary>
36 /// <param name="numPlayers">Number of players.</param>
37 public GameState(int numPlayers)
38 {
39 mNumberOfPlayers = numPlayers;
40 mFrameNumber = 0;
41
42 mIsGameOver = new bool[numPlayers];
43 mIsTerminated = new bool[numPlayers];
44
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>();
49
50 mKeypressCount = new int[numPlayers];
51 mElapsedTime = 0;
52 mChecksum = 0;
53 }
54
55
56 /// <summary>
57 /// Should be called by the Game class to advance the state
58 /// to the next frame.
59 /// </summary>
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)
64 {
65 mFrameNumber++;
66 mElapsedTime += milliseconds;
67
68 for (int player = 0; player < NumberOfPlayers; player++)
69 {
70 if (inputs.IsMousePressedChanged[player])
71 {
72 mMouseButton[player] = inputs.MousePressed[player];
73 }
74
75 if (inputs.IsMouseLocationChanged[player])
76 {
77 mMouseLocation[player] = inputs.MouseLocation[player];
78 }
79
80 foreach (Keys k in inputs.KeysPressed[player])
81 {
82 if (!mKeysDown[player].Contains(k))
83 {
84 mKeysDown[player].Add(k);
85 mKeypressCount[player]++;
86 }
87 }
88
89 foreach (Keys k in inputs.KeysReleased[player]) mKeysDown[player].Remove(k);
90 }
91
92 ComputeChecksum();
93 }
94
95
96 /// <summary>
97 /// Get the mouse location for a player.
98 /// </summary>
99 /// <param name="playerNum">Player Number.</param>
100 /// <returns>Mouse location.</returns>
101 public Point GetMouseLocation(int playerNum)
102 {
103 return mMouseLocation[playerNum];
104 }
105
106 /// <summary>
107 /// Get the mouse button state for a player.
108 /// </summary>
109 /// <param name="playerNum">Player number.</param>
110 /// <returns>Mouse button state..</returns>
111 public bool GetMouseButton(int playerNum)
112 {
113 return mMouseButton[playerNum];
114 }
115
116 /// <summary>
117 /// Get the keyboard state for a player.
118 /// </summary>
119 /// <param name="playerNum">Player number.</param>
120 /// <returns>Keyboard state.</returns>
121 public List<Keys> GetKeysDown(int playerNum)
122 {
123 return mKeysDown[playerNum];
124 }
125
126 #endregion
127
128
129 #region Private Methods
130
131 // Calculates a checksum for debugging network synchronization issues.
132 long ComputeChecksum()
133 {
134 mChecksum += FrameNumber;
135 for (int i = 0; i < NumberOfPlayers; i++)
136 {
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);
144
145 }
146 mChecksum += mElapsedTime;
147
148 return mChecksum;
149 }
150
151 #endregion
152
153
154 #region Private Variables
155
156 int mNumberOfPlayers;
157 public Point[] mMouseLocation;
158 public bool[] mMouseButton;
159 public List<Keys>[] mKeysDown;
160
161 long mFrameNumber;
162
163 bool[] mIsGameOver;
164 bool[] mIsTerminated;
165
166 int[] mKeypressCount;
167 long mElapsedTime;
168 long mChecksum;
169
170 #endregion
171 }
172
173 /// <summary>
174 /// Container class for all the inputs for a single frame.
175 /// </summary>
176 public class NextInputs
177 {
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;
184
185 public NextInputs(int numPlayers)
186 {
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>();
194 }
195 }
196
197
198 /// <summary>
199 /// The big kahuna.
200 /// </summary>
201 public class Game : IDeterministicGame
202 {
203 #region Public Properties
204
205 /// <summary>
206 /// Get the content manager associated with this game.
207 /// </summary>
208 public ContentManager ContentManager { get { return mContentManager; } }
209
210 /// <summary>
211 /// Get the state.
212 /// </summary>
213 public GameState State;
214
215 public bool[,] Grid
216 {
217 get
218 {
219 bool[,] grid = State.Map.Grid;
220 foreach (IEntity entity in State.Entities)
221 {
222 Point coordinates = entity.Coordinates;
223 grid[coordinates.X, coordinates.Y] = true;
224 }
225 return grid;
226 }
227 }
228
229 #endregion
230
231
232 #region Public Methods
233
234 public bool IsCellOpen(Point point)
235 {
236 if (!State.Map.IsCellOpen(point)) return false;
237 foreach (IEntity entity in State.Entities)
238 {
239 if (entity.Coordinates == point) return false;
240 }
241 return true;
242 }
243
244 public Game()
245 {
246 mDisplay = new Display(this);
247 }
248 public void LoadContent(ContentManager contentManager)
249 {
250 mContentManager = contentManager;
251 mDisplay.LoadContent(contentManager);
252 }
253
254 public void UnloadContent()
255 {
256 }
257
258 private int GetPlayerNumber(Object playerIdentifier)
259 {
260 for (int i = 0; i < mPlayerIdentifiers.Length; i++)
261 {
262 if (mPlayerIdentifiers[i] == playerIdentifier) return i;
263 }
264 throw new Exception("Illegal player identifier" + playerIdentifier);
265 }
266
267 public Vector2 PreferredScreenSize
268 {
269 get { return new Vector2(800, 600); }
270 }
271
272 public int MinimumSupportedPlayers
273 {
274 get { return 1; }
275 }
276
277 public int MaximumSupportedPlayers
278 {
279 get { return 4; }
280 }
281
282 public void ResetGame(object[] playerIdentifiers, object thisPlayer)
283 {
284 int numPlayers = playerIdentifiers.Count();
285
286 mPlayerIdentifiers = new object[numPlayers];
287 for (int i = 0; i < numPlayers; i++) mPlayerIdentifiers[i] = playerIdentifiers[i];
288
289 mThisPlayerID = GetPlayerNumber(thisPlayer);
290
291 State = new GameState(numPlayers);
292 mInputs = new NextInputs(numPlayers);
293
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");
298
299 /*
300 mPlayers.Clear();
301 for (int i = 0; i < PlayerIdentifiers.Length; i++)
302 {
303 Human player = new Human(mMap, "");
304 mPlayers.Add(player);
305 mDisplay.AddCharacters(player);
306 mPlayers.Add(player);
307 mDisplay.AddCharacters(player);
308 }
309 this.playerIdentifiers = PlayerIdentifiers;
310 for (int i = 0; i < mPlayers.Count; i++)
311 {
312 Point starting = mMap.GetStartingPositionForPlayer(i + 1);
313 mPlayers[i].Spawn(new Vector2(starting.X, starting.Y));
314 }
315 */
316 }
317
318 public long CurrentFrameNumber
319 {
320 get { return State.FrameNumber; }
321 }
322
323 public long CurrentChecksum
324 {
325 get { return 0; }
326 }
327
328 public void ApplyKeyInput(object playerIdentifier, Keys key, bool isKeyPressed)
329 {
330 //code from Prof Jensen's TestHarness
331 int player = GetPlayerNumber(playerIdentifier);
332
333 if (isKeyPressed && !mInputs.KeysPressed[player].Contains(key))
334 mInputs.KeysPressed[player].Add(key);
335
336 if (!isKeyPressed && !mInputs.KeysReleased[player].Contains(key))
337 mInputs.KeysReleased[player].Add(key);
338
339 }
340
341 public void ApplyMouseLocationInput(object playerIdentifier, int x, int y)
342 {
343
344 }
345
346 public void ApplyMouseButtonInput(object playerIdentifier, bool isButtonPressed)
347 {
348
349 }
350
351 public bool IsGameOver(object playerIdentifier)
352 {
353 return false;
354 }
355
356 public bool IsTerminated(object playerIdentifier)
357 {
358 return false;
359 }
360
361 public long Update(TimeSpan elapsedTime)
362 {
363 State.AdvanceFrame(mInputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state.
364 mDisplay.Update(elapsedTime, State);
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;
369
370 }
371
372 public long Draw(SpriteBatch spriteBatch)
373 {
374 mDisplay.Draw(spriteBatch);
375 return CurrentFrameNumber;
376 }
377
378 #endregion
379
380
381 #region Private Variables
382
383 Display mDisplay;
384
385 ContentManager mContentManager;
386 NextInputs mInputs;
387
388 Object[] mPlayerIdentifiers;
389 int mThisPlayerID;
390
391 #endregion
392 }
393 }
This page took 0.050476 seconds and 4 git commands to generate.