4

私は現在、Game Center を使用してオンライン機能 (マッチメイキングとターン処理) を処理するターン ベースのゲームを開発しています。

私は 2 つのサンドボックス アカウントを使用しています。1 つは 3gs で、もう 1 つは 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);
                       }
                     }];
  }  

}

(注:ゲームには2人のプレーヤーしかいません)

isLocalPlayerCurrentPlayerForMatch は次のとおりです。

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

誰かがこの問題に遭遇して解決策を見つけましたか? ここで何か間違ったことをしているのですか、それともあまりにも明白すぎて見えないだけですか?

その問題の根本を見つけるのに役立つコメントをありがとうございます。

アップデート

@kaan-dedeoglu のおかげで、両方のユーザーの一致リストが空であることがわかりました (表示された状態と一致しています)。

3 つ目のサンドボックス アカウントも作成しました。最初の 2 つのアカウントを A と B、C を 3 つ目のアカウントとします。

状態 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. プレイできません (現在のマッチのリストにアクセスできません。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];

}

オートマッチを起動すると、まったく同じエラー「ゲームを作成できませんでした - 既存のゲームを削除してからやり直してください。」が表示されます。

4

4 に答える 4

1

念のため: これらの両方のデバイスで、これらの行を認証完了ハンドラーに追加し、1 回実行します。(その後、コメントアウトできます)。

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

   for (GKTurnbasedMatch *match in matches) {

       [match removeWithCompletionHandler:NULL];

    }
}];

これにより、すべてのゲームがプレイヤー ID から確実に削除されます。

于 2012-06-04T12:28:00.003 に答える
1

これは問題の解決策である場合とそうでない場合がありますが、同様の問題があり、次の方法で解決しました。

デフォルトまたはどういうわけか、Game Center は値が異なるアプリCFBundleVersion(バージョン番号ではなくビルド番号CFBundleShortVersionString) を互いに互換性がないものとして扱い、ビルド番号が増分されたアプリ間の一致を表示しないようです。(開発中に新しいアドホック ビルドまたは安定版リリースが配布されると、開発者はこの数を増やすことが多いため、これは非常に残念なことです)。

「見つからない」ゲームを見つけて削除するために、CFBundleVersion値を減らして (ゲームが明らかになりました)、問題のある試合を削除しました。

あるいは、iTunes Connect でいくつかの設定を微調整すると、このCFBundleVersion非互換性が解消されたようです。反映には時間がかかりますが、アプリをタップし、[詳細を表示] をタップし、Game Center のスイッチが [有効] に設定されていることを確認し、[マルチプレイヤーの互換性] に項目があることを確認したことが原因だったと思います。テーブル。元のアプリ画面から「ゲームセンターの管理」ボタン内の可能性を試すこともできますが、「マルチプレイヤー互換性」設定により、以前は非表示になっていたすべての「古い」マッチを最終的に表示できるようになったと思います.

幸運を!

于 2013-03-23T15:45:00.483 に答える
0

以下は私のために働いた。最初に、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");
                }
            }];
        }
    }];
}
于 2013-05-19T03:18:22.367 に答える
0

バカバカしい 。新しい一致を作成するために、既存の一致を削除する必要はありません。私はこのようなゲームを開発していますが、実際に動作します。

于 2013-01-13T02:13:20.010 に答える