2 using System.Collections.Generic;
5 using Microsoft.Xna.Framework.Net;
6 using System.Diagnostics;
7 using Microsoft.Xna.Framework.GamerServices;
8 using Microsoft.Xna.Framework.Graphics;
9 using Microsoft.Xna.Framework;
10 using Microsoft.Xna.Framework.Input;
12 namespace CS_3505_Project_06
14 public class NetworkGame
16 NetworkSession mNetworkSession;
19 IDeterministicGame mGame;
21 TimeSpan mTargetTimeSpan = new TimeSpan(166666);
22 public TimeSpan TargetTimeSpan
26 return mTargetTimeSpan;
30 List<Keys> lastPressedKeys;
31 bool lastButtonPressed;
33 Object[] playerIdentifiers = { "One", "Two", "Three", "Four" }; // Any objects will do, strings are easy to debug.
41 public SpriteFont font;
44 public NetworkGame(ILobby lobby, IDeterministicGame game)
46 Debug.Assert(lobby != null && game != null);
51 // Begin: Test harness stuff
52 lastPressedKeys = new List<Keys>();
53 activePlayer = playerIdentifiers[0];
56 // Reset the game - indicate that player #1 (player 0) owns this instance of the game.
58 mGame.ResetGame(playerIdentifiers, playerIdentifiers[0]);
62 public LocalNetworkGamer LocalGamer
66 return mNetworkSession.LocalGamers[0];
70 // I added this as I needed a way to display all gamers not just the first gamer
72 public GamerCollection<NetworkGamer> NetworkGamers
76 return mNetworkSession.AllGamers;
81 public NetworkSession CreateSession()
83 return CreateSession(mGame.MaximumSupportedPlayers);
86 public NetworkSession CreateSession(int maxGamers)
88 Debug.Assert(mNetworkSession == null);
90 mNetworkSession = NetworkSession.Create(NetworkSessionType.SystemLink, 1, maxGamers);
91 mNetworkSession.AllowHostMigration = true;
92 mNetworkSession.AllowJoinInProgress = false;
94 return mNetworkSession;
97 // added so I can test if sessionExists and thus be able to call things on NetworkGame safely
99 public bool sessionExists()
101 return mNetworkSession != null;
104 public AvailableNetworkSessionCollection FindSessions()
106 return NetworkSession.Find(NetworkSessionType.SystemLink, 1, new NetworkSessionProperties());
109 public NetworkSession JoinSession(AvailableNetworkSession availableSession)
111 Debug.Assert(mNetworkSession == null);
113 mNetworkSession = NetworkSession.Join(availableSession);
115 return mNetworkSession;
118 // added to begin the game. I made the LobbyGUI make sure that only the host will call it when everyone is ready.
119 // This is already taken care of in the update method below. But it may be nice to allow the host to signal the start
120 // rather then having it start automatically. Just a suggestion.
122 public void StartGame()
124 mNetworkSession.StartGame();
127 public void LeaveSession()
129 Debug.Assert(mNetworkSession != null);
131 mNetworkSession.Dispose();
132 mNetworkSession = null;
136 public void SimulateBadNetwork()
138 Debug.Assert(mNetworkSession != null);
140 mNetworkSession.SimulatedLatency = new TimeSpan(0, 0, 0, 0, 200);
141 mNetworkSession.SimulatedPacketLoss = 0.1f;
145 public void Update(GameTime gameTime)
147 if (mNetworkSession == null)
149 mLobby.Update(gameTime, this);
153 mNetworkSession.Update();
155 if (mNetworkSession.SessionState == NetworkSessionState.Lobby)
157 if (mNetworkSession.IsHost &&
158 mNetworkSession.AllGamers.Count >= mGame.MinimumSupportedPlayers &&
159 mNetworkSession.IsEveryoneReady)
161 mNetworkSession.StartGame();
162 mNetworkSession.ResetReady();
166 mLobby.Update(gameTime, this);
169 else if (mNetworkSession.SessionState == NetworkSessionState.Playing)
171 // TODO: in-game update stuff
172 UpdateTestHarness(gameTime);
174 mGame.Update(mTargetTimeSpan);
179 public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
181 mLobby.Draw(spriteBatch);
182 DrawTestHarness(gameTime, spriteBatch);
188 void UpdateTestHarness(GameTime gameTime)
190 // Get user's input state.
192 KeyboardState keyState = Keyboard.GetState();
193 MouseState mouseState = Mouse.GetState();
195 // Make a list of the keys pressed or released this frame.
197 List<Keys> pressedKeys = new List<Keys>();
198 List<Keys> releasedKeys = new List<Keys>();
200 Keys[] pressedKeysArray = keyState.GetPressedKeys();
201 foreach (Keys k in pressedKeysArray)
202 if (!lastPressedKeys.Contains(k))
205 lastPressedKeys.Remove(k);
207 releasedKeys = lastPressedKeys;
208 lastPressedKeys = new List<Keys>(pressedKeysArray);
210 // Get mouse button state.
212 bool buttonPressed = mouseState.LeftButton == ButtonState.Pressed;
214 /***** Begining of game logic. *****/
216 // Debug - allow user on this machine to direct input to any player's state in the game.
218 if (pressedKeys.Contains(Keys.F1)) activePlayer = playerIdentifiers[0];
219 if (pressedKeys.Contains(Keys.F2)) activePlayer = playerIdentifiers[1];
220 if (pressedKeys.Contains(Keys.F3)) activePlayer = playerIdentifiers[2];
221 if (pressedKeys.Contains(Keys.F4)) activePlayer = playerIdentifiers[3];
223 // Debug - allow user on this machine to pause/resume game state advances.
225 if (pressedKeys.Contains(Keys.F12) ||
226 pressedKeys.Contains(Keys.P) && (keyState.IsKeyDown(Keys.LeftControl) || keyState.IsKeyDown(Keys.RightControl)))
229 return; // Don't update on pause start or stop
232 // Debug - automatically pause every 1000 frames.
234 if (mGame.CurrentFrameNumber % 1000 == 0 && mGame.CurrentFrameNumber != lastAutoPause)
237 lastAutoPause = mGame.CurrentFrameNumber;
241 //if (pressedKeys.Contains(Keys.Escape))
246 // Direct inputs to the game engine - only report changes.
248 foreach (Keys k in pressedKeys)
249 mGame.ApplyKeyInput(activePlayer, k, true);
251 foreach (Keys k in releasedKeys)
252 mGame.ApplyKeyInput(activePlayer, k, false);
254 mGame.ApplyMouseLocationInput(activePlayer, mouseState.X, mouseState.Y);
256 if (lastButtonPressed != buttonPressed)
257 mGame.ApplyMouseButtonInput(activePlayer, buttonPressed);
259 lastButtonPressed = buttonPressed;
263 // Advance the game engine.
265 mGame.Update(mTargetTimeSpan);
269 void DrawTestHarness(GameTime gameTime, SpriteBatch spriteBatch)
272 // BEGIN: Test harness stuff.
273 if (paused && gameTime.TotalRealTime.Milliseconds < 500)
274 spriteBatch.DrawString(font, "-=> Paused <=-", new Vector2(10, 130), Color.White);
276 spriteBatch.DrawString(font, "Press [F1]...[F4] to simulate input for each player. Click X's to end game or terminate player.", new Vector2(10, 540), Color.White);
277 spriteBatch.DrawString(font, "Press [ESC] to exit and [F12] to pause/unpause. Game auto-pauses every 1000 frames.", new Vector2(10, 570), Color.White);
278 //END: Test harness stuff.