/// <summary> /// Internal method for leaving the network session. This disposes the /// session, removes the NetworkSessionComponent, and returns the user /// to the main menu screen. /// </summary> void LeaveSession() { // Destroy this NetworkSessionComponent. Dispose(); // If we have a sessionEndMessage string explaining why the session has // ended (maybe this was a network disconnect, or perhaps the host kicked // us out?) create a message box to display this reason to the user. MessageBoxScreen messageBox; if (!string.IsNullOrEmpty(sessionEndMessage)) { messageBox = new MessageBoxScreen(sessionEndMessage, false); } else { messageBox = null; } // At this point we want to return the user all the way to the main // menu screen. But what if they just joined a session? In that case // they went through this flow of screens: // // - MainMenuScreen // - CreateOrFindSessionsScreen // - JoinSessionScreen (if joining, skipped if creating a new session) // - LobbyScreeen // // If we have these previous screens on the history stack, and the user // backs out of the LobbyScreen, the right thing is just to pop off the // intermediate screens, returning them to the existing MainMenuScreen // instance without bothering to reload everything. But if the user is // in gameplay, or has been in gameplay and then returned to the lobby, // the screen stack will have been emptied. // // To do the right thing in both cases, we scan through the screen history // stack looking for a MainMenuScreen. If we find one, we pop any // subsequent screens so as to return back to it, while if we don't // find it, we just reset everything via the LoadingScreen. GameScreen[] screens = screenManager.GetScreens(); // Look for the MainMenuScreen. for (int i = 0; i < screens.Length; i++) { if (screens[i] is MainMenuScreen) { // If we found one, pop everything since then to return back to it. for (int j = i + 1; j < screens.Length; j++) { screens[j].ExitScreen(); } // Display the why-did-the-session-end message box. if (messageBox != null) { screenManager.AddScreen(messageBox, null); } return; } } // If we didn't find an existing MainMenuScreen, reload everything. // The why-did-the-session-end message box will be displayed after // the loading screen has completed. LoadingScreen.Load(screenManager, false, null, new TitleBackgroundScreen(), new MainMenuScreen(), messageBox); }
/// <summary> /// Event handler for when the Single Player menu entry is selected. /// </summary> void SinglePlayerMenuEntrySelected(object sender, PlayerIndexEventArgs e) { LoadingScreen.Load(ScreenManager, true, e.PlayerIndex, new GameplayScreen(null)); }
/// <summary> /// Updates the state of the game. /// </summary> public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { base.Update(gameTime, otherScreenHasFocus, false); // Gradually fade in or out depending on whether we are covered by the pause screen. if (coveredByOtherScreen) { pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1); } else { pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0); } if (IsActive) { starField.Update(gameTime); if (networkSession != null) { // Process Incoming Packets ReceiveNetworkData(); if (networkSession.IsHost) { LocalNetworkGamer gamer = networkSession.Host as LocalNetworkGamer; if (updatesSinceGameDataSend >= updatesBetweenGameDataPackets) { updatesSinceGameDataSend = 0; SendGameData(); } else { updatesSinceGameDataSend++; } } // Update players foreach (NetworkGamer gamer in networkSession.AllGamers) { Player p = gamer.Tag as Player; if (p != null) { p.Update(gameTime); if (gamer.IsLocal && p.wasKilled) { // Reset the death flag p.wasKilled = false; SendLocalShipDeath(); } } } // Send Player Data if (updatesSincePlayerDataSend >= updatesBetweenPlayerDataPackets) { updatesSincePlayerDataSend = 0; SendLocalPlayerData(); } else { updatesSincePlayerDataSend++; } // Send Ship Data if (updatesSinceStatusPacket >= updatesBetweenStatusPackets) { updatesSinceStatusPacket = 0; SendLocalShipData(); } else { updatesSinceStatusPacket++; } } else { players[(int)ControllingPlayer].Update(gameTime); } // Update Asteroids asteroidManager.Update(gameTime); // See if we need to increment the level if (asteroidManager.Asteroids.Count == 0) { asteroidManager.StartLevel(level++); // Enable Spawn Protection if (networkSession == null) { players[0].EnableSpawnProtection(); } else { foreach (NetworkGamer gamer in networkSession.AllGamers) { Player p = gamer.Tag as Player; if (p != null) { p.EnableSpawnProtection(); } } } } // Handle collision detection if (networkSession == null) { CheckCollisions(); } else { CheckMultiplayerCollisions(); } } // Check for gameOver state if (networkSession != null) { bool shouldReturnToLobby = true; foreach (NetworkGamer gamer in networkSession.AllGamers) { Player p = gamer.Tag as Player; if (p.IsGameOver == false) { shouldReturnToLobby = false; } } // If all players are in the gameOver state then return to the lobby if (networkSession.IsHost && shouldReturnToLobby) { if (networkSession.SessionState == NetworkSessionState.Playing) { networkSession.EndGame(); } } } // If we are in a network game, check if we should return to the lobby. if ((networkSession != null) && !IsExiting) { if (networkSession.SessionState == NetworkSessionState.Lobby) { LoadingScreen.Load(ScreenManager, false, null, new TitleBackgroundScreen(), new LobbyScreen(networkSession)); } } }