【问题标题】:Game Center Sandbox : "Could not create game" issue游戏中心沙盒:“无法创建游戏”问题
【发布时间】:2012-06-04 10:43:22
【问题描述】:

我目前正在开发一款回合制游戏,使用 Game Center 来处理在线功能(用于匹配和回合处理)。

我正在使用两个沙盒帐户 - 一个在我的 3gs 上,一个在 ios 模拟器上。 我一直在使用 GKTurnBasedMatchMakerViewController 测试我的应用程序来进行匹配一段时间,没有任何问题,但我现在遇到了一个问题:

每次我想邀请其他玩家加入新玩家(与一个或另一个玩家一起)时,GKTurnBasedMatchMakerViewController 都会显示一个 UIAlertView 声明:

无法创建游戏 - 请删除现有游戏并重试。

问题是,我已经删除了每个玩家的所有比赛(他们的列表中没有任何比赛(甚至没有封闭的比赛)。所以目前没有任何用户参加任何比赛。

在我的 GKTurnBaseMatchMakerViewControllerDelegate 中,未调用 turnBasedMatchmakerViewController:didFailWithError:。 当我单击 UIAlertView 上的 OK 按钮时,委托中调用的唯一调用函数是 turnBasedMatchmakerViewControllerWasCancelled:

我唯一能想到的是,我的游戏实际上并没有从 GameCenter 中删除,但是当我使用 GKMatchMakerViewController UI 删除它们时,我几乎不这么认为。


当我从回合制比赛中退出时,我已经实现了 turnBasedMatchmakerViewController:playerQuitForMatch:,如下所示:

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController playerQuitForMatch:(GKTurnBasedMatch *)match
{
  if ( [self isLocalPlayerCurrentPlayerForMatch:match] ) {

    NSData* endData = match.matchData;

    for (GKTurnBasedParticipant* participant in match.participants) {
      participant.matchOutcome = GKTurnBasedMatchOutcomeWon;
    }
    match.currentParticipant.matchOutcome = GKTurnBasedMatchOutcomeLost;

    [match endMatchInTurnWithMatchData:endData 
                     completionHandler:^(NSError *error) {
                       if (error) {
                         NSLog(@"%@",error.description);
                       }
                     }];
  }  

}

(注意:我的游戏中只有两个玩家)

isLocalPlayerCurrentPlayerForMatch 在哪里:

- (BOOL) isLocalPlayerCurrentPlayerForMatch:(GKTurnBasedMatch*)match
{
  return [[[GKLocalPlayer localPlayer] playerID] isEqualToString:match.currentParticipant.playerID];
}

有没有人遇到过这个问题并找到了解决方案? 我在这里做错了什么,还是太明显了我看不到?

非常感谢任何可以帮助我找到问题根源的 cmets。

更新

感谢@kaan-dedeoglu,我设法知道两个用户都有一个空的匹配列​​表(与显示的状态一致)。

我还创建了第三个沙盒帐户。 将前两个帐户命名为 A 和 B,将 C 命名为第三个。

状态 1:

  1. A 和 B 未链接到任何匹配项。
  2. A 和 B 在创建任何游戏时都出现“无法创建游戏”错误(A 邀请 B,A||B 邀请其他玩家,A||B 创建新的自动匹配)。

状态 2:

  1. C(工作账号)可以邀请B,正常和B开派对。
  2. C(工作)可以邀请 B 参加另一个同时聚会
  3. C(工作)邀请 A 玩。
  4. A 不能玩(无法访问当前比赛列表,GKTurnBasedMatchMakerViewController 直接去创建新游戏)。
  5. C 不再工作了。
  6. A、B 和 C 现在卡在“无法创建游戏”错误中。

作为补充,这里是我如何初始化我的 GKTurnBasedMatchMakerViewController,但我不认为这是错误的。

- (void) displayMatchMakerVC
{

  if (! [[GKLocalPlayer localPlayer] isAuthenticated] ) return;

  GKMatchRequest* request = [[[GKMatchRequest alloc] init] autorelease];
  int nbPlayers = 2;
  request.minPlayers = nbPlayers;
  request.maxPlayers = nbPlayers;


  GKTurnBasedMatchmakerViewController*  matchMakerVC = [[[GKTurnBasedMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
  matchMakerVC.turnBasedMatchmakerDelegate = self;
  matchMakerVC.showExistingMatches = YES;

  [[CCDirector sharedDirector] presentModalViewController:matchMakerVC animated:YES];
}

注意:我没有使用 ARC,这可能与内存问题有关吗?我并不是真正的内存管理专家,但它似乎符合我的理解。

知道这与我的代码而不是游戏中心有何关联吗? 非常感谢您的任何回答,可以帮助我走得更远。

更新 2:turnbasedMatchmakerViewController:didFindMatchMethod:

这是我的 turnbasedMatchmakerViewController:didFindMatchMethod: 方法。

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFindMatch:(GKTurnBasedMatch *)match
{
  BLTheme* theme = [[[BLGameConfig sharedConfig] localPlayer] userTheme];
  GameSceneRemoteGCLoader* loader = [[GameSceneRemoteGCLoader alloc] initWithGKMatch:match andTheme:theme];
  [viewController dismissViewControllerAnimated:NO completion:^{}];
  [[CCDirector sharedDirector] replaceScene:loader];

}

当我启动自动匹配时,它会启动完全相同的错误“无法创建游戏 - 请删除现有游戏并重试。”。

【问题讨论】:

  • 关于您的更新的几个问题。当您使用自动匹配开始游戏时会发生什么 - 即在不邀请任何人的情况下点击“播放”。另外,我可以看看你的“turnBasedMatchmakerViewController:didFindMatch:”实现吗?
  • 当我开始自动匹配时,我得到相同的“无法创建游戏错误”。再次更新我的帖子以显示 turnBasedMatchmakerViewController:didFindMatch。感谢您的帮助,非常感谢。
  • 第二次编辑之后。我也差不多迷路了。您共享的代码部分看起来相当不错。我不知道你为什么会出错。我假设 turnBasedMatchmakerViewControllerDidFindMatch 方法甚至没有被调用。沙盒模式有时会表现得很奇怪。我的最后一个建议是注销并登录并尝试删除所有游戏(使用我的答案)。我希望我能提供更多帮助!
  • 你是对的,它甚至没有被调用。我用你的答案删除了它们,但它也没有解决我的问题。我也倾向于认为它可能与沙盒有关,因为它似乎只与我的前两个帐户有关,但我没有任何正式证据支持这一点。如果我得到答案或更多元素,我会回来发布。非常感谢您提供的帮助和花费的时间! :)
  • @thib_b ,你有没有找到解决方案?我遇到了同样的问题,一直无法找到解决方案。我怀疑当我更新构建时,旧匹配会从新构建中隐藏,但它们实际上并没有被删除,而且我有太多匹配 somewhere 导致出现错误消息。跨度>

标签: ios cocos2d-iphone game-center gamekit


【解决方案1】:

这可能是也可能不是您的问题的解决方案,但我遇到了类似的问题并通过以下方式解决了。

似乎默认情况下或不知何故,Game Center 将具有不同 CFBundleVersion(内部版本号,不是版本号,或 CFBundleShortVersionString)值的应用视为彼此不兼容,因此不会显示应用之间的匹配具有递增的内部版本号。 (通常,随着新的临时构建或稳定版本在开发过程中分发,开发人员会增加这个数字,所以这是非常不幸的)。

为了查找和删除“丢失”的游戏,我减少了我的 CFBundleVersion 值(显示游戏),然后删除了有问题的匹配项。

另外,调整 iTunes Connect 中的一些设置似乎已经消除了 CFBundleVersion 的不兼容性。传播需要一段时间,但我认为它是在点击我的应用程序,点击查看详细信息,确保游戏中心开关设置为“启用”,并确保“多人游戏兼容性”中有一个项目桌子。您也可以在原始应用程序屏幕的“管理游戏中心”按钮中玩各种可能性,但我认为“多人游戏兼容性”设置最终让我能够看到以前隐藏的所有“旧”比赛。

祝你好运!

【讨论】:

  • 我无法再测试您的解决方案,但由于这为您解决了这个特定问题,我将其标记为解决方案。谢谢!
【解决方案2】:

只是为了确保:在这两种设备中,将这些行添加到您的身份验证完成处理程序中并运行一次。 (然后您可以将其注释掉)。

[GKTurnBasedMatch loadMatchesWithCompletionHandler:(^)(NSArray *matches, NSError *error) {

   for (GKTurnbasedMatch *match in matches) {

       [match removeWithCompletionHandler:NULL];

    }
}];

这将确保从您的 playerID 中删除所有游戏。

【讨论】:

  • 非常感谢。您的代码允许我检查是否没有匹配项(空列表,检索它们也没有错误)。如果您想更进一步,请更新我的帖子。总之非常感谢! :)
  • 此调用不会从本地 playerID 中删除所有游戏。请参阅方法 removeWithCompletionHandler 的 GKTurnBasedMatch 类参考 --> “在本地玩家作为活跃参与者的比赛上调用此方法是一个编程错误。”
  • @JayHaase 在发布版本上是的,您应该先将轮到下一位玩家,然后删除比赛(否则比赛会卡住)。但是在调试时,可以在所有设备上运行此代码 - 这样就可以从游戏中心服务器中删除匹配项(因为每个参与者都会删除匹配项。)
  • 它不会删除退出匹配。如何在 ios6 中删除退出匹配项
【解决方案3】:

这很荒谬。您不必删除现有匹配来创建新匹配。我正在开发这样的游戏,它确实有效。

【讨论】:

  • Game Center 上的应用程序所允许的 GKTurnBasedMatch 的数量似乎确实存在限制。
  • 是的,正在进行的比赛是 30。但是还有更多没有进行中的。
【解决方案4】:

以下内容对我有用。首先,我在设备上为每个玩家运行应用程序,调用 quitAllMatches。然后我在每台设备上再次运行该应用程序,调用 removeAllMatches。

从长远来看,最好在进行过程中清理它们。但这解决了眼前的问题。

-(void) quitAllMatches {
    [GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray* matches, NSError* error)  {
        for (GKTurnBasedMatch* match in matches) {
            GKTurnBasedParticipant* participant = match.currentParticipant;
            NSString* playerID = participant.playerID;
            NSString* localPlayerID = [GKLocalPlayer localPlayer].playerID;
            if ([playerID isEqualToString: localPlayerID]) {
                NSArray* participants = match.participants;
                for (GKTurnBasedParticipant* participant in participants) {
                    participant.matchOutcome = GKTurnBasedMatchOutcomeTied;
                }
                NSData* data = [NSData data];
                [match endMatchInTurnWithMatchData: data completionHandler:^(NSError* error) {
                    if (error) {
                        WJLog(@"did not end -- error %@", [error localizedDescription]);
                    }
                    else {
                        WJLog(@"match ended!");
                    }
                }];
            }
        }
    }];
}

-(void) removeAllMatches {
    [GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray* matches, NSError* error)  {
        for (GKTurnBasedMatch* match in matches) {
            [match removeWithCompletionHandler:^(NSError* error) {
                if (error) {
                    WJLog(@"error: %@", [error localizedDescription]);
                }
                else {
                    WJLog(@"removed match");
                }
            }];
        }
    }];
}

【讨论】:

  • 它不会删除退出匹配。你能说一下如何在 ios6 中删除退出匹配项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多