Основанные на повороте соответствия

В основанном на повороте соответствии плееры соответствия не должны быть одновременно подключены к Игровому Центру, чтобы сыграть матч вместе. Вместо этого игра использует подход промежуточной буферизации; один проигрыватель принимает оборот прежде, чем передать следующую игру другому проигрывателю. Проигрыватели продолжают сменяться до концов соответствия только с одним проигрывателем, который в состоянии вносить изменения в игру за один раз.

Основанные на повороте соответствия имеют много полезных характеристик, делающих их великими для реализации настольных игр и других подобных стилей игр; например:

В iOS 7 обмены представлены основанным на повороте соответствиям. Обмены позволяют двум или больше проигрывателям принимать меры, даже когда это не их очередь. Это позволяет разработчикам создавать более сложные и разнообразные основанные на повороте игры, чем в настоящее время возможны, позволяя больше, чем просто местный игрок внести изменения в игру. Некоторые возможные применения для обменов:

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

Когда Вы реализуете основанные на повороте соответствия в своей игре, списке проигрывателей, данных для соответствий, и другие подробные данные все сохранены на Игровом Центре. Ваша игра загружает эту информацию по мере необходимости. Игровой Центр прежде всего ответственен за то, что хранил данные. Вы ответственны за обеспечение игровой логики, использующей эту инфраструктуру. В частности Вы определяете:

Контрольный список для реализации основанного на повороте соответствия

Для добавления основанной на повороте поддержки игре Вы пишете код для обработки следующих действий:

Каждое соответствие имеет список участников

Думайте об основанном на повороте соответствии на Игровом Центре как настольная игра посреди таблицы. Вокруг таблицы пустые места, ожидая, чтобы быть заполненным потенциальными проигрывателями. Когда соответствие сначала создается и никогда не изменяется, число игроков установлено.

Когда матч начинается, только некоторые места могут быть заполнены проигрывателями. Другие места могут быть забронированы для определенных проигрывателей или быть заполненными Игровым Центром соответствие службы. Например, рассмотрите рисунок 10-1. Мэри создала новое соответствие с четырьмя местами. Поскольку Мэри создала соответствие, она выполняет первый поворот, и затем играйте передачи в другой проигрыватель.

Рисунок 10-1  Мэри начинает новый матч

В этой точке Игровой Центр видит, что этому соответствию нужен новый проигрыватель для продолжения игры. Когда Боб ищет соответствие, Игровой Центр видит, что Боб хочет играть в ту же игру, как Женятся, и присваивает Боба в качестве нового игрока соответствия Мэри. Поскольку эта игра ожидала на новом проигрывателе для продолжения соответствия, это - теперь очередь Боба.

../Art/match_and_fill-3_2x.png

Игровой Центр всегда отслеживает игроков соответствия в определенном порядке. Тот порядок никогда не изменяется на время соответствия, независимо от которого устройства работает Ваша игра. В этом примере, если Мэри находится на первом месте (слот), она остается на первом месте для всей игры.

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

Данные соответствия представляют состояние соответствия

Ваша игра отправляет к Игровым данным соответствия Центра, описывающим состояние соответствия. Игровой Центр устанавливает предел для размера этих данных соответствия, но иначе не заботится о его содержании. Ваша игра должна хранить любые данные, необходимо для сохранения состояния соответствия.

В любое время проигрыватель в соответствии может запустить Вашу игру для просмотра соответствия. Когда проигрыватель запускает игру, Ваша игра загружает данные соответствия, интерпретирует их и выводит на экран их к проигрывателю.

Рисунок 10-2  текущий проигрыватель хочет просмотреть соответствие

Только текущему проигрывателю позволяют изменить данные соответствия. Предоставьте текущему проигрывателю пользовательский интерфейс, позволяющий им принимать меры в игре. Поскольку проигрыватель принимает меры, Ваша игра обновляет данные соответствия и передает их назад в Игровой Центр.

../Art/store_and_forward-3_2x.png

Ваша игра решает правила игры

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

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

