iPhone - многопользовательская онлайн-игра ... понимание механики - PullRequest
1 голос
/ 23 февраля 2012

Я занимаюсь разработкой многопользовательской онлайн-игры, но я борюсь с документацией Apple. (Я пробовал эти уроки Рэя Вендерлиха Часть 1 и Часть 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];

Окно будет доступно всем пользователям, которых я хочу пригласить. Предположим, что первый человек нажимает ПРИНЯТЬ на приглашение. Какой метод будет запущен в моем приложении, как я могу получить идентификационные данные пользователя и как я узнаю, что все пользователи приняли?

спасибо.

1 Ответ

4 голосов
/ 23 февраля 2012

Прежде всего, пожалуйста, имейте в виду, что приглашения в среде Песочницы, как правило, работают беспорядочно, поэтому я предлагаю вам начать с поиска игроками доступного совпадения.Код будет выглядеть примерно так:

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.Там есть метод, который будет вызываться для каждого игрока, который присоединяется к матчу, и для каждого игрока, который отсоединяется от него (с помощью этого метода вы можете узнать личность пользователя по его ID игрока):

- (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.

...