一些startBrowsingForNearbyPlayersWithReachableHandler问题

时间:2013-08-07 16:15:24

标签: ios game-center gamekit

我试图使用[[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:]在GameKit中进行本地匹配。从本质上讲,我试图实现无接口的本地匹配:只要我本地附近有一名玩家,我想连接并开始匹配。重要的是,我想要为本地玩家做这件事:我从不希望通过互联网自动匹配。

我在iTunes中为我的应用启用了游戏中心连接,并在我用来测试的每台设备上注册了不同的沙盒帐户。

我已尝试与GKMatchmakerViewController进行配对(在验证本地播放器之后)和与startBrowsingForNearbyPlayersWithReachableHandler:进行程序化匹配,在iPhone 4和第4代iPod Touch上运行相同的代码我桌上的对方。都没有找到另一个;当使用GKMatchmakerViewController时,用于寻找附近玩家的界面仍然在

  

寻找玩家......

微调器,当使用startBrowsingForNearbyPlayersWithReachableHandler:时,通知块永远不会被调用。

这是我目前的测试代码块:

-(void)connectLocal
{
    if( ![GKLocalPlayer localPlayer].isAuthenticated )
    {
        // authenticateLocalPlayer calls connectLocal again after authentication is complete
        [ self authenticateLocalPlayer ];
        return;
    }
    [[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:^(NSString *playerID, BOOL reachable) {
             NSLog(@"Reachability changed for player %@", playerID );
        } ];
}

文档有点稀疏&这个主题令人困惑,特别是当涉及到本地多人游戏和互联网上的比赛之间的差异时。例如,在找到加入该匹配的玩家(Creating Any Kind of Match Starts with a Match Request)之前,似乎有必要对本地玩家进行身份验证并创建匹配。但是this little nugget似乎暗示:

  

标准用户界面允许玩家发现附近的其他玩家,即使这两个玩家当前都没有直接连接到游戏中心。

此外,在Searching For Nearby Players中描述的流程中,在通过传递给startBrowsingForNearbyPlayersWithReachableHandler:的通知块找到玩家之后, 创建匹配请求。不幸的是,我从来没有这么远。

所以,问题:

1)我是否认为在认证本地玩家之前可以致电startBrowsingForNearbyPlayersWithReachableHandler:我是对的? GameKit不会抛出错误,所以我假设它没问题。这可能是一个轻率的假设。无论我是否认证,似乎都没有太大作用。

2)是否有人使用[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:成功实施了本地自动匹配?是否有好的示例代码可以说明完整的流程,从浏览播放器到开始匹配,都是以编程方式进行的?

3)网上似乎有关于是否可以在iOS模拟器中测试启用GameKit的应用程序的报告存在冲突。普遍的共识似乎没有,并且在iOS硬件上进行测试会更好。我一直在使用iPhone 4&第四代iPod Touch。对于那些已成功测试本地多人游戏的人来说,测试设置和测试设置是什么?您使用的是哪种方法?

3 个答案:

答案 0 :(得分:2)

  

1)我是否正确地认为我可以调用startBrowsingForNearbyPlayersWithReachableHandler:在验证本地播放器之前?

没有。 startBrowsingForNearbyPlayersWithReachableHandler通过宣传现有玩家和浏览其他玩家来工作,但最重要的是,用于识别玩家的信息是playerID ...在玩家进行身份验证之前不可用。

  

3)网上似乎有关于是否可以在iOS模拟器中测试启用GameKit的应用程序的报告存在冲突。普遍的共识似乎没有,并且最好在iOS硬件上进行测试

GameCenter身份验证,成就和排行榜在模拟器中工作,其他一切都应该在真实硬件上进行测试。我实际上推荐用于身份验证测试的模拟器,因为它避免了沙盒/生产开关,它可以在设备上进行详细的验证测试有点令人困惑。其他所有东西只能在设备上测试。模拟器不能很好地支持接收推送通知,这会打破匹配设置,并且通用硬件配置不同,无论如何都不太可能正常工作。

答案 1 :(得分:1)

您需要按此顺序执行以下操作:

  1. 验证本地播放器
  2. 安装邀请处理程序
  3. 开始浏览附近的玩家
  4. 需要身份验证 - 这会将您的应用程序注册到游戏中心并将玩家记录下来。在大多数情况下,您甚至不需要访问互联网来执行此操作。

    还需要安装邀请处理程序,我认为这是您缺少的步骤。这可让您的应用知道在收到入站邀请时该怎么做。如果您不这样做,设备将无法注册为附近。

    只有在完成上述两项操作后才开始浏览。

    这里有一些示例代码可以帮到您。在应用启动后调用此方法:

    - (void) authenticateLocalPlayer
    {
    
        static BOOL gcAuthenticationCalled = NO;
        if (!gcAuthenticationCalled) {
            GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
    
            void (^authenticationHandler)(UIViewController*, NSError*) = ^(UIViewController *viewController, NSError *error) {
                NSLog(@"Authenticating with Game Center.");
                GKLocalPlayer *myLocalPlayer = [GKLocalPlayer localPlayer];
                if (viewController != nil)
                {
                    NSLog(@"Not authenticated - storing view controller.");
                    self.authenticationController = viewController;
                }
                else if ([myLocalPlayer isAuthenticated])
                {
                    NSLog(@"Player is authenticated!");
    
                    //iOS8 - register as a listener
                    [localPlayer unregisterAllListeners];
                    [localPlayer registerListener:self];
    
                    [[GKLocalPlayer localPlayer] loadFriendPlayersWithCompletionHandler:^(NSArray *friendPlayers, NSError *error) {
    
                        //Do something with the friends
    
                    }];
    
                    //iOS7 - install an invitation handler
                    [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
                        // Insert game-specific code here to clean up any game in progress.
                        if (acceptedInvite)
                        {
                            //This player accepted an invitation.
                            //If doing programmatic matchmaking, call GKMatchmaker's matchForInvite:completionHandler 
                            //to get a match for the invite.  Otherwise you need to allocate a GKMatchmakerViewController 
                            //instance and present it with the invite.
    
                        }
                        else if (playersToInvite)
                        {
                            //Your game was launched from the GameCenter app to host a match.
                        }
                    };
    
                    //Now you can browse.  Note this is the iOS8 call.  The iOS7 call is slightly different.
                    [[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithHandler:^(GKPlayer *player, BOOL reachable) {
    
                        NSLog(@"Player Nearby: %@", player.playerID);
    
                    }];
    
    
    
                }
                else
                {
                    //Authentication failed.
                    self.authenticationController = nil;
                    if (error) {
                        NSLog([error description], nil);
                    }
                }
    
    
            };
    
            localPlayer.authenticateHandler = authenticationHandler;
            gcAuthenticationCalled = YES;
        }
    }
    

    *重要* 如果您使用的是iOS8,则无法安装邀请处理程序。您可以将对象注册为侦听协议GKLocalPlayerListener,并实现以下方法:

    -player:didAcceptInvite:
    -player:didRequestMatchWithRecipients:
    

    如果您未在iOS8上实施这些方法,它就无法工作!

    然后在验证本地播放器后通过调用此链接将GKMatchmaker链接到该对象:

    [localPlayer registerListener:self];
    

    确保在.h文件中声明实现协议的对象:

    @interface MyImplementingObject : NSObject <GKMatchDelegate, GKLocalPlayerListener>
    

    如果您执行了所有这些操作并且仍然无法正常工作,请确保您在应用中正确设置了套件ID(点击该应用,点击&#39;目标&#39;,确保捆绑标识符和版本填写),然后点击“功能”#39;选项卡(XCode 6),并确保游戏中心已启用。

    转到会员中心,确保使用该捆绑包ID的应用也为其配置文件启用了Game Center。如有必要,请下载并重新申请您的配置文件。

    确保GameCenter中的“设置”中的沙盒开关处于启用状态,并确保“允许邀请”#39;和附近的玩家&#39;开关打开。

    最后,请确保您转到iTunes Connect并确认您的应用也启用了Game Center。

答案 2 :(得分:1)

因此,请记住iOS7和iOS8之间的差异。此代码适用于任一版本,并依次调用'updateNearbyPlayer'。

if ( IS_IOS8 )
{
    [[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithHandler:^(GKPlayer *gkPlayer, BOOL reachable) 
     {
         NSLog(@"PLAYER ID %@ is %@",gkPlayer.playerID,reachable?@"reachable" : @"not reachable");
         [self updateNearbyPlayer:gkPlayer reachable:reachable];
     }];

} else {
    /*
     *  iOS 7...
     */
    [[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:^(NSString *playerID, BOOL reachable) 
     {
         NSLog(@"PLAYER ID %@ is %@",playerID,reachable?@"reachable" : @"not reachable");

         [GKPlayer loadPlayersForIdentifiers:@[playerID] withCompletionHandler:^(NSArray *players, NSError *error) {
             NSLog(@"Loaded: %@, error= %@",players,error);
             GKPlayer *gkPlayer = [players objectAtIndex:0];
             [self updateNearbyPlayer:gkPlayer reachable:reachable];
         }];
     }];
}

由于潜在的Bonjour服务有一些延迟,这种机制很有效。但是,需要通过适当的调用来平衡:

[[GKMatchmaker sharedMatchmaker] stopBrowsingForNearbyPlayers];

每当您使用其中一个报告的GKPlayers / PlayerID建立匹配项或将其添加到现有匹配项时,您应该停止浏览。比赛完成,关闭或取消后,再次开始浏览。否则,在第二次尝试连接到附近的设备时,您将失败。