zoukankan      html  css  js  c++  java
  • [翻译]XNA 3.0 Game Programming Recipes之fiftyfour


    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
    (完)
  • 相关阅读:
    ubuntu安装netcat
    护网工作
    ssrf绕过
    文件包含绕过
    thinkphp5.0.23
    xxe
    文件上传
    文件上传html xss
    获取网站title
    RobotFramework使用AutoItLibrary输入字符错误问题
  • 原文地址:https://www.cnblogs.com/315358525/p/1560878.html
Copyright © 2011-2022 走看看