Правила, что шахматное использование для проигрывателей является очень непротиворечивым, но Игровой Центр позволяет Вам разрабатывать более гибкие игры. Например, каждый раз, когда проигрыватель принимает оборот, можно показать им различный экран интерфейса пользователя и подарить проигрывателю различные варианты для игры. Очередь проигрывателя может быть столь же простой столь же принятие единственного решения или столь же сложной как выбор, что создать, решение, куда отправить ресурсы и участвование в военных действиях с другим проигрывателем. Ваша игра отслеживает перемещения, которые проигрыватель делает и перемещения, которые им позволяют сделать как часть Ваших данных соответствия.

Рассмотрите другой популярный стиль стратегической игры: 4X игра, призывающая проигрыватели исследовать, разворачивает, использует и истребляет. В этом стиле игры многократные типы поворотов используются в различных точках в соответствии. Вот один возможный способ организовать это:

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

Рисунок 10-3  блок-схема поворота для гипотетического 4X игра

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

Сохраните данные соответствия каждый раз, когда важные события имеют место

Устройство текущего проигрывателя может сохранить данные к Игровому Центру сразу каждый раз, когда любые меры приняты, не передавая управление другому проигрывателю. Необходимо сохранить данные соответствия каждый раз, когда происходит что-либо интересное. Рассмотрите следующий список как критические места, куда данные должны быть отправлены Игровому Центру:

Реализация основанного на повороте соответствия Используя игровой набор

Для реализации основанной на повороте поддержки в игре Вы используете классы, перечисленные в Таблице 10-1.

Табличные 10-1  Классы в Гэйме Ките раньше реализовывали основанную на повороте поддержку соответствия

Имя класса

Функция класса

GKTurnBasedMatch

Описывает основанное на повороте соответствие, сохраненное на Игровом Центре. Когда текущий проигрыватель принимает оборот, Вы используете этот объект проверить текущее состояние соответствия и обновить состояние соответствия.

GKMatchRequest

Описывает характеристики соответствия и может включать первоначальный список проигрывателей для приглашения.

GKTurnBasedParticipant

Описывает проигрыватель в соответствии. Большинство его свойств только для чтения, но matchOutcome свойство не; когда проигрыватель оставляет соответствие, Вы присваиваете результат этому свойству.

GKTurnBasedMatchmakerViewController

Обеспечивает стандартный пользовательский интерфейс, позволяющий местному игроку создавать новые соответствия или просматривать существующие соответствия.

GKTurnBasedEventHandler

События дескрипторов, когда проигрыватель получает приглашение присоединиться к соответствию или уведомлению, что было обновлено существующее соответствие. Существует единственный объект обработчика событий, предоставленный Вам Гэймом Китом. После того, как проигрыватель аутентифицируется, Вы присваиваете обработчик событий этому одноэлементному объекту. Точные события, поставленные Вашей игре, варьируются в зависимости от того, является ли Ваша игра в настоящее время приоритетным приложением на устройстве. Когда Ваша игра находится на переднем плане, она получает все события, связанные с основанными на повороте соответствиями. Не работая на переднем плане, Ваша игра запущена или принесена к переднему плану только, когда получены важные события.

Игровой центр налагает пределы на соответствие

Таблица 10-2 описывает два из важных пределов, которые необходимо рассмотреть при разработке игры. Эти пределы подвержены изменениям и могут оба быть запрошены во время выполнения.

Таблица 10-2  Важные пределы соответствия

Элемент

Предел

Доступ во время выполнения

Число игроков

16

Вызовите maxPlayersAllowedForMatchOfType: метод класса GKMatchRequest класс.

Размер данных соответствия

64k

Читайте matchDataMaximumSize свойство GKTurnBasedMatch объект.

Присоединение к новому соответствию

Когда проигрыватель присоединяется к соответствию, для проигрывателей начинается новый матч. Как с другими формами matchmaking, Ваша игра запускает процесс путем создания a GKMatchRequest объект, как описано в Создании Любого Вида Соответствия Запускается с Запроса Соответствия. Запрос соответствия не гарантирует, что новое соответствие будет создаваемым; это может также соответствовать проигрыватель в существующее соответствие, имеющее пустую позицию как текущий проигрыватель.

Можно принять решение вывести на экран стандартный пользовательский интерфейс, предоставленный Игровым Центром или реализовать собственный пользовательский интерфейс. Независимо от которого метода Вы используете, соответствие возвратилось к Вашей игре, всегда имеет местного игрока, поскольку текущий проигрыватель ожидал принимать оборот.

Показ стандартного пользовательского интерфейса Matchmaking

Вы используете a GKTurnBasedMatchmakerViewController возразите для отображения стандартного пользовательского интерфейса. Перечисление 10-1 показывает типичную реализацию.

Перечисление 10-1  , Выводящее на экран стандартный интерфейс для присоединения к основанному на повороте соответствию

- (IBAction)joinChessMatch: (id) sender
{
    GKMatchRequest *request = [[GKMatchRequest alloc] init];
    request.minPlayers = 2;
    request.maxPlayers = 2;
 
    GKTurnBasedMatchmakerViewController *mmvc = [[GKTurnBasedMatchmakerViewController alloc] initWithMatchRequest:request];
    mmvc.turnBasedMatchmakerDelegate = self;
 
    [self presentViewController:mmvc animated:YES completion:nil];
}

Контроллер представления представления в этом примере реализует GKTurnBasedMatchmakerViewControllerDelegate образец. Для matchmaking необходимо обработать три из методов протокола.

turnBasedMatchmakerViewControllerWasCancelled: когда проигрыватель отклоняет экран matchmaking путем ответвления Кнопки отмены, метод делегата вызывают. В большинстве случаев необходимо просто возвратиться к предыдущему экрану в игре. Минимальная версия этого кода может быть найдена в Перечислении 10-2.

Перечисление 10-2  Реализовывая метод отмены

- (void)turnBasedMatchmakerViewControllerWasCancelled:(GKTurnBasedMatchmakerViewController *)viewController
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

turnBasedMatchmakerViewController:didFailWithError: когда matchmaking встречается с ошибкой при попытке найти соответствие, метод делегата вызывают. Например, устройство, возможно, потеряло свое сетевое соединение. Ваша реализация должна также возвратиться к предыдущему экрану Вашей игры. Минимальная версия этого кода может быть найдена в Перечислении 10-3.

Перечисление 10-3  Реализовывая метод обработки ошибок

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFailWithError:(NSError *)error
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

Наконец, turnBasedMatchmakerViewController:didFindMatch: когда соответствие было найдено или создано, метод вызывают. Объект соответствия возвращается Вашему делегату. Как правило, Ваша игра отклоняет контроллер представления антрепренера и сразу запускает его собственный пользовательский интерфейс, чтобы позволить проигрывателю играть поворот. Реализация в Перечислении 10-4 использует пользовательский переход для показа экрана геймплея. Соответствие передается как отправитель так, чтобы это могло быть передано как ввод новому контроллеру представления.

Перечисление 10-4  Реализовывая соответствие нашло метод

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFindMatch:(GKTurnBasedMatch *)match
{
    [self dismissViewControllerAnimated:YES completion:nil];
    [self performSegueWithIdentifier:@"GamePlayScene" sender:match];
}
 
- (void )prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"GamePlayScene"])
    {
        MyGamePlayViewController* gameVC = (MyGamePlayViewController*) segue.destinationViewController;
        gameVC.delegate = self;
        gameVC.match = (GKTurnBasedMatch*) sender;
    }
}

Реализация пользовательского интерфейса соответствия

Для создания собственного интерфейса соответствия Вы обычно используете методы на GKTurnBasedMatch класс. Перечисление 10-5 показывает тривиальную реализацию этого метода. Это создает новый запрос соответствия и затем использует его для нахождения нового соответствия. (Как правило, если бы Ваша игра реализовывала пользовательский интерфейс соответствия, то она могла бы установить другие свойства объекта запроса, такой как playersToInvite свойство.), Если соответствие найдено, оно переходит на экран геймплея.

Перечисление 10-5  , Находящее основанное на повороте соответствие программно

- (IBAction)findProgrammaticMatch: (id) sender
{
    GKMatchRequest *request = [[GKMatchRequest alloc] init];
    request.minPlayers = 4;
    request.maxPlayers = 16;
    [GKTurnBasedMatch findMatchForRequest: request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
    {
        if (match)
            [self performSegueWithIdentifier:@"GamePlayScene" sender:match];
    }];
}

Один общий сценарий поддерживается автоматически Игровым Центром. Когда матч заканчивается, можно вызвать rematchWithCompletionHandler: метод экземпляра создать новое соответствие с теми же участниками.

Обработка приглашений программно

Если запрос соответствия включает список проигрывателей для приглашения, то те проигрыватели добавляются к списку проигрывателей в недавно создаваемом соответствии. Однако приглашения фактически не поставлены, пока один из тех проигрывателей не становится текущим проигрывателем. Когда это происходит, уведомление нажатия отправляется в проигрыватель. Процесс для обработки уведомлений описан позже в Ответе на Уведомления Соответствия. На данный момент все, что необходимо знать, - то, что можно вывести на экран собственный интерфейс, позволяющий проигрывателю принимать или отклонять приглашение соответствия. Вы вызываете объект соответствия acceptInviteWithCompletionHandler: метод для принятия приглашения или declineInviteWithCompletionHandler: метод для отклонения приглашения.

Работа с существующими соответствиями

Если Вы выводите на экран стандарт matchmaking пользовательский интерфейс, то проигрыватель видит существующие соответствия также. Проигрыватель может выбрать существующее соответствие, уже происходящее, и выполнить другие общие задачи. Если проигрыватель выбирает существующее соответствие, turnBasedMatchmakerViewController:didFindMatch: метод вызывают, точно как его вызвали, когда создавалось новое соответствие. Обратите внимание на то, что в этом случае проигрыватель может не быть текущим проигрывателем.

Проигрыватель может принять решение уйти из соответствия из стандартного пользовательского интерфейса. Ваш делегат должен реализовать a turnBasedMatchmakerViewController:playerQuitForMatch: метод для обработки отставки проигрывателя. Ваша игра должна установить результат соответствия для проигрывателя отставки, и, если необходимо, выбрать другой проигрыватель для действия в соответствии. Для получения дополнительной информации посмотрите Установку Результата Соответствия Когда Участник Листы Соответствие.

При реализации пользовательского matchmaking пользовательского интерфейса необходимо обеспечить эквивалентную функциональность, позволяющую проигрывателю управлять списком соответствий. Перечисление 10-6 показывает, как получить список соответствий, в которых участвует местный игрок.

Перечисление 10-6  , Получающее список соответствий местный игрок, участвует в

- (void) loadMatches
{
    [GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error) {
      if (matches)
          {
// Use the match data to populate your user interface.
          }
     }];
}

Таблица 10-3 перечисляет наиболее распространенные действия, которые проигрыватель мог бы хотеть выполнить на соответствии.

Таблица 10-3  Общие действия для выполнения на соответствии

Действие

Реализация

Просмотрите соответствие

Представьте свой пользовательский интерфейс геймплея, с помощью объекта соответствия в качестве ввода. См. Перечисление 10-4 для вдохновения о том, как реализовать это.

Удалите завершенное соответствие

Вызовите объект соответствия removeWithCompletionHandler: метод.

Уйдите из соответствия

Установите результат проигрывателя и затем вызовите метод для ухода из соответствия. Посмотрите Установку Результата Соответствия Когда Участник Листы Соответствие.

Конец, достойный всех участников

Результаты набора для всех проигрывателей и затем вызывают соответствие endMatchInTurnWithMatchData:completionHandler: метод. Посмотрите Заканчивание Матча.

Создайте матч - реванш

Вызовите rematchWithCompletionHandler: метод на законченном матче.

Получение информации о соответствии

Когда проигрыватель решает просмотреть соответствие, Ваша игра читает свойства соответствия для определения текущего состояния соответствия. Таблица 10-4 перечисляет наиболее распространенные свойства, к которым необходимо получить доступ.

  Свойства Table 10-4 Important объекта соответствия

Свойство

Описание

matchID

Строка, однозначно определяющая соответствие. Если Вы хотите хранить специфичные для соответствия данные в другом месте, используйте эту строку в качестве ключа. Ваша игра могла также сохранить этот ID и использовать его позже для загрузки этого определенного соответствия. Для загрузки определенного соответствия вызовите loadMatchWithID:withCompletionHandler: метод класса.

состояние

Состояния, происходит ли соответствие все еще.

сообщение

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

участники

Массив GKTurnBasedParticipant объекты. Объекты в массиве всегда хранятся в том же порядке. Вы читаете свойства участвующих объектов создать Ваш пользовательский интерфейс. Эти объекты также используются в качестве вводов к определенным методам на объекте соответствия. Таблица 10-5 перечисляет наиболее распространенные свойства, используемые для реализации игры.

currentParticipant

Участвующий объект для следующего проигрывателя ожидал действовать в соответствии. Этот объект всегда является одним из объектов, хранивших в participants массив.

Таблица 10-5 перечисляет наиболее распространенные участвующие свойства, используемые для реализации игры.

  Свойства Table 10-5 Important участвующего объекта

Свойство

Описание

playerID

Идентификатор проигрывателя для проигрывателя, принимая это место заполнен. Используйте его для загрузки имен дисплея и фотографий для проигрывателя.

состояние

Объявляет, заполнено ли это место и, если это, объявляет, активен ли проигрыватель все еще в соответствии.

timeoutDate

Время, в которое проигрыватель должен действовать прежде, чем утратить поворот. Ваша игра решает то, что происходит, когда утрачен поворот. Для некоторых игр утраченный поворот мог бы закончить матч. Для других игр Вы могли бы выбрать разумный набор действий по умолчанию для проигрывателя, или просто ничего не сделать.

matchOutcome

Когда проигрыватель оставляет соответствие, это свойство описывает то, что произошло с проигрывателем. Проигрыватель, возможно, выиграл или проиграл матч.

Работа с данными соответствия

Когда соответствие сначала создается, данные соответствия пусты. Но как только матч начинается, и проигрыватели начинают сменяться, Ваша игра, как ожидают, предоставит данные соответствия, которые целесообразны для Вашей игры. Данные соответствия NSData возразите и его размер ограничивается, таким образом, необходимо быть творческими и закодировать данные игры так, чтобы они заполнили как можно меньше пространство.

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

  • Закодируйте только действия проигрывателя: В этом проекте Ваши данные соответствия просто состоят из перемещений, сделанных проигрывателями. Например, в шахматах, Вы знаете, что белые движения сначала, перемещения всегда чередуются, и часть перемещается от одной позиции платы до другого. Это упрощает для Вас кодировать каждое перемещение запуском и конечной позицией передвинутой фигуры. Остальная часть данных (кто сделал перемещения) может быть полностью выведена. Когда Ваша игра загружает данные соответствия, она быстро воспроизводит перемещения для генерации текущей позиции платы.

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

  • Закодируйте только текущее состояние соответствия: Для очень сложных игр реальное положение, требуемое закодировать игру, могло быть очень большим. В этом случае Вы, возможно, должны закодировать текущее состояние соответствия, не волнуясь о действиях, генерировавших те данные соответствия. Это - особенно истина для очень сложных игр, где список перемещений мог бы стать слишком большим для помещений в доступное пространство памяти.

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

  • Закодируйте текущее состояние соответствия и ряда недавних действий проигрывателя: Это - гибридная стратегия, занимающая элементы из других двух стратегий. По существу данные соответствия, хранившие на Игровом Центре, состоят из недавнего снимка соответствия плюс другие данные, кодирующие недавние действия, так как был взят тот последний снимок. Когда данные, записывающие действия, становятся слишком большими, Ваша игра воспроизводит некоторые из тех перемещений для обновления снимка соответствия и затем удаляет те перемещения из его списка действий.

    С этой стратегией обычно необходимо определять, какие действия текущий проигрыватель видел (на основе того, когда они в последний раз приняли оборот). Когда Ваша игра сглаживает данные соответствия, она никогда не удаляет данных, не замеченных всеми участниками. Это позволяет всем участникам видеть перемещения, которые сделали их противники.

И вот некоторые другие общие руководящие принципы:

  • Избегайте использования NSCoder класс за исключением самой тривиальной из игр. Несмотря на то, что полезный для приложений общего назначения, NSCoder класс может не заархивировать данные в достаточно компактном формате для Вашей игры. Вы не можете точно предсказать размер архива, который он производит. Вместо этого Вы выделяете свой собственный блок памяти и выполняете Вашу собственную сериализацию данных.

  • Закодируйте отдельные элементы как сжато по мере необходимости. Например, в игре с 16 проигрывателями, можно закодировать участвующее число проигрывателя в 4 битах. Сбалансируйте потребность в компактности с потребностью в удобочитаемости в Вашем коде. Например, шахматная позиция могла быть закодирована во всего 6 битах, но на практике шахматная партия не приближается к пределу данных соответствия.

  • Если Ваши игровые выполнения и в OS X и в iOS, используйте методы кодирования сетевых данных для предотвращения проблем порядка байтов.

Загрузка данных соответствия

Когда необходимо загрузить данные соответствия, Вы вызываете объект соответствия loadMatchDataWithCompletionHandler: метод для получения данных соответствия. Когда обработчик завершения вызывают, Вы получаете данные соответствия. После того, как работа завершается, объект соответствия matchData свойство также обновляется для указания на тот же объект данных.

Перечисление 10-7  , Загружающее данные соответствия из Игрового Центра

- (void) loadAndDisplayMatchData
{
    [this.myMatch loadMatchDataWithCompletionhandler: ^(NSData *matchData, NSError *error) {
        if (matchData)
        {
// App-specific routine to decode the match data.
            this.gameData = [MyMatchDataClass initWithData: matchData];
            // Display the match.
        }
      }];
}

Сохранение данных соответствия

Если проигрыватель принимает меры, которые являются безотзывными (но управление еще не передается к другому проигрывателю), закодируйте обновленные данные соответствия и отправьте их Игровому Центру путем вызова saveCurrentTurnWithMatchData:completionHandler: метод.

Перечисление 10-8  , Сохраняющее данные соответствия к Игровому Центру

- (void) updateMatchData
{
// App-specific routine to encode the match data.
    NSData *updatedMatchData = [this.gameData encodeMatchData];
    [this.myMatch saveCurrentTurnWithMatchData: updatedMatchData completionHandler ^(NSError *error) {
        if (error)
        {
            // Handle the error.
        }
      }];
}

Усовершенствование состояния соответствия

В конечном счете текущий проигрыватель принимает меры, или заканчивающие матч или требующие, чтобы действовал другой участник. Как правило, Ваша игра обновляет message свойство объекта соответствия, кодирует данные соответствия и определяет, кто действует затем в соответствии. Обычно, это означает кодировать список всех участников соответствия в порядке, они будут действовать затем. Причина Вы делаете это, состоит в том, что иногда проигрыватели отбрасывают от соответствия без утраты; они просто прекращают играть. Вы не хотите, чтобы соответствие закончилось, потому что оно застревает, ожидая навсегда отсутствующего проигрывателя. Вместо этого Вы кодируете список участников так, чтобы, если один участник утрачивает поворот, усовершенствования соответствия другому участнику.

Перечисление 10-9 показывает типичную структуру для этого кода, задерживая некоторые определенные шаги к специфичным для приложения подпрограммам, основывающимся на фактической структуре Вашей игры. Те методы представляют места, где необходимо обеспечить определенные реализации в игре. advanceTurn метод сначала устанавливает новое сообщение, затем кодирует текущие данные соответствия как прежде. Наконец, это вычисляет порядок, в котором участники должны действовать и вызывают endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: метод для фактической передачи управления к тому списку проигрывателей.

Перечисление 10-9  , Совершенствующееся следующему участнику соответствия

- (void) advanceTurn
{
    NSData *updatedMatchData = [this.gameData encodeMatchData];
    NSArray *sortedPlayerOrder = [this.gameData encodePlayerOrder];
    this.MyMatch.message = [this.gameData matchAppropriateMessage];
    [this.myMatch endTurnWithNextParticipants: sortedPlayerOrder turnTimeOut: GKTurnTimeoutDefault
                  matchData: updatedMatchData completionHandler ^(NSError *error) {
        if (error)
        {
            // Handle the error.
        }
      }];
}

Установка результата соответствия, когда участник оставляет соответствие

В то время как соответствие развивается, участники могут оставить соответствие. Например, Ваша игровая логика могла бы решить, что участник был устранен из соответствия.

