Saturday, December 1, 2007

Networking Step 2: Create/Join Session

Now we want to be able to select from the following options:
Under XBox Live:
- Create XBox LIVE Session
- Join Xbox LIVE Session
So lets go ahead and add a new menu screen like we did before for the Multiplayer menu screen.
I'll call this screen XboxLiveScreen.cs very similar setup to before:

#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
#endregion

namespace GameStateManagement
{
class XboxLiveScreen : MenuScreen
{
public XboxLiveScreen()
{
MenuEntries.Add("Create XBox LIVE Session");
MenuEntries.Add("Join XBox LIVE Session");

MenuEntries.Add("Back");
}

/// <summary>
/// Responds to user menu selections.
/// </summary>
protected override void OnSelectEntry(int entryIndex)
{
switch (entryIndex)
{
case 0:
// Create XBox LIVE Session
break;
case 1:
// Join XBox LIVE Session
break;
case 2:
// Go back to Multiplayer Menu
ScreenManager.AddScreen(new LiveOptionsMenuScreen());
break;
}
}

/// <summary>
/// When the user cancels the options screen, go back to the main menu.
/// </summary>
protected override void OnCancel()
{
ExitScreen();
}
}
}

Now go back to the LiveOptionsMenuScreen and add the following to the OnSelectEntry function under case 0 (the part in italic bold is what needs to be added to call the Xbox Live screen):

// If not signed in lets display the Sign-in Guide
if (!isSignedInToLive)
{
if (!Guide.IsVisible)
{
Guide.ShowSignIn(1, true);
}
}
else
{
ScreenManager.AddScreen(new XboxLiveScreen());
}

You should also change case 3 to this:

// Go back to the main menu.
ScreenManager.AddScreen(new MainMenuScreen());
break;

the above change just makes sure that you dont end up going to the previous screen (like Xbox Live Screen) but instead go to the Main Menu.

Now we want to create the network session, whilst its busy trying to create it the session it will freeze the game which isn't a great user experience. Instead lets use IAsyncResult to create it asynchronously, but whilst its creating we dont want the user to be able to move around the menu either, so we will need to introduce a way of disabling the joypad/keyboard from moving threw the menu options whilst the async task is busy.

Lets edit the MenuScreen.cs by adding a new property:

bool
_isEnabled = true;

public bool isEnabled
{
get { return _isEnabled; }
set { _isEnabled = value; }
}

Then in the HandleInput function surround everything with a if (isEnabled) so that the user cannot move around the menu whilst its disabled.

Now lets go back to XBoxLiveScreen class and add the following field:
IAsyncResult LIVEResult = null;
In the OnSelectEntry function under case 0: add the following:

this.isEnabled = false;

LIVEResult = NetworkSession.BeginCreate(NetworkSessionType.PlayerMatch, 2, 8, new AsyncCallback(LoadLobbyScreen), null);
Feel free to change the parameters above (the 2 = local players and 8 = max network players) to whatever you want for your project. You will also want to let the player know that something has happend when the pressed the button to start the LIVE session... so lets change the menu text to the following:
MenuEntries[0] = "Creating Session...";
Next we need to add the Callback function we used above called "LobbyLoadScreen"... add this to you XBoxLiveScreen class:

///
/// Callback to load the lobby screen with the new session.
///
void LoadLobbyScreen(IAsyncResult result)
{
if ((LIVEResult != null) && LIVEResult.IsCompleted)
{
networkSession = null;
isEnabled = true;

try
{
networkSession = NetworkSession.EndCreate(result);
}
catch (NetworkException error)
{
MessageBoxScreen messageBox = new MessageBoxScreen("Failed to create the session");
messageBox.Accepted += FailedMessageBox;
messageBox.Cancelled += FailedMessageBox;
ScreenManager.AddScreen(messageBox);

System.Console.WriteLine("Failed to create the session: " + error.Message);
}

MenuEntries[0] = "Session Created";

// A valid network session has been created
if (networkSession != null)
{
// Set a few properties:
networkSession.AllowHostMigration = true;
networkSession.AllowJoinInProgress = true;
// ** This bit we will add in the next article so lets leave it
// commented out for now so the project will still build **
//LobbyScreen lobbyScreen = new LobbyScreen(networkSession);
//lobbyScreen.ScreenManager = this.ScreenManager;
//ScreenManager.AddScreen(lobbyScreen);
}

// Dont need this anymore so set it to null
LIVEResult = null;
}
}

We will also need to end the above Session if we decide to go back to the Multiplayer Menu... so lets add this in to the OnSelectEntry function inside XBoxLiveScreen class:

case 2:
// Go back to Multiplayer Menu
if (networkSession != null)
{
if (networkSession.AllGamers.Count == 1)
{
if (networkSession.SessionState == NetworkSessionState.Playing)
{
networkSession.EndGame();
}
}

networkSession.Dispose();
networkSession = null;
}



Ok.. so now what?

At this stage in the menu of a game you would be ready to Host a LIVE game.... to do this you would need a Lobby whereby you can customize the session you are hosting, these would generally be Network options like:
  • Max Players
  • Number of reserved entries for friends
Other options would be more game specific like:
  • Level / Map
  • Match type (Capture the Flag, Deathmatch, Team etc..)
And the Lobby is a good place to get all the players ready before sttarting the game.

So next we will create a LobbyScreen.cs file where we will get into more detail on networking.

No comments: