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, который я сохранил, чтобы добавить больше игроков. К счастью, такой метод существует, но как он будет работать? Когда вы это называете в этом случае? Я решил поместить его под кнопку, чтобы я мог вручную запустить его, когда будет найдено совпадение.

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

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

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

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


person Mark    schedule 07.10.2010    source источник
comment
Это основано на модели сервер-клиент или модели p2p? Что используется для инициализации соединения, tcp, udp, http? Где хранятся данные о подключенных в данный момент игроках?   -  person Tom 'Blue' Piddock    schedule 09.11.2010
comment
Я пытаюсь позволить двум игрокам играть в игру, если к ним присоединяется третий игрок. Можете ли вы добавить точки с запятой и запятые во 2-е и 3-е предложения? Как бы то ни было, в дополнительных предложениях трудно сказать, изменяет ли каждое предложение if предыдущее или следующее независимое предложение.   -  person LarsH    schedule 12.11.2010


Ответы (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.

person Thomas Langston    schedule 17.11.2010

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

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

person benzado    schedule 14.11.2010

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

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

person Dronz    schedule 14.11.2010

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

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

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

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

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

finishMatchmakingForMatch();

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

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

addPlayersToMatch: matchRequest: completedHandler

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

finishMatchmakingForMatch();

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

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

person idbrii    schedule 11.07.2021