[翻译]XNA 3.0 Game Programming Recipes之fifty-four


PS:自己翻译的,转载请著明出处

                                                                8-2 创建一个网络会话
问题
                                你想要创建一个网络会话,这样别的Xbox360控制台,Zunes,或者PCs可以找到并且加入你的会话中。
解决方案
                                一台机器首先需要去开始一个网络会话,你可以非常容易的实现它,使用NetworkSession.Create方法。这台机器,它创建一个会话将会是主机的会话。
                                在这个绘画被创建,所有的机器连接到这个会话,包括主机,通过会话可以监听任何发生的事件,例如一个玩家加入或者离开这个会话。
它如何工作的
                                你需要去包括Microsoft.XNA.Framework.Net命名空间从这节在本章的结尾的地方。通过添加下面的代码行去实现,并把它放在你代码文件的上面:
1  using  Microsoft.Xna.Framework.Net;
                                在本章中,你的程序将循环通过三个自身定义的状态。正如我们前面章节所讨论的,你将会开始在SignIn状态,在这种情况下用户被询问去选择一个帐号。前面章节的这个SingedIn状态通过CreateSession会话被取代,你创建一个新的网络会话并且监听它们的事件。最终,你结束这个InSession状态。
                                开始定义这些状态:
1  public   enum  GameState{SignIn,CreateSession,InSession}

                                SignIn状态已经在前面的章节中讨论过了。让我们开始编写CreateSession状态。

Creating a NetWwork Session(创建一个网络会话)
                                在这种状态下,你将会创建一个新的网络会话。通过添加这个变量到你的代码中:

1  NetworkSession networkSession;
                                你可以创建一个新的网络会话并保存它在这个你刚才定义的变量中,使用这个NetworkSession.Create方法,正如这里显示的:

 

1  networkSession = NetworkSession.Create(NetworkSessionType.SystemLink, 4 , 8 );
                               这行将导致这台机器主机一个新的会话到其他可以连接的玩家。正如你看见的,这个方法期待三个参数。
                               这个第一个参数指定它应该创建的会话类型。如果所有的玩家都被连接到一个同意个机器上时,一个NetworkSessionType.Local类型的会话应该被创建,例如,四个玩家可以有它们自己的控制器连接到同一台Xbox360控制台上。
                               如果一个或者更多的玩家在不同的机器上,它被连接到同样的网络中,你可以创建一个NetworkSessionType.SystemLink类型的会话。
NetworkSessionType.PlayerMatch类型与SystemLink类型以相同的方式工作,但是它将允许用户去连接会话在因特网上,产生有用的在线服务器。在此刻,虽然,为了使用这些服务,你需要去买一个Live Gold 会员为所有的多个Xbox360控制台。
注意:因为Zune可以创建网络连接到其他的Zunes,你可以使用唯一的NetworkSessionType.Local和NetworkSessionType.SystemLink会话
类型为这个Zune.
                              第二个参数指定是否多个玩家连接到网络上的同一台机器。如果不能,你应该指定,这里每台机器只能有一个玩家。如果你想这样,例如,开始一个本地会话,你应该允许更多玩家去连接到同一台机器。
注意:一个本地玩家是一个用户在这台机器上允许它的代码。现在,XNA3.0支持唯一的一个本地玩家在每一个Windows-based机器和Zune,同时让四个玩家可以连接到一个Xbox360控制台。通过其他三个玩家连接到同样的机器上,这台四个玩家之一的玩家机器被认为是本地机器(译者:主机)
                              最后一个参数指定它能连接会话中的最大玩家数量。因为你处理多人游戏,这个数量至少是2,同时它应该等于或者小于上限,那么PC的上限是31,Xbox360的是31,Zune设备的上限是8
                              NetworkSession.Create方法有一个重载版本,它接收两个以上的参数。第一个参数指定玩家的数量,它应该保持这个变量为你的朋友。这样,只有你标记为朋友的玩家将可以加入这个会话。最后一个参数允许你去标记你的会话用一个NetworkSessionProperties对象,这样其他可以很容易的找到它。参看8-3节的列子。
注意:如果机器根本没有连接任何的网络,这个NetworkSession.Create方法将会抛出一个错误,这样你希望封装它在try-catch结构中。
                              现在,我们开始一个新的会话,你可以设置一些它的属性。一个重要的属性定义为什么会发生,如果主机退出这个会话。你可以指定XNA应该自动选择客户/同行之一通过设置这个AllowHostMigration属性为true,去成为新的主机:
1  networkSession.AllowHostMigration = true ;
2  networkSession.AllowJoinInProgress = false ;

                              正如你所看见的,你同样可以指定客户是否被允许加入这个会话在游戏已经开始了。
注意:应该特别注意采取主机的移植。如果任何游戏数据被专门的保存在旧的主机上,当它退出这个会话,它是非常重要的使这些数据自动转换到新的主机上。你想使至关重要的数据复制到最新的两台机器上,这样如果主机退出了,你可以复制这个数据到新的主机上。
                              因为XNA3.0,当本地玩家离开这个游戏时,本地网络会话将不会结束。相反,这个会话将持续至少还有一个玩家在这个会话中。

Hooking to the Session Events
                              现在,你的机器主持一个网络会话(主机),它将会很容易知道当其他人加入了这个会话。你可以通过挂起一个自身-定义的方法到网络会话的GamerJoined事件来实现它。只要一个玩家加入这个会话,这个会话将自动触发这个GamerJoined事件。作为一个结果,所有的方法挂起到这个将会被调用的事件。

                              这行将导致本身-定义的GamerJoinedEventHandler方法被挂起到GamerJoined的事件:
