Sunday, December 2, 2007

Networking Step 3: The Lobby Phase 1.

Ok, this is going to be where the majority of the networking features happen, so im going to try break it up into different phases and I'll try make it that at the end of each phase you will still be able to build your project without issues and have something to try out.

Lets create a new class under the Screens subfolder called "LobbyScreen.cs", this time we will pass into the constructor the networkSession from the XBoxLiveScreen where we initially created it. We will also create some network events that we will make use of later.

We also want to add a bit more functionality into the Lobby so we are going to overrider the Update function. Here we will check to see what state the Lobby is currently in i.e. what to do under the different situations which would probably be:
Host
  • Waiting for all players to click ready
  • Ready to start game
Joined Player
  • Click Ready
  • Waiting for host to start game
Here is what I have so far:

#region using
using Microsoft.Xna.Framework.Net;
using System;
#endregion

namespace GameStateManagement
{
class LobbyScreen : MenuScreen
{
NetworkSession networkSession;

/// <summary>
/// Constructs a new LobbyScreen object.
/// </summary>
public LobbyScreen(NetworkSession networkSession)
: base()
{
this.networkSession = networkSession;

// add the single menu entry
MenuEntries.Add("Play Game");
MenuEntries.Add("Close Lobby");

// set the transition time
TransitionOnTime = TimeSpan.FromSeconds(1.0);
TransitionOffTime = TimeSpan.FromSeconds(0.0);

// set the networking events
networkSession.GamerJoined += new EventHandler<GamerJoinedEventArgs>(networkSession_GamerJoined);
networkSession.GamerLeft += new EventHandler<GamerLeftEventArgs>(networkSession_GamerLeft);
networkSession.GameStarted += new EventHandler<GameStartedEventArgs>(networkSession_GameStarted);
networkSession.SessionEnded += new EventHandler<NetworkSessionEndedEventArgs>(networkSession_SessionEnded);
}

/// <summary>
/// Responds to user menu selections.
/// </summary>
protected override void OnSelectEntry(int entryIndex)
{
switch (entryIndex)
{
case 0:

// Play the game (only if everyone is ready)
if ((networkSession != null) && networkSession.IsHost && networkSession.IsEveryoneReady
&& networkSession.SessionState == NetworkSessionState.Lobby)
{
networkSession.StartGame();
}
break;

case 1:
// Exit
if (networkSession != null)
{
networkSession.Dispose();
networkSession = null;
}

ScreenManager.AddScreen(new XboxLiveScreen());
break;
}
}

/// <summary>
/// Updates the lobby. This method checks the GameScreen.IsActive
/// property, so the game will stop updating when the pause menu is active,
/// or if you tab away to a different application.
/// </summary>
public override void Update(Microsoft.Xna.Framework.GameTime gameTime, bool otherScreenHasFocus,
bool coveredByOtherScreen)
{
if (networkSession != null)
{
// update the network session
networkSession.Update();
}

// update the menu entry text
if (otherScreenHasFocus == false)
{
if (networkSession.LocalGamers.Count > 0 && networkSession.SessionState == NetworkSessionState.Lobby)
{
if (networkSession.LocalGamers.Count > 0 && networkSession.SessionState == NetworkSessionState.Lobby)
{
if (!networkSession.LocalGamers[0].IsReady)
{
if (!networkSession.IsHost)
{
MenuEntries[0] = "Press X to Mark as Ready";
}
else
{
// You are the host so no need for you to manually tick ready... as you will start the game
networkSession.LocalGamers[0].IsReady = true;
}
}
else if (!networkSession.IsEveryoneReady)
{
MenuEntries[0] = "Waiting for all players to mark as ready...";
}
else if (!networkSession.IsHost)
{
MenuEntries[0] = "Waiting for host to start the game...";
}
else
{
MenuEntries[0] = "Press A to Start Game";
}
}
else if (networkSession.SessionState == NetworkSessionState.Playing)
{
MenuEntries[0] = "Game starting...";
}
}

// if the game is playing then start up
if (networkSession.SessionState == NetworkSessionState.Playing)
{
MenuEntries[0] = "Game is now in progress..";
// This is where we will lod the Gameplay Screen once we get around to it
}
}

base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
}

/// <summary>
/// When the user cancels the main menu
/// </summary>
protected override void OnCancel()
{
}

/// <summary>
/// Handle the start of the game session.
/// </summary>
void networkSession_GameStarted(object sender, GameStartedEventArgs e)
{
}

/// <summary>
/// Handle a new player joining the session.
/// </summary>
void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e)
{
}

/// <summary>
/// Handle a player leaving the session.
/// </summary>
void networkSession_GamerLeft(object sender, GamerLeftEventArgs e)
{
}

/// <summary>
/// Handle the end of the network session.
/// </summary>
void networkSession_SessionEnded(object sender, NetworkSessionEndedEventArgs e)
{
}
}
}

In Phase 2 we will start looking at displaying the list of connected players and their ready status.

No comments: