6

我正在尝试使用 Game Center 实施邀请,但有一件事我不明白。好的,我已经从一台设备向另一台设备发送了邀请。然后我在接收器上有一个 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 的教程说我应该选择第二种方式,但是当解除警报并点击“立即播放”时,发件人设备仍在等待响应并且不知道我已经接受了邀请。如果我此时点击“立即播放”,那么正如我上面所说,它会显示一条警报,说明应用程序正在等待响应。因此,如果您曾经这样做过,请解释一下我该怎么做。谢谢!

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 调用 match maker 以关闭游戏中心控制器并创建匹配:

- (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 回答