1  networkSession.GamerJoined += GamerJoinedEventHandler;
                              在这个GamerJoinedEventHandler方法,你可以放入所有代码,它可以被执行只要一个新玩家加入了这个会话。下面的样列将会导致文本行包含玩家的姓名被打印到屏幕上:
1  void  GamerJoinedEventHandler( object  sender,GamerJoinedEventArgs e)
2  {
3      log.Add(e.Gamer.Gamertag + " joined the current session " );
4  }
                              如同所有的事件-处理方法,这个方法将接收对象,它放出事件(在这种情况下,网络会话),以及第二个参数包含指定的信息,它来自这种类型事件。在这种情况下,GamerJoinedEventArgs包含Gamer对象对应的玩家,它刚刚加入了这个会话。
                              这个网络会话可以唤醒别的事件,你可以监听它。这里包括GamerLeft事件和GameStarted和GameEnded事件,它表明当会话从大厅转换到游戏模式(参看8-7节),以及SessionEnded和HostChanged事件。
                              SessionEnded事件被激发,当主机退出这个会话,同时AllowHostMigration被设置为false或者当主机调用这个Dispose方法在网络会话上。这个HostChanged事件被触发当主机退出这个会话,同时AllowHostMigration被设置成true。
                              下面的代码将会坚听这个GamerJoined,GamerLeft,和HostChanged事件的激发通过网络会话,并且打印一个相应的行到屏幕上:
 1  void  HookSessionEvents()
 2  {
 3      log.Add( " Listening for session events " ); 
 4      networkSession.GamerJoined += GamerJoinedEventHandler;
 5      networkSession.GamerLeft += GamerLeftEventHandler;
 6      networkSession.HostChanged += HostChangedEventHandler;
 7  }
 8  void  GamerJoinedEventHandler( object  sender,GamerJoinedEventArgs e)
 9  {
10       log.Add(e.Gamer.Gamertag + " joined the current session " );
11  }
12  void  GamerLeftEventHandler( object  sender,GamerLeftEventArgs e)
13  {
14       log.Add(e.Gamer.Gamertag + " left the current session " );
15  }
16  void  HostChangedEventHandler( object  sender,HostChangedEventArgs e)
17  {
18       log.Add( " Host migration detected " );
19       NetworkSession eventRaisingSession = (NetworkSession)sender;
20        if (eventRaisingSession.IsHost)
21            log.Add( " This machine has become the new Host! " );
22  }
                               在主机的移动的情况下,发送对象(它是你知道的一个网络会话)是首先转化为NetworkSession对象,这样你可以询问它的属性。这它们其中之一是IsHost属性,你可以使用它去检测这台机器是否成为这个会话新的主机。
                               确保你直接调用这个HookSessionEvents方法在你已经创建你的会话之后。这就是CreateSession状态在Update方法应该看起来象这样:
1  case  GameState.CreateSession:
2  {
3     networkSession = NetworkSession.Create(NetworkSessionType.SystemLink, 4 , 8 );
4     networkSession.AllowHostMigration = true ;
5     networkSession.AllowJoinInProgress = false ;
6     log.Add( " New session created " );
7     HookSessionEvents();
8     currentGameState = GameState.InSession;
9  }

                               这个会话被创建,AllowHostMigration和AllowJoinInProgress值被设置,并且程序正在监听每个触发的事件通过这个会话。

Updateing the Network Session(更新网络会话)
                               一旦你连接了一个会话,你应该更新它在定期的时间内。一个明显的地方要做到这个是在你的游戏的更新循环中。现在,这是唯一的事情,它被完成在InSession状态时期:

1  case  GameState.InSession:
2  {
3      newworkSession.Update();
4  }
5  break ;

 

代码
                                在这里,你可以找到最终的Update方法。这个程序将开始于SignIn状态,在一个会话被创建在CreateSession状态中。程序结束在InSession状态。
 1  protected   override   void  Update(GameTime gameTime)
 2  {
 3        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
 4              this .Exit();
 5        if ( this .IsActive)
 6       {
 7            switch (currentGameState)
 8           {
 9                case  GameState.SignIn:
10               {
11                    if (Gamer.SignedInGamers.Count < 1 )
12                   {
13                          Guide.ShowSignIn( 1 , false );
14                          log.Add( " Opened User SignIn Interface " );
15                   }
16                    else
17                   {
18                          currentGameState = GameState.CreateSession;
19                          log.Add(Gamer.SignedInGamers[ 0 ].Gamertag + " logged in -proceed to CreateSession " );
20                   }
21               }
22                break ;
23                case  GameState.CreateSession:
24               {
25                          networkSession = NetworkSession.Create(NetworkSessionType.SystemLink, 4 , 8 );
26                          networkSession.AllowHostMigration = true ;
27                          networkSession.AllowJoinInProgress = false ;
28                          log.Add( " New session created " );
29                          HookSessionEvents();
30                          currentGameState = GameState.InSession;
31               }
32                break ;
33                case  GameState.InSession:
34               {
35                          networkSession.Update();
36               }
37                break ;
38           }
39       }
40        base .Update(gameTime);
41  }
42 
源代码: http://shiba.hpe.cn/jiaoyanzu/WULI/soft/xna.aspx?classId=4
(完)

转载于:https://www.cnblogs.com/315358525/archive/2009/09/05/1560878.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值