【问题标题】:iPhone - Online Multiplayer game ... understanding the mechanicsiPhone - 在线多人游戏...了解机制
【发布时间】:2012-02-23 09:04:57
【问题描述】:

我正在开发一款在线多人游戏,但我在处理 Apple 文档时遇到了困难。 (我已经尝试了 Ray Wenderlichs Part 1part 2 的这些教程,但它们不起作用(匹配永远不会开始,因为邀请设备永远不会收到匹配接受)。

由于这个主题很广泛,我将创建一个问题,然后在必要时创建另一个关于 SO 的问题。

我想创建一个在线多人游戏,让用户可以邀请 1 到 3 个人。所以,这将是一场 2 到 4 人的比赛。游戏不是基于回合制的。它是实时的,用户之间传输的数据最少。

让我们从基本的东西开始。

1) 我做的第一件事是创建一个通知

if (self.gameCenterAvailable) {
    NSNotificationCenter *nc = 
    [NSNotificationCenter defaultCenter];
    [nc addObserver:self 
           selector:@selector(authenticationChanged) 
               name:GKPlayerAuthenticationDidChangeNotificationName 
             object:nil];

}

通知更改时通知我。发生这种情况时,authenticationChanged 方法将触发...这里是

- (void)authenticationChanged {    

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;
        [self 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;
        [self presentModalViewController:mmvc animated:YES];
    }
};

}

我从 Apple 获取了此代码。我的问题是这个。如果 Apple 说在用户通过身份验证后运行此代码,为什么它要检查邀请或用户邀请?据我所知,尚未邀请用户。除非当时没有执行代码,对吧?它只会留在内存中等待被调用,当邀请完成时,对吗?

如果是这样,我现在创建一个比赛邀请

[self dismissModalViewControllerAnimated:NO];
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease]; 
request.minPlayers = minPlayers;     
request.maxPlayers = maxPlayers;
request.playersToInvite = self.pendingPlayersToInvite;

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

[self presentModalViewController:mmvc animated:YES];

我选择邀请的所有用户都会看到一个窗口。假设第一个在邀请上点击接受。我的应用会触发哪种方法,如何获取用户身份以及如何知道是否所有用户都接受了?

谢谢。

【问题讨论】:

    标签: iphone ios game-center


    【解决方案1】:

    首先请注意,沙盒环境中的邀请往往无法正常工作,因此我建议您首先让所有玩家搜索可用的匹配项。代码是这样的:

    GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
    request.minPlayers = minPlayers;
    request.maxPlayers = maxPlayers;
    
    [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request
                                   withCompletionHandler:^(GKMatch *match, NSError *error) {
                                         if (error || !match) {
                                           // handle the error
                                         }
                                         else if (match != nil){
                                           // match found
                                         }}];
      }
    

    那么你必须实现协议GKMatchDelegate。那里有一个方法,将为每个加入比赛的玩家和每个与它断开连接的玩家调用(在此方法上,您可以通过其 playerID 找到用户身份):

    - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
        switch (state){
          case GKPlayerStateConnected: 
            if (match.expectedPlayerCount == 0) {
              // start the match
            }
            break;
          case GKPlayerStateDisconnected:
            // remove the player from the match, notify other players, etc
            break;
        } 
    }
    

    关于您的第一个问题,authenticationChanged 上的代码仅注册这些方法的处理程序,这意味着通知到达时将调用的代码。

    编辑:关于您评论的问题,如果比赛是由邀请开始的,开始比赛的用户必须等到所有邀请都被接受,或者取消其中一些邀请,然后按开始比赛(或类似的东西) 在邀请屏幕上。在这种情况下,一旦所有接受邀请的玩家都连接到比赛,match.expectedPlayerCount == 0 条件将得到满足。 如果比赛是由 AutoMatch 开始的,那么 Game Center 会执行以下操作:一旦发现 minPlayers 正在等待开始比赛,它会将他们分配给一场比赛,然后再等待几秒钟,看看它是否可以填满剩余的插槽。在某些时候,它将在 minPlayers 和 maxPlayers 之间以一定数量的玩家开始比赛。那么条件match.expectedPlayerCount == 0 将仅在所有玩家有效加入比赛后才满足,但请注意,当决定开始比赛时,Game Center 已经确定了该比赛的预期玩家人数。

    【讨论】:

    • 感谢您的回答,但这是关于“if (match.expectedPlayerCount == 0)”这一行的问题。如果我让用户可以创建一个邀请 1 到 3 人的匹配,那么这个条件究竟会在什么时候触发?我的意思是,如果比赛可以有从 2 到 4 的任意数量的玩家,那么它每次都会满足这个“如果”。因此,在第一个用户接受后,比赛将开始。这就是我对这件事如何运作的看法开始分崩离析的原因。
    • 请看我上面的编辑。如果您有更多问题,请告诉我,根据我自己的经验,Game Center 一开始可能会让人感到困惑,但一旦处理得当,它就会像魅力一样发挥作用。
    • 好的,现在我明白了,但假设这样:一个玩家(我们称他为玩家一号)发送了 3 个邀请,两个邀请被接受,但在最后一个回答之前,玩家一按现在开始播放。将运行什么方法?比赛:球员:didChangeState:?感谢您的帮助。
    • 不,match:player:didChangeState: 不会被执行,因为第三个玩家一开始就没有连接到比赛。另外我不确定您是否可以按立即播放(我现在没有开发环境可以检查),除非所有受邀玩家都已接受或您已取消邀请。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 2017-12-09
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多