6

Game Center で招待状を実装しようとしていますが、わからないことが 1 つあります。わかりました。あるデバイスから別のデバイスに招待状を送信しました。次に、受信者に UIAlertView があり、招待を受け入れるか拒否するかを尋ねます。私がそれを受け入れると、次のように処理されます。

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) 
                 {
                     // Insert application-specific code here to clean up any games in progress.
                     if (acceptedInvite)
                     {
                         GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
                         mmvc.matchmakerDelegate = self;
                         [presentingViewController presentModalViewController:mmvc animated:YES];
                     }
                     else if (playersToInvite)
                     {
                         GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
                         request.minPlayers = 2;
                         request.maxPlayers = 4;
                         request.playersToInvite = playersToInvite;

                         GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
                         mmvc.matchmakerDelegate = self;
                         [presentingViewController presentModalViewController:mmvc animated:YES];

                     }
                 };

それは素晴らしいことですが、次は何ですか?送信側のデバイスは明らかに標準タイプの応答を待っています。「今すぐプレイ」をタップすると、まだ応答されていない招待状があることを知らせるアラートも表示されます。

では、どうすれば招待を受け入れることができるのでしょうか? どのようなデータを (どのように) 送り返す必要がありますか? そして、受信側で正確に何をすべきですか?[同意する] をタップした後、すぐにゲームを開始する必要がありますか?それとも、最初に AlertView を閉じてから [今すぐプレイ] をタップする必要がありますか?

Ray Wenderlich のチュートリアルでは、2 番目の方法を選択する必要があると書かれていますが、アラートを閉じて [今すぐ再生] をタップすると、送信側のデバイスがまだ応答を待っていることがわかり、招待を既に受け入れたことを認識していません。この時点で「今すぐプレイ」をタップすると、上で述べたように、アプリケーションが応答を待っていることを示すアラートが表示されます。それで、あなたがそれをしたことがあるなら、私が何をすべきかを説明してください. ありがとう!

4

3 に答える 3

5
  1. ゲームがロードされるとすぐに招待に登録し、招待が受信されたらデリゲートに電話します
  2. したがって、inviteReceived はマッチ メーカーを呼び出して、ゲーム センター コントローラーを閉じ、マッチを作成します。
  3. そして最後に、一致が見つかると、メソッド connectionStatusChanged がすべてのゲームのビューとプレーヤーなどを表示します。

コードは次のとおりです。

ゲームが読み込まれるとすぐに招待を登録し、招待を受信したらデリゲートを呼び出します。

- (void)registerInvites {
    [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
        self.pendingInvite = acceptedInvite;
        self.pendingPlayersToInvite = playersToInvite;
        [delegate inviteReceived];
    };
}

したがって、inviteReceived はマッチ メーカーを呼び出して、ゲーム センター コントローラーを閉じてマッチを作成します。

- (void)inviteReceived {
    [[GCMultiplayerHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:(UIViewController*)[self.superview nextResponder] delegate:self];
}


- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCMultiplayerHelperDelegate>)theDelegate {
    if (!gameCenterAvailable) return;

    matchStarted = NO;
    self.match = nil;
    self.presentingViewController = viewController;
    delegate = theDelegate;

    [presentingViewController dismissModalViewControllerAnimated:YES];
    GKMatchmakerViewController *mmvc;

    if (pendingInvite != nil) {

        mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:pendingInvite] autorelease];

    } else {

        GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease]; 
        request.minPlayers = minPlayers;     
        request.maxPlayers = maxPlayers;
        request.playersToInvite = pendingPlayersToInvite;

        mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];    

    }

    mmvc.matchmakerDelegate = self;
    [presentingViewController presentModalViewController:mmvc animated:YES];

    self.pendingInvite = nil;
    self.pendingPlayersToInvite = nil;
}

そして最後に、一致が見つかった場合、connectionStatusChanged メソッドがすべてのゲーム ビュー、プレイヤーの表示、および一致の開始を処理します。

- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch
{
    self.match = theMatch;
    match.delegate = self;
    if (!matchStarted && match.expectedPlayerCount == 0) {
        NSLog(@"Ready to start match! - didFindMatch");
        [presentingViewController dismissModalViewControllerAnimated:YES];

        [self.delegate connectionStatusChanged:CONNECTIONSUCCESS];
    }
}
于 2012-06-14T20:22:22.893 に答える
3

Ray のチュートリアルに従って、オンライン ゲーム センター マッチを正常に実装しました。あなたの質問に対する答えは次のとおりです。招待側のデバイスに何も送信する必要はありません。line: を呼び出すとGKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];、matchMakerVController が接続を処理します。ただし、できれば認証変更メソッドで、できるだけ早く招待ハンドラを作成する必要があります。私を参照してください:

-(void) authenticationChanged {

if ([GKLocalPlayer localPlayer].isAuthenticated && !userAuthenticated) {
    NSLog(@"Authentication changed: player authenticated.");
    userAuthenticated = TRUE;

    [self sendUnsentScores];

    [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite){

        NSLog(@"Invite");

        if([AppDelegate mainMenuController].presentedViewController!=nil) {
            [[AppDelegate mainMenuController] dismissViewControllerAnimated:NO completion:^{

            }];
        } // if we're not on the main menu, or another game is going on.
          // this would be easier to do if you were using a navigation controller
          // where you'd just push the multiplayer menu etc.


        self.pendingInvite = acceptedInvite;
        self.pendingPlayersToInvite = playersToInvite;

        [[AppDelegate mainMenuController] presentViewController:[AppDelegate mainMenuController].multiGameMenu animated:NO completion:^{ // push the multiplayer menu

            [[AppDelegate mainMenuController].multiGameMenu duel:nil];
        }];

    };

}

決闘方法はこちら。非常に厄介なコードですが、それを処理してください:)

- (IBAction)duel:(id)sender {
NSLog(@"duel");

if (presentingMenu.multiGameController==nil || presentingMenu.multiGame.gameInProgress==NO) {

    presentingMenu.multiGame=nil;
    presentingMenu.multiGameController=nil;

    MultiViewController *mvc = [[MultiViewController alloc] init]; //create game VC

    presentingMenu.multiGameController = mvc; //presenting menu is just the main menu VC
                                              // it holds this menu, and the game
                                              // objects.
}

if (presentingMenu.multiGame == nil) {

    presentingMenu.multiGame = [[MultiGame alloc] // similarly create the game object

    initWithViewController:presentingMenu.multiGameController];
    //they both have pointers to each other (A loose, bad MVC).                        

    presentingMenu.multiGameController.game = presentingMenu.multiGame;

    [presentingMenu.multiGame startGame];

}

if (presentingMenu.multiGameController.gameState==0) { //new game

    presentingMenu.multiGameController.game = presentingMenu.multiGame;

    [[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:self delegate:presentingMenu.multiGame]; // the GC magic happens here - it know about the invite.

} else {

    [self presentViewController:presentingMenu.multiGameController animated:YES completion:^{

    }];

}

}
于 2012-06-13T20:13:44.120 に答える
1

invokeHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) は非推奨になりました。招待通知の新しい登録方法をご覧ください。

GKMatchMaker 招待ハンドラの廃止

于 2014-11-06T18:55:46.383 に答える