Problem
You want to create a session so that other Xbox 360 platforms or PCs can find and join your session.
Solution
A machine first needs to start a Network Session, which can be easily done by using the networksession. Create method. The machine that creates the session is the Session host.
After a session is created, all machines connected to the session, including the host, will listen to any events generated by the session, such as players joining or leaving the session.
Working Principle
You need to include the Microsoft. xNa. Framework. Net namespace.CodeAdd the using code on the top to do the following:
Using Microsoft. xNa. Framework. net
In this tutorial,ProgramIt loops in three custom states. As described in the previous tutorial, you are in the signin status at the beginning and ask the player to select an account. In the previous tutorial, The signedin status is replaced by the createsession status. In the createsession status, you will create a new network session and listen to its events. It ends in insession status.
First, define these statuses:
Public Enum gamestate... {signin, createsession, insession}
The previous tutorial on signin status has been discussed. Let's start coding the createsession status code.
Create a Network Session
In this status, you will create a new network session. First, add the variable to the Code:
Networksession;
You can create a new network session and store it in the variables just defined using the networksession. Create method:
Networksession = networksession. Create (networksessiontype. systemlink, 4, 16 );
This line of code allows the machine to create a new session that other players can connect. As you can see, this method requires three parameters.
The first parameter specifies the session type. If all gamers connect to the same machine, they should create a networksessiontype. Local session. For example, each of the four gamers has its own Controller connected to the same Xbox 360.
If one or more players are on different machines and these machines are connected to the same network, you should create a networksessiontype. systemlink session. Networksessiontype. playermatch sessions work in a similar way as systemlink, but it allows players to connect to sessions over the Internet and use live services. In this case, to use these services, all participating players must purchase live gold members.
Note:Because Zune can only create network connections to another Zune, only networksessiontype. Local and networksessiontype. systemlink sessions can be used on Zune.
The second parameter specifies whether multiple players connected to the same machine can join the network. If not, you must specify that each machine has only one player. For example, if you want to start a local session, you should allow more than one player to connect to the same machine.
Note:A local player is a user on the machine where the code runs. XNa 3.0 supports only one local player on each Windows machine or Zune, and allows up to four players on Xbox 360. Each of the four players is considered local only when the other three players are connected to the same machine.
The last parameter specifies the maximum number of players that can be connected to this session. Because you want to deal with multi-player games, this number must be at least 2 and the upper limit is 31.
Networksession. Create another overload method can accept two more parameters. The first parameter specifies the number of player slots reserved for friends. In this way, only players marked as friends can connect to the session. The second parameter allows you to use a networksession attribute as the session tag, so that other players can easily find it. For more information, see tutorial 3-8.
Note:If the machine is not connected to the network, the networksession. Create method returns an error, So You encapsulate it in a try-catch structure.
Now you have a new session. You can set some attributes. An important attribute defines what should happen if the host exits. You can set the allowhostmigration attribute to true to specify that xNa automatically selects one of clients/peers to become a new host:
Networksession. allowhostmigration = true; networksession. allowjoininprogress = false;
As you can see, you can also specify which client can be added to the session after the game starts.
Note:Pay special attention to the migration of hosts. If the game data is only stored in the old host when the session exits, it is impossible to automatically transmit the data to the new host. You need to copy important data to at least two machines. In this case, if the host exits, you can copy the data to the new host.
Link to session events
Now your machine is a host of network sessions, and you need to know whether other players are connected to this session. You can do this by linking a custom method to the gamerjoined event of a Network Session. As long as a player joins a session, the session will automatically trigger the gamerjoined event. The result is that all methods linked to this event are called.
The following code connects the custom gamerjoinedeventhandler method to the gamerjoined event:
Networksession. gamerjoined + = gamerjoinedeventhandler;
In the gamerjoinedeventhandler method, you can place the code to be executed when a new player joins the session. In the following example, a line of text containing the player name is displayed on the screen:
Void gamerjoinedeventhandler (Object sender, gamerjoinedeventargs e)... {log. Add (E. gamer. gamertag + "joined the current session ");}
Like all event processing methods, this method accepts the object that initiates the event (in this example, a network session), and the second parameter contains the specific information of the event type. In this example, gamerjoinedeventargs contains the gamer object of the player who joins the session.
Network sessions can trigger other events you want to listen to, including gamerleft events, gamestarted events, and gameended events (This event indicates that the session is switched from the lobby to the game mode, see tutorial 8-7) sessionended event and hostchanged event.
Sessionended events are triggered when allowhostmigration is set to false and the host exits the session or when the host calls the dispose method on the Network Session. Hostchanged is triggered when allowhostmigration is set to true and the host exits from the session.
The following code listens to gamerjoined, gamerleft, and hostchanged events through network sessions and displays the corresponding information on the screen:
Void hooksessionevents ()... {log. add ("listening for session events"); networksession. gamerjoined + = gamerjoinedeventhandler; networksession. gamerleft + = gamerlefteventhandler; networksession. hostchanged + = hostchangedeventhandler;} void gamerjoinedeventhandler (Object sender, gamerjoinedeventargs e )... {log. add (E. gamer. gamertag + "joined the current session");} void gamerlefteventhandler (Object Sen Der, gamerlefteventargs e )... {log. add (E. gamer. gamertag + "left the current session");} void hostchangedeventhandler (Object sender, hostchangedeventargs e )... {log. add ("host migration detected"); networksession eventraisingsession = (networksession) sender; If (eventraisingsession. ishost) log. add ("this machine has become the new host! ");}
During host migration, the sender object (a network session here) is first converted to a networksession object, so that you can obtain its attributes. You can use the ishost attribute to check whether the machine has become a new host of the session.
Make sure that the hooksessionevents method is called immediately after the session is created. The following code shows the createsession status in the update method:
Case gamestate. createsession :... {networksession = networksession. create (networksessiontype. systemlink, 4, 16); networksession. allowhostmigration = true; networksession. allowjoininprogress = false; log. add ("new session created"); hooksessionevents (); currentgamestate = gamestate. insession ;}
The session is created and the values of allowhostmigration and allowjoininprogress are set. The program listens to any session-related events.
Update a Network Session
After you connect to a session, you need to update it at a certain interval. Obviously, this code should be placed during game updates. Now, you only need to perform one operation in the insession status:
Case gamestate. insession:... {networksession. Update ();} break;
Code
Here is the final update method. When the program starts, it is in the signin state, and then creates a session in the createsession state. The program is in insession state when it ends.
Protected override void Update (gametime )... {If (gamepad. getstate (playerindex. one ). buttons. back = buttonstate. pressed) This. exit (); If (this. isactive )... {Switch (currentgamestate )... {Case gamestate. signin :... {If (gamer. signedingamers. count <1 )... {guide. showsignin (1, false); log. add ("opened user signin interface");} else... {currentgamestate = gamestate. createsession; log. add (gamer. signedingamers [0]. gamertag + "logged in-Proceed to createsession") ;}} break; Case gamestate. createsession :... {networksession = networksession. create (networksessiontype. systemlink, 4, 16); networksession. allowhostmigration = true; networksession. allowjoininprogress = false; log. add ("new session created"); hooksessionevents (); currentgamestate = gamestate. insession;} break; Case gamestate. insession :... {networksession. update () ;}break ;}} base. update (gametime );}