2

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

我试图使用这段代码,希望它能起作用,但它是徒劳的。“我们已断开连接”。消息永远不会被触发。

- (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];
  }
}

但是我假设如果对手断开连接并且我们无法向他们发送消息,那么“成功”也将是错误的。

我有一个非常严格的游戏逻辑,如果有人掉线了,我需要通知他们他们无法继续比赛并且他们已经输了。

非常感谢任何帮助。

4

2 回答 2

1

有两个地方可以做到这一点,都在GKMatchDelegate协议中。

首先是实施:

- (void)match:(GKMatch *)match player:(NSString *)playerID 
  didChangeState:(GKPlayerConnectionState)state
{
}

如果是 2 人比赛,那么您可以发现断开连接的第二个地方是:

- (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" ) ;
}
于 2013-05-27T17:00:37.003 回答
0

检查error以下代码行之后的内容如何:

  BOOL success = [match sendDataToAllPlayers:data
                                withDataMode:GKMatchSendDataReliable
                                       error:nil]; //replace nil with NSError variable

也许error会给你额外的信息你需要。
另一个想法是创建 NSTimer 并设置一些特定的时间来进行移动/转弯。如果某个玩家在一段时间内没有成功,则假设该玩家已断开连接。您还可以检查您的 Internet 连接状态以确定您是否有连接,因为您可能只是丢失了它,这就是您无法发送/接收任何数据的原因。
您还可以通过使用 GC 向他们发送一些少量数据来定期检查每个玩家,以便让他们回答您。这样,您可以确保所有玩家都“活着”或检测到一些“僵尸”。
请记住,如果玩家使用主页按钮将游戏移至后台,则无论如何您都不会检测到它,因为游戏中的代码不会执行。而这种情况并不意味着玩家是“僵尸”。播放器可能正忙于通话或其他应用程序之类的东西。播放器可能会暂时断开 Internet 连接。这意味着他/她可以很快回到比赛中......

于 2012-12-05T20:54:26.477 回答