如何检测GameKit自动匹配失败

时间:2013-06-11 22:24:33

标签: iphone ios game-center

如何检测GameKit自动匹配是否失败?

等待2分钟后,即使没有找到自动匹配的玩家,也会调用 GKMatchmakerViewControllerDelegate matchmakerViewController:didFindMatch:。游戏中心的小号声音甚至可以播放。我确信没有找到任何玩家,因为这是在Game Center Sandbox中发生的,没有其他人可以访问我的应用程序。

当我尝试加载播放器*时,我收到错误,但必须有更好的方法来检查自动匹配失败,对吧?当自动匹配失败时,有没有办法防止喇叭声响起?


*加载播放器会在自动匹配失败时显示错误:

[GKPlayer loadPlayersForIdentifiers:self.match.playerIDs withCompletionHandler:^(NSArray *players, NSError *error)
     {
         LOG_DEBUG(@"loadPlayersForIdentifiers completion handler called");
         if (error != nil)
         {
             LOG_ERROR(@"Error loading player information: %@", error);                 
         }
     }];

这显示以下错误:

  

加载播放器信息时出错:Error Domain = GKErrorDomain Code = 17“由于一个或多个参数无效,无法完成请求的操作。” UserInfo = 0xb183a70 {NSLocalizedDescription =由于一个或多个参数无效,无法完成请求的操作。}


以下是我用来调出GameKit匹配用户界面的代码:

GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.defaultNumberOfPlayers = 2;

GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];
mmvc.matchmakerDelegate = self;

[self presentViewController:mmvc animated:YES completion:nil];

对于完整的上下文,我的整个应用程序都是开源的,主视图控制器在这里:https://github.com/jdimatteo/TeamRun/blob/master/TeamRun/TeamRun/TeamRunViewController.m

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

即使没有找到播放器,自动匹配也会成功。第二个(等等)参与者将是具有零ID的非零对象,并代表占位符以供将来玩家匹配。如果可以在没有将所有玩家添加到游戏中的情况下进行第一次转弯,则可以立即开始游戏。

我认为loadPlayersWithIdentifiers的错误是因为其中一些标识符为nil。

您可以检查participant.playerID == nil,然后将其视为尚未准备就绪,或以对游戏有意义的方式处理。

答案 1 :(得分:0)

webjprgm's answer仅与GKTurnBaseMatches有关,AFAIK。从代码的外观来看,您正在实现实时匹配。

在实时匹配中,自动匹配仅保证种类成功。

我的意思是,在实践中,我发现它有时根本没有成功。但有时候会返回一个空的匹配。“空”我的意思是它根本没有任何的玩家,甚至没有任何

棘手的是,如果你得到一个空的匹配,有时那个匹配实际上很快就会被填满。但有时候只是。其他时候你可以永远等待,但它不会被填满。

因此,为了监控这种情况,我必须做的事情很复杂,但它确实有效:

  • 在您的请求处理程序中,将任何返回的GKMatch存储为实例变量。我相信你已经这样做了。
  • 发送请求后,创建一个{15}左右运行任务的DispatchSourceTimer *。 DispatchSourceTimer在Swift中可用,同样的事情是可行的但在Objective-C中更复杂。
  • 该计时器必须在后台线程中运行。这非常重要。这不适用于高优先级队列。
  • 在该任务中,检查两件事。
    • 检查GKMatch实例变量是否为nil
    • 如果不是nil,请检查其.players.count号码是否为0
  • 如果第一个条件为真,取消匹配请求,并在取消的完成处理程序中,启动新请求和新计时器。
  • 如果第二个条件为真,请执行相同的操作,除非此时将计时器设置为在20秒内关闭(因为有时现有匹配需要更长时间才能填充,但你仍然不想永远地闲逛。)

最终结果是你有一个循环周期,请求自动匹配,检查它是否成功,如果没有,则取消并重新启动请求。

我花了很长时间才使这个解决方案有效,但是当我这样做时,我对结果非常满意。是的,这是一个复杂的过程,如果有人想尝试一下,我希望他们能够驾驭Game Kit和Grand Central Dispatch的许多陷阱。

但值得一提的是,在我迄今为止的测试中,这绝不会失败以匹配请求自动匹配游戏的两个玩家。在我这样做之前,经常发生两个请求游戏的玩家永远不会连接。对我来说,它的效果非常好。

*注意:我发现将计时器设置为少于15秒的时间使得该过程极不可能成功。不完全确定原因,但情况确实如此。