Если местный игрок уходит из соответствия и является также текущим проигрывателем соответствия, Ваша игра должна вызвать объект соответствия participantQuitInTurnWithOutcome:nextParticipants:turnTimeout:matchData:completionHandler: метод. Этот метод подобен endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: метод в этом это дает контроль другому участнику. Из-за этого Вы обязаны обновлять данные соответствия и обеспечивать участвующий список. Однако Ваша игра также обеспечивает результат соответствия для проигрывателя, просто вышедшего из соответствия — по существу, численное значение, указывающее, почему тот проигрыватель оставил соответствие. Участвующий объект для того проигрывателя обновляется для включения этого нового состояния соответствия. Как только участник вышел из соответствия, Ваша игра может не сделать тот проигрыватель текущим проигрывателем.

Игровой Набор обеспечивает некоторые стандартные значения, которые можно использовать для установки результата соответствия. Посмотрите Установку Результата Соответствия.

Например, на рисунке 10-4, Боб был просто устранен из соответствия. Игра принимает решение установить результат GKTurnBasedMatchOutcomeFourth и сделайте Мэри новым текущим проигрывателем. Боб может все еще просмотреть соответствие, но может не принять меры.

Рисунок 10-4  Боб был устранен из соответствия

Иногда проигрыватель может оставить игру, когда они не текущий проигрыватель. Для обработки этого игра вызывает объект соответствия participantQuitOutOfTurnWithOutcome:withCompletionHandler: метод. Вы обеспечиваете результат соответствия, но не предоставляете новые данные соответствия или участвующий список.

Заканчивание матча

В конечном счете Ваша игровая логика собирается решить, что соответствие закончено. У всех участников соответствия должен быть допустимый результат соответствия прежде, чем закончить матч. Ваша игра вызывает объект соответствия endMatchInTurnWithMatchData:completionHandler: метод для формального заканчивания матча. Этот метод подобен другим методам, обновляющим состояние соответствия, но в этом случае Вы не обеспечиваете список участников, потому что никакие дальнейшие действия не позволяются в этом соответствии. Вы действительно обновляете сохраненные данные соответствия, чтобы описать, как закончился матч. Проигрыватели могут все еще выбрать это соответствие из matchmaking пользовательского интерфейса; Ваша игра должна вывести на экран окончание соответствия, но не позволить проигрывателю принимать меры.

../Art/set_match-2_2x.png

Ответ на уведомления соответствия

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

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

- (void) installTurnBasedEventHandler
{
    [GKTurnBasedEventHandler sharedTurnBasedEventHandler].delegate = self;
}

Для ответа на события обработчик событий реализует методы, определенные GKTurnBasedEventHandlerDelegate протокол. Таблица 10-6 перечисляет события. События, полученные через уведомление нажатия, запускают Вашу игру или приносят Вашу игру к переднему плану (если необходимый), и тогда поставлены игре. Приоритетные события поставлены, только если Ваша игра работала на переднем плане, когда было получено событие.

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

Таблица 10-6  Основанные на повороте методы обработчика событий

Событие

Тип события

Метод обработчика событий

Проигрыватель получает приглашение

Продвинуть

handleInviteFromGameCenter:

Это становится очередью проигрывателя

Продвинуть

handleTurnEventForMatch:didBecomeActive:

Матч закончился

Продвинуть

handleMatchEnded:

Это становится чьим-либо поворотом

Передний план

handleTurnEventForMatch:didBecomeActive:

Проигрыватель обновил данные соответствия

Передний план

handleTurnEventForMatch:didBecomeActive:

Проигрыватель получает обменный запрос

Продвинуть

player:receivedExchangeRequest:forMatch:

Проигрыватель отменяет обменный запрос

Продвинуть

player:receivedExchangeCancellation:forMatch:

Все проигрыватели ответили или испытали таймаут при ответе на обмен

Продвинуть

player:receivedExchangeReplies:forCompletedExchange:forMatch:

По умолчанию, когда Ваша игра получает уведомление, значок добавляется к игровому значку. Добавить GKGameCenterBadgingDisabled к Вашему Info.plist изменить это поведение. Посмотрите Ключи Какао для подробных данных.

Добавление обменов к основанному на повороте соответствию

Добавьте обмены к своей игре для расширения то, что может сделать игра. Обмены позволяют проигрывателям кроме текущего проигрывателя влиять на текущий поворот. Предусматривают ли через торговые элементы с другим проигрывателем или непосредственно влиянием на очередь текущего проигрывателя, обмены большую гибкость в том, как Вы разрабатываете свою игру.

Анатомия Exchange

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

Используя обмены, можно разработать игру так, чтобы проигрыватели кроме текущего проигрывателя могли принять меры во время поворота. Обмен является взаимодействием между обменным инициатором и одним или более обменными получателями. Следующий поток операций используется для обмена:

  • Инициатор отправляет обменный запрос получателю.

  • Получатели уведомляются, что они получили обменный запрос.

  • Получатель действует на обменный запрос и передает их действие обратно инициатору.

  • Инициатор уведомляется относительно завершенного обмена.

  • Текущий проигрыватель уведомляется относительно завершенного обмена и обновляет данные соответствия.

Отправление запроса Exchange

В зависимости от того, как Вы разрабатываете свою игру, любой проигрыватель может подать обменную заявку, являются ли они текущим проигрывателем или нет. Например, во время очереди Мэри, Фред решает, что хочет торговать картами с Келли. Фред выбирает карты, которыми он хочет торговать Келли и что он хочет в ответ. Он тогда отправляет обменный запрос Келли. После того, как запрос отправлен, обновление отправляется Мэри так, чтобы могло быть обновлено соответствие. Посмотрите рисунок 10-5.

Рисунок 10-5  , Инициализирующий торговлю посредством обмена

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

  • Отправитель выбирает, кого отправить обменный запрос к.

  • Природа запроса должна быть определена. Проигрыватель просит торговать картами, обращающимися за помощью в атаке другого проигрывателя или чего-то еще?

  • Количество времени получатели должны реагировать на обменный запрос, должно быть установлено. Можно позволить отправителю выбирать это или устанавливать предел трудного времени.

Объем данных, который можно отправить, ограничивается максимумом 1k. Данные должны быть достаточно всесторонними, что игра проигрывателя получения может действовать и представить данные проигрывателю в пути, который целесообразен в контексте Вашей игры. Когда обменный запрос отправлен, гарантируйте, что текущий проигрыватель также получает данные запроса так, чтобы могло быть обновлено текущее соответствие. Перечисление 10-10 показывает основной обменный запрос. Получатель обмена размещается в массив, и запрос отправлен к проигрывателю, перечисленному в массиве получателей.

Перечисление 10-10  , Отправляющее обменный запрос к другому проигрывателю

- (void) exchangeRequest (GKTurnBasedParticipant receiver)
{
     NSArray *recipients = @[receiver];
     [self sendExchangeToParticipants:recipients data:data localizableMessageKey:key arguments:arguments timeout:timeout completionHandler:^(GKTurnBasedExchange *exchange, NSError *error) {
          // refresh your match data
     }];
}

Прежде чем любые получатели реагируют на обменный запрос, отправитель может отменить запрос. Когда отправитель отменяет обмен, уведомление нажатия отправляется всем получателям, говорящим им, что был отменен обмен.

Перечисление 10-11  , Отменяющее обменный запрос

-(void)player:(GKPlayer *)player exchangeCanceled:(GKTurnBasedExchange *)exchange match:(GKTurnBasedMatch *)match
{
     // update your match data to show the canceled request
}

Ответ на запрос Exchange

После того, как обменный запрос создается, проигрыватели в массиве получателей получают уведомление нажатия. Открытие игры представит обменное сообщение. Получатель может принять решение реагировать на обменный запрос или позволить ему испытать таймаут. Рисунок 10-6 показывает принятие Келли торговля Fred ' s и ответ на его обменный запрос. После того, как обмен завершается, обменный результат отправляется в текущий проигрыватель. Обмен согласован в конце очереди текущего проигрывателя.

Рисунок 10-6  , Принимающий торговлю посредством обмена

Перечисление 10-12 показывает основной формат ответа. Получатель реагирует на обменный запрос и передает любые соответствующие данные обратно исходному отправителю. Ваша игра также должна отправить результаты обмена к текущему проигрывателю так, чтобы они могли обновить соответствие.

Перечисление 10-12  , Отвечающее на обменный запрос

-(void) replyToExchange
{
     [self replyWithLocalizableMessageKey:key arguments:arguments data:data completionHandler:^(NSError *error) {
          // refresh your match data
     }
}