Game Center Поиск совпадения программно

Я просто не могу понять, как это работает. То, что я пытаюсь сделать, это позволить двум игрокам играть в игру, если третий игрок присоединяется к нему, он может немедленно присоединиться к игре, если четвертый и последний игрок присоединяется, он также может мгновенно присоединиться к игре. Они также могут выйти из игры в любое время по любой причине, если это произойдет, должно быть место, открытое для другого человека или для того же человека, чтобы восстановить соединение. Это идея.

Теперь я получил следующее. Я аутентифицирую местного игрока по понятным причинам. Затем я ищу совпадение так:

if (matchRequest) [matchRequest release];
matchRequest            = [[GKMatchRequest alloc] init];
matchRequest.minPlayers = 2;
matchRequest.maxPlayers = 4;

[[GKMatchmaker sharedMatchmaker] findMatchForRequest:matchRequest withCompletionHandler:^(GKMatch *match, NSError *error) {
    if (error) {
        // An error occured
    } else {
        if (matchCurrent) [matchCurrent release];
        matchCurrent          = [match retain];
        matchCurrent.delegate = self;
    }
}];

Если я выполню эту часть на трех разных устройствах, два из них найдут друг друга, а третье все еще ищет. Поэтому я решил, что после поиска соответствия для запроса будет найдено минимальное количество игроков, которое будет выполнено один раз. Так что мне нужен был метод, который использовал matchCurrent, который я сохранил, чтобы добавить больше игроков. К счастью, этот метод существовал, но как он будет работать? Когда вы называете это в этом случае? Я решил поместить его под кнопку, чтобы вручную выполнить его, когда совпадение найдено.

Я обнаружил, что когда я нажал его на первом устройстве, наконец, третье устройство могло найти совпадение, в котором находились первое и второе устройства. Фактически, второе и третье устройства содержали идентификаторы игроков каждого задействованного устройства. Что хорошо. Но есть две проблемы.

  1. Какое устройство на самом деле должно вызывать метод addPlayersToMatch? И как вы можете ограничить это одним устройством, выполняющим этот метод? Плюс, когда ты должен это назвать?
  2. Почему на устройстве, вызывающем этот метод, не обновляются идентификаторы игроков?

    [[GKMatchmaker sharedMatchmaker] addPlayersToMatch:matchCurrent matchRequest:matchRequest completionHandler:^(NSError *error) {
        //matchCurrent.playerIDs is not updated?!
    }]; 
    

    На самом деле они обновляются. Когда я вижу, что идентификаторы playerID появляются на втором и третьем устройстве, я вручную обновляю matchCurrent.playerIDs на устройстве one, и внезапно он распознает игрока. Однако даже "didChangeState" для игрока не вызывается, когда новый игрок обнаружен на первом устройстве.

4 ответа

Вы используете Apple iOS Game Center GKMatchmaker класс. Я предполагаю, что вы используете одноранговое соединение, а не хостинг.

Класс GKMatch предоставляет вам массив playerIDs.

@property(nonatomic, readonly) NSArray *playerIDs

Это упорядоченный список, поэтому вы можете использовать его для выбора первого вызова игрока addPlayersToMatch.

Ниже приведена некоторая документация.

http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKMatchmaker_Ref/Reference/Reference.html

http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKMatch_Ref/Reference/Reference.html

http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/GameKit_Guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008304

Какое устройство на самом деле должно вызывать метод addPlayersToMatch? И как вы можете ограничить это одним устройством, выполняющим этот метод?

Вы можете решить эту проблему, если бы устройства "рисовали соломинки". Каждое устройство генерирует случайное число, а затем отправляет его другим. Устройство с наибольшим номером является лидером, и именно оно должно вызывать addPlayersToMatch. Если два устройства выбирают один и тот же номер, выбросьте цифры и начните все сначала.

Я бы посоветовал вам периодически (возможно, раз в секунду или два) опрашивать статус других игроков, чтобы вы могли определить, присоединился ли кто-либо или ушел по какой-либо причине. Если архитектура iphone, которую вы используете, уже предоставляет функцию, которая обрабатывает это событие.

Похоже, вы захотите найти дополнительную документацию и / или пример кода для многопользовательской среды, которую вы используете.

Я делаю это с Unity через GameCenterMultiplayerBinding Prime31 . Я не совсем уверен, как это соотносится с GameKit (документы скудны и не содержат этих деталей), но названия очень наводят на размышления.

Чтобы иметь возможность подбирать от 2 до 4 игроков в матче, я делаю:

      findMatchProgrammaticallyWithFilters(
                        minPlayers: 2,
                        maxPlayers: 4,
                        playerGroup: GetCurrentPlayerGroup(),
                        playerAttributes: 0);

Я предполагаю, что это соответствует findMatchForRequest:withCompletionHandler.

После этого я звоню:


Что, безусловно, соответствует finishMatchmakingForMatch. Я обнаружил, что вызов findMatchForRequest или addPlayersToMatch завершился ошибкой с сообщением «Запрошенная операция была отменена или отключена пользователем», если я не позвонил первым.

      addPlayersToCurrentMatchWithUpdatedMatchRequest(
                        minPlayers: 2,
                        maxPlayers: 4,
                        playerGroup: GetCurrentPlayerGroup(),
                        playerAttributes: 0,
                        playersToInvite: null);

addPlayersToMatch:matchRequest:completionHandler

После этого я звоню:

      finishMatchmakingForMatch();

Если у меня есть место для других игроков, я зацикливаюсь и снова звоню.

Я ожидал этого, так как мне нужно позвонить finishMatchmakingForMatch когда я закончу сватовство, стреляю findMatchProgrammaticallyбудет продолжать искать, пока не найдет maxPlayers, но это не так. Сдается после первого матча. Итак, нам нужно позвонить addPlayersToMatch.

Другие вопросы по тегам