Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何判断何时与GameCenter GKMatch会话断开连接?_Iphone_Objective C_Ios_Game Center_Multiplayer - Fatal编程技术网

Iphone 如何判断何时与GameCenter GKMatch会话断开连接?

Iphone 如何判断何时与GameCenter GKMatch会话断开连接?,iphone,objective-c,ios,game-center,multiplayer,Iphone,Objective C,Ios,Game Center,Multiplayer,我想知道当游戏会话正在进行,并且我们无法与其他玩家交流数据时,如何获取本地玩家的断开连接消息。由于文档中没有说明“当您的连接失败时,此方法将通知您”,我有点不知所措 我试图使用这段代码,希望它能工作,但这是徒劳的。“我们已断开连接”消息从未触发 - (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state { if (self.match

我想知道当游戏会话正在进行,并且我们无法与其他玩家交流数据时,如何获取本地玩家的断开连接消息。由于文档中没有说明“当您的连接失败时,此方法将通知您”,我有点不知所措

我试图使用这段代码,希望它能工作,但这是徒劳的。“我们已断开连接”消息从未触发

- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
  if (self.match != theMatch) return;

  switch (state) {

    case GKPlayerStateDisconnected:
      //disconnected
      NSLog(@"player status changed: disconnected");
      matchStarted = NO;
      GKLocalPlayer *player = [GKLocalPlayer localPlayer];
      if ([playerID isEqualToString:player.playerID]) {

        // We have been disconnected
        NSLog(@"We're disconnected.");
      }
      if ([delegate respondsToSelector:@selector(matchEnded)]) {
        [delegate matchEnded];
      }
      break;
  }
}
我发现的另一条可能告诉我们无法通信的线路是当我们实际发送以下数据时:

- (void)sendRandomMatchData:(NSData *)data {  
  GKMatch *match = [GCHelper sharedInstance].match;
  BOOL success = [match sendDataToAllPlayers:data
                                withDataMode:GKMatchSendDataReliable
                                       error:nil];
  if (!success) {
    [self matchEnded];
  }
}
但我认为,如果对手断开连接,我们无法向他们发送消息,“成功”也将是错误的

我有一个非常严格的游戏逻辑,如果有人已经断开连接,我需要通知他们,他们无法继续比赛,他们已经输了


非常感谢您的帮助。

在以下代码行之后检查
错误如何:

  BOOL success = [match sendDataToAllPlayers:data
                                withDataMode:GKMatchSendDataReliable
                                       error:nil]; //replace nil with NSError variable
可能
error
会为您提供所需的额外信息。
另一个想法是创建NSTimer并为移动/转弯设置一定的时间。如果某个玩家在某段时间内没有成功,则假定该玩家已断开连接。此外,您还可以检查您的Internet连接状态以确定您是否有连接,因为您可能刚刚丢失了连接,这就是您无法发送/接收任何数据的原因。
此外,您还可以使用GC定期向每个玩家发送少量数据,让他们回答您的问题。这样,您可以确保所有玩家都“活着”或检测到一些“僵尸”。

请记住,如果玩家使用Home按钮将游戏移动到后台,您无论如何都不会检测到它,因为游戏中的Z代码不会执行。这种情况并不意味着玩家是“僵尸”。玩家可能正忙着打电话或其他类似于其他应用程序的事情。玩家可能会暂时失去互联网连接。这意味着他/她可以很快回到游戏中……

您可以在两个位置执行此操作,这两个位置都在协议中

第一是实施:

- (void)match:(GKMatch *)match player:(NSString *)playerID 
  didChangeState:(GKPlayerConnectionState)state
{
}
如果这是一场双人比赛,你能抓住的第二个机会是:

- (BOOL)match:(GKMatch *)theMatch shouldReinvitePlayer:(NSString *)playerID
{
}
GKMatch
终止时,这两个事件都会可靠地触发。如果Stan的回答回答了您的问题,那么我强烈建议您在任何可用的地方练习捕捉
NSError
!可以节省你很多时间

因此,要发送数据并捕获错误:

NSError* nsErr ;
int result = [theMatch sendData:nsd toPlayers:theMatch.playerIDs
              withDataMode:GKMatchSendDataReliable error:&nsErr] ;
if( !result ) { // NO if the match was unable to queue the data.
  error( nsErr, "Failed to sendRoundtripPing" ) ;
}

sendDataToAllPlayers
是异步的。返回代码只告诉您队列是否成功,而不告诉您传输是否成功。您还应该捕获
n错误
!我也注意到了这一点。如果玩家主动结束比赛,GKPlayerStateDisconnected将被命中,但在网络错误时,它不会被触发,并且可以在无效状态下获得活动比赛。