]> Dogcows Code - chaz/carfire/blob - CarFire/CarFire/CarFire/Game.cs
Can now choose between melee and ranged character... melee attack not
[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 public Player[] mCharacters = new Player[4];
28 public Display mDisplay;
29
30 #endregion
31
32
33 #region Public Methods
34
35 /// <summary>
36 /// Construct a game state container with the number of players.
37 /// </summary>
38 /// <param name="numPlayers">Number of players.</param>
39 public GameState(int numPlayers)
40 {
41 mNumberOfPlayers = numPlayers;
42 mFrameNumber = 0;
43
44 mIsGameOver = new bool[numPlayers];
45 mIsTerminated = new bool[numPlayers];
46
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>();
51
52 mKeypressCount = new int[numPlayers];
53 mElapsedTime = 0;
54 mChecksum = 0;
55 }
56
57
58 /// <summary>
59 /// Should be called by the Game class to advance the state
60 /// to the next frame.
61 /// </summary>
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)
66 {
67 mFrameNumber++;
68 mElapsedTime += milliseconds;
69
70 for (int player = 0; player < NumberOfPlayers; player++)
71 {
72 if (inputs.IsMousePressedChanged[player])
73 {
74 mMouseButton[player] = inputs.MousePressed[player];
75 }
76
77 if (inputs.IsMouseLocationChanged[player])
78 {
79 mMouseLocation[player] = inputs.MouseLocation[player];
80 }
81
82 foreach (Keys k in inputs.KeysPressed[player])
83 {
84 if (!mKeysDown[player].Contains(k))
85 {
86 mKeysDown[player].Add(k);
87 mKeypressCount[player]++;
88 }
89 }
90
91 foreach (Keys k in inputs.KeysReleased[player]) mKeysDown[player].Remove(k);
92 }
93
94 ComputeChecksum();
95 }
96
97
98 /// <summary>
99 /// Get the mouse location for a player.
100 /// </summary>
101 /// <param name="playerNum">Player Number.</param>
102 /// <returns>Mouse location.</returns>
103 public Point GetMouseLocation(int playerNum)
104 {
105 return mMouseLocation[playerNum];
106 }
107
108 /// <summary>
109 /// Get the mouse button state for a player.
110 /// </summary>
111 /// <param name="playerNum">Player number.</param>
112 /// <returns>Mouse button state..</returns>
113 public bool GetMouseButton(int playerNum)
114 {
115 return mMouseButton[playerNum];
116 }
117
118 /// <summary>
119 /// Get the keyboard state for a player.
120 /// </summary>
121 /// <param name="playerNum">Player number.</param>
122 /// <returns>Keyboard state.</returns>
123 public List<Keys> GetKeysDown(int playerNum)
124 {
125 return mKeysDown[playerNum];
126 }
127
128 #endregion
129
130
131 #region Private Methods
132
133 // Calculates a checksum for debugging network synchronization issues.
134 long ComputeChecksum()
135 {
136 mChecksum += FrameNumber;
137 for (int i = 0; i < NumberOfPlayers; i++)
138 {
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);
146
147 }
148 mChecksum += mElapsedTime;
149
150 return mChecksum;
151 }
152
153 #endregion
154
155
156 #region Private Variables
157
158 int mNumberOfPlayers;
159 public Point[] mMouseLocation;
160 public bool[] mMouseButton;
161 public List<Keys>[] mKeysDown;
162
163 long mFrameNumber;
164
165 bool[] mIsGameOver;
166 bool[] mIsTerminated;
167
168 int[] mKeypressCount;
169 long mElapsedTime;
170 long mChecksum;
171
172 #endregion
173 }
174
175 /// <summary>
176 /// Container class for all the inputs for a single frame.
177 /// </summary>
178 public class NextInputs
179 {
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;
186
187 public NextInputs(int numPlayers)
188 {
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>();
196 }
197 }
198
199
200 /// <summary>
201 /// The big kahuna.
202 /// </summary>
203 public class Game : IDeterministicGame
204 {
205 #region Public Properties
206
207 /// <summary>
208 /// Get the content manager associated with this game.
209 /// </summary>
210 public ContentManager ContentManager { get { return mContentManager; } }
211
212 /// <summary>
213 /// Get the state.
214 /// </summary>
215 public GameState State;
216
217 public bool[,] Grid
218 {
219 get
220 {
221 bool[,] grid = State.Map.Grid;
222 foreach (IEntity entity in State.Entities)
223 {
224 Point coordinates = entity.Coordinates;
225 grid[coordinates.X, coordinates.Y] = true;
226 }
227 return grid;
228 }
229 }
230
231 #endregion
232
233
234 #region Public Methods
235 public bool IsCellOpen(Point point)
236 {
237 if (!State.Map.IsCellOpen(point)) return false;
238 foreach (IEntity entity in State.Entities)
239 {
240 if (entity.Coordinates == point) return false;
241 }
242 return true;
243 }
244
245 public Game()
246 {
247
248 }
249 /// <summary>
250 /// This method should be called whenever the players want to move to a new map.
251 /// Not implemented yet. Need some way to get next map.
252 /// </summary>
253 public void startNewMap()
254 {
255 //TODO somehow get next map
256 State.Entities.Clear();
257 //State.Map = State.Map.getNextMap();
258 for (int i = 0; i < State.mCharacters.Length; i++)
259 {
260 State.mCharacters[i].Coordinates = State.Map.GetStartingPositionForPlayer(i + 1);
261 }
262 State.Entities = State.Map.GetAllEntities();
263 }
264 public void LoadContent(ContentManager contentManager)
265 {
266 mContentManager = contentManager;
267 menu = mContentManager.Load<SpriteFont>("menuFont");
268
269 }
270
271 public void UnloadContent()
272 {
273 }
274
275 private int GetPlayerNumber(Object playerIdentifier)
276 {
277 for (int i = 0; i < mPlayerIdentifiers.Length; i++)
278 {
279 if (mPlayerIdentifiers[i] == playerIdentifier) return i;
280 }
281 throw new Exception("Illegal player identifier" + playerIdentifier);
282 }
283
284 public Vector2 PreferredScreenSize
285 {
286 get { return new Vector2(800, 600); }
287 }
288
289 public int MinimumSupportedPlayers
290 {
291 get { return 1; }
292 }
293
294 public int MaximumSupportedPlayers
295 {
296 get { return 4; }
297 }
298
299 public void ResetGame(object[] playerIdentifiers, object thisPlayer)
300 {
301 int numPlayers = playerIdentifiers.Count();
302
303 mPlayerIdentifiers = new object[numPlayers];
304 for (int i = 0; i < numPlayers; i++) mPlayerIdentifiers[i] = playerIdentifiers[i];
305
306 mThisPlayerID = GetPlayerNumber(thisPlayer);
307
308 State = new GameState(numPlayers);
309 mInputs = new NextInputs(numPlayers);
310 State.mDisplay = new Display(this);
311 State.mDisplay.LoadContent(mContentManager);
312
313 State.Map = mContentManager.Load<Map>("Maps/stable");
314 State.Map.Game = this;
315 State.Entities = State.Map.GetAllEntities();
316 Map.DefaultTile = mContentManager.Load<Texture2D>("default");
317
318 /*
319 mPlayers.Clear();
320 for (int i = 0; i < PlayerIdentifiers.Length; i++)
321 {
322 Human player = new Human(mMap, "");
323 mPlayers.Add(player);
324 mDisplay.AddCharacters(player);
325 mPlayers.Add(player);
326 mDisplay.AddCharacters(player);
327 }
328 this.playerIdentifiers = PlayerIdentifiers;
329 for (int i = 0; i < mPlayers.Count; i++)
330 {
331 Point starting = mMap.GetStartingPositionForPlayer(i + 1);
332 mPlayers[i].Spawn(new Vector2(starting.X, starting.Y));
333 }
334 */
335 }
336
337 public long CurrentFrameNumber
338 {
339 get { return State.FrameNumber; }
340 }
341
342 public long CurrentChecksum
343 {
344 get { return 0; }
345 }
346
347 public void ApplyKeyInput(object playerIdentifier, Keys key, bool isKeyPressed)
348 {
349 //code from Prof Jensen's TestHarness
350 int player = GetPlayerNumber(playerIdentifier);
351
352 if (isKeyPressed && !mInputs.KeysPressed[player].Contains(key))
353 mInputs.KeysPressed[player].Add(key);
354
355 if (!isKeyPressed && !mInputs.KeysReleased[player].Contains(key))
356 mInputs.KeysReleased[player].Add(key);
357
358 }
359
360 public void ApplyMouseLocationInput(object playerIdentifier, int x, int y)
361 {
362
363 }
364
365 public void ApplyMouseButtonInput(object playerIdentifier, bool isButtonPressed)
366 {
367
368 }
369
370 public bool IsGameOver(object playerIdentifier)
371 {
372 return false;
373 }
374
375 public bool IsTerminated(object playerIdentifier)
376 {
377 return false;
378 }
379
380 public long Update(TimeSpan elapsedTime)
381 {
382 State.AdvanceFrame(mInputs, elapsedTime.Milliseconds); // Apply the inputs, advance game state.
383 State.mDisplay.Update(elapsedTime, State, mThisPlayerID);
384 State.Entities.ForEach(delegate(IEntity e) { e.Update(elapsedTime); });
385 mInputs = new NextInputs(State.NumberOfPlayers); // Start with inputs cleared on the next frame.
386 //mDisplay.Update(elapsedTime);
387 return State.FrameNumber;
388
389 }
390
391 public long Draw(SpriteBatch spriteBatch)
392 {
393 bool allCharactersSelected = true;
394 for (int i = 0; i < State.NumberOfPlayers; i++)
395 {
396 //If player has not selected a player yet let them select one.
397 if (State.mCharacters[i] == null)
398 {
399 allCharactersSelected = false;
400 if (State.GetKeysDown(i).Contains(Keys.M))
401 {
402 State.mCharacters[i] = new Melee(this, "", State.Map.GetStartingPositionForPlayer(i + 1), i);
403 State.mCharacters[i].LoadContent(mContentManager);
404 }
405 else if (State.GetKeysDown(i).Contains(Keys.R))
406 {
407 State.mCharacters[i] = new Ranged(this, "", State.Map.GetStartingPositionForPlayer(i + 1), i);
408 State.mCharacters[i].LoadContent(mContentManager);
409 }
410 }
411 }
412 if (allCharactersSelected)
413 {
414
415 State.mDisplay.Draw(spriteBatch);
416 }
417 else
418 {
419 spriteBatch.GraphicsDevice.Clear(Color.Black);
420 spriteBatch.DrawString(menu, "Press R to select a Ranged Character and M to select a Melee Character", new Vector2(30, 30), Color.RosyBrown);
421 }
422 return CurrentFrameNumber;
423 }
424
425 #endregion
426
427
428 #region Private Variables
429
430 SpriteFont menu;
431
432 ContentManager mContentManager;
433 NextInputs mInputs;
434
435 Object[] mPlayerIdentifiers;
436 int mThisPlayerID;
437
438 #endregion
439 }
440 }
This page took 0.054549 seconds and 5 git commands to generate.