Некоторые начальные вопросы по теме NearbyPlayersWithReachableHandler
Я пытаюсь заставить местных сватов работать в GameKit, используя [[GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:]
, По сути, я пытаюсь реализовать локальные совпадения без интерфейса: пока в моей локальной сети есть игрок, я хочу подключиться и начать матч. Важно отметить, что я хочу делать это только для местных игроков: я никогда не хочу автоматически сравнивать их по Интернету.
Я включил Game Center для своего приложения в iTunes connect и зарегистрировался для каждой учетной записи песочницы на каждом устройстве, которое я использую для тестирования.
Я пробовал оба сватовства с GKMatchmakerViewController
(после проверки подлинности локального игрока) и программного поиска startBrowsingForNearbyPlayersWithReachableHandler:
запускаю один и тот же код на iPhone 4 и iPod Touch 4-го поколения, сидящих рядом на моем столе. Никто никогда не находит другого; когда используешь 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 );
} ];
}
Документы немного скудны и запутаны по этому вопросу, особенно когда речь идет о разнице между локальным мультиплеером и матчами через Интернет. Например, кажется необходимым проверить подлинность локального игрока и создать матч, прежде чем найти игроков, которые присоединятся к этому матчу ( создание любого вида матча начинается с запроса на матч). Однако этот маленький самородок, кажется, подсказывает обратное:
Стандартный пользовательский интерфейс позволяет игрокам находить других соседних игроков, даже если в данный момент ни один из игроков не подключен к Game Center напрямую.
Кроме того, в последовательности, описанной в разделе Поиск ближайших игроков, запрос на совпадение не создается до шага 3, после поиска игроков через блок уведомлений, переданный в startBrowsingForNearbyPlayersWithReachableHandler:
, К сожалению, я никогда не заходил так далеко.
Итак, вопросы:
1) Правильно ли я думаю, что могу позвонить startBrowsingForNearbyPlayersWithReachableHandler:
перед аутентификацией местного игрока? GameKit не выдает ошибку, поэтому я предполагаю, что все в порядке. Это может быть опрометчивым предположением. Похоже, аутентифицирую я или нет, не имеет большого значения.
2) Кто-нибудь успешно реализовал локальное автоматическое сопоставление, используя [GKMatchmaker sharedMatchmaker] startBrowsingForNearbyPlayersWithReachableHandler:
? Есть ли хороший пример кода где-нибудь, который иллюстрирует весь процесс, от просмотра игроков до начала матча, все программно?
3) В Интернете появляются противоречивые сообщения о том, можно ли тестировать приложения с поддержкой GameKit в симуляторе iOS. Общепринятого мнения нет, и лучше тестировать на оборудовании iOS. Я использую iPhone 4 и iPod Touch 4-го поколения. Для тех, кто успешно протестировал локальный мультиплеер, какую настройку и методику тестирования вы использовали?
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>
Если вы делаете все это, и это все еще не работает, убедитесь, что у вас правильно установлен идентификатор пакета в вашем приложении (нажмите приложение, нажмите "Цели", убедитесь, что идентификатор пакета и версия заполнены), затем нажмите Закладка "Возможности" (XCode 6) и убедитесь, что Game Center включен.
Перейдите в Центр участников и убедитесь, что в приложении, использующем этот идентификатор пакета, также включен Game Center для его профиля обеспечения. При необходимости загрузите и повторно примените ваш профиль обеспечения.
Убедитесь, что переключатель "Песочница" включен в настройках GameCenter, а также убедитесь, что переключатели "Разрешить приглашения" и "Ближайшие игроки" включены.
Наконец, убедитесь, что вы идете в iTunes Connect и убедитесь, что Game Center также включен для вашего приложения.
1) Правильно ли я думаю, что могу вызвать startBrowsingForNearbyPlayersWithReachableHandler: до аутентификации локального проигрывателя?
Нет. startBrowsingForNearbyPlayersWithReachableHandler
работает как за счет рекламы существующего игрока, так и за просмотром других игроков, но, самое главное, информация, которую он использует для идентификации игроков, является playerID
... который не будет доступен, пока игрок не аутентифицируется.
3) В Интернете появляются противоречивые сообщения о том, можно ли тестировать приложения с поддержкой GameKit в симуляторе iOS. Достигнуто общее согласие, и лучше тестировать на оборудовании iOS
В симуляторе работают аутентификация GameCenter, достижения и списки лидеров, все остальное нужно тестировать на реальном оборудовании. Я на самом деле рекомендую симулятор для проверки подлинности, так как он избегает переключателя "песочница" / "производство", что может несколько усложнить детальное тестирование аутентификации на устройствах. Все остальное можно проверить только на устройствах. Симулятор не имеет большой поддержки для получения push-уведомлений, что нарушает настройку соответствия, и общая конфигурация оборудования достаточно различна, так что обмен данными по совпадению вряд ли будет работать в любом случае.
Итак, имейте в виду различия между 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/Player, чтобы установить совпадение или добавить его к существующему совпадению, вы должны прекратить просмотр. Как только матч будет завершен, закрыт или отменен, начните просмотр снова. В противном случае при второй попытке подключения к ближайшему устройству у вас не получится.