5

我正在尝试使用[[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:]. 本质上,我正在尝试实现无界面的本地比赛:只要我当地附近有玩家,我就想连接并开始比赛。重要的是,我只想为本地玩家这样做:我不想通过互联网自动匹配。

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

我已经尝试了匹配GKMatchmakerViewController(在验证本地玩家之后)和程序匹配startBrowsingForNearbyPlayersWithReachableHandler:,在 iPhone 4 和第四代 iPod Touch 上运行相同的代码。两者都找不到对方;使用GKMatchmakerViewController寻找附近玩家的界面时停留在

寻找玩家...

spinner,并且在使用时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)。然而,这个小金块似乎另有暗示:

标准用户界面允许玩家发现附近的其他玩家,即使当前没有玩家直接连接到 Game Center。

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

所以,问题:

1)我认为我可以startBrowsingForNearbyPlayersWithReachableHandler:在验证本地播放器之前打电话是对的吗?GameKit 不会抛出错误,所以我假设它没问题。这可能是一个轻率的假设。我是否进行身份验证似乎没有太大区别。

2) 有没有人使用成功实现本地自动匹配[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:?任何地方都有很好的示例代码来说明完整的流程,从浏览玩家到开始比赛,所有这些都是以编程方式进行的吗?

3) 关于是否可以在 iOS 模拟器中测试支持 GameKit 的应用程序,网络上似乎存在相互矛盾的报道。普遍的共识似乎没有,最好在 iOS 硬件上进行测试。我一直在使用 iPhone 4 和第四代 iPod Touch。对于那些成功测试过本地多人游戏的人,您使用了哪些测试设置和方法?

4

3 回答 3

2

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

不可以 通过startBrowsingForNearbyPlayersWithReachableHandler为现有播放器做广告和浏览其他播放器来工作,但最重要的是,它用来识别播放器的信息是playerID......直到播放器验证后才能使用。

3) 关于是否可以在 iOS 模拟器中测试支持 GameKit 的应用程序,网络上似乎存在相互矛盾的报道。普遍共识似乎没有,最好在iOS硬件上测试

GameCenter 身份验证、成就和排行榜在模拟器中工作,其他一切都应在真实硬件上进行测试。我实际上推荐使用模拟器进行身份验证测试,因为它避免了沙盒/生产切换,这会使设备上的详细身份验证测试有些混乱。其他一切只能在设备上进行测试。模拟器对接收推送通知没有很好的支持,这会破坏匹配设置,并且一般硬件配置足够不同,以至于匹配通信不太可能正常工作。

于 2014-06-25T22:53:16.170 回答
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 来建立比赛或将其添加到现有比赛中时,您应该停止浏览。比赛结束、关闭或取消后,重新开始浏览。否则,在第二次尝试连接到附近的设备时,您将失败。

于 2014-10-09T21:31:45.093 回答
1

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

  1. 验证本地播放器
  2. 安装邀请处理程序
  3. 开始浏览附近的玩家

需要身份验证 - 这会将您的应用程序注册到 Game Center 并让玩家登录。在大多数情况下,您甚至不需要互联网访问来执行此操作。

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

完成上述两项后才开始浏览。

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

- (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(点击应用,点击“目标”,确保填写捆绑标识符和版本),然后点击“功能”选项卡(XCode 6),并确保游戏中心已打开。

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

确保在 GameCenter 下的设置中打开沙盒开关,并确保打开“允许邀请”和“附近玩家”开关。

最后,确保您转到 iTunes Connect 并验证那里的应用程序也启用了 Game Center。

于 2014-10-07T04:26:59.417 回答