2015-08-13 2 views
1

Я использую пошаговые матчи Game Center для своей карточной игры. Он чувствует себя хорошо, потому что люди хотят проверить свою электронную почту или написать текст иногда между очередями. Некоторые пользователи заявили, что действительно хотят иметь очень асинхронный игровой опыт.GameKit Пошаговый слушатель не надежно вызывается при изменении matchData

Для людей, которые держат игру открытой между поворотами, я хочу обновить экран, чтобы отразить то, что делают другие игроки на своих поворотах. Я установил слушателя на GKLocalPlayer, который отвечает на player:receivedTurnEventForMatch:didBecomeActive. В документации говорится, что это будет вызвано, когда данные сопоставления будут сохранены другим игроком, даже если он не станет чередой игрока (игрок на текущем устройстве). Это не похоже на 100% времени. Фактически, похоже, что он получает только около 1 в 3 раза, что соответствует данным, которые сохраняются другими игроками. Кажется более надежным, когда он становится чередой игрока, но даже это не на 100% надежнее.

Я использую saveCurrentTurnWithMatchData:completionHandler: на GKTurnBasedMatch сохранить данные матча, не конец очереди текущего игрока, и я звоню endTurnWithNextParticipants:turnTimeout:matchData:completionHandler: на GKTurnBasedMatch, чтобы сохранить данные, когда это закончится поворот текущего игрока. Есть несколько сценариев, в которых я хочу позвонить saveCurrentTurn… с обновленными matchData. В моей игре вы можете иметь компьютеры, играющие в вашей многопользовательской игре. Таким образом, игрок может сыграть карту, а затем компьютер может сыграть карту до того, как закончится поворот GKPlayer. Существуют также сценарии, в которых отдельный игрок может играть дважды. (например, игрок играет на последней карте с трюком. Этот игрок делает трюк и получает возможность провести следующий трюк.)

Я установил тонну регистрации в этом поле, и я вижу ясные сценарии, когда одно устройство звонки saveCurrentTurn…, а завершениеHandler вызывается без ошибки, а другое устройство не получает уведомление с вызовом player:receivedTurnEvent…. Я также добавил регистрацию, чтобы проверить, что каждый раз, когда я звоню , я вызываю его с новыми matchData. Я не делаю лишних звонков.

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

Я пробовал регулировать звонки до saveCurrentTurn…, чтобы они не происходили в непосредственной последовательности, и это не помогло.

Оба устройства в моем тестировании работают под управлением iOS 8.4. Кажется, что проблема в iOS 8.3 была исправлена ​​(see this question). This Apple forum post также сообщает об этой проблеме 2 года назад, и, похоже, отчеты об ошибках были зарегистрированы и отмечены исправленными.

Кто-нибудь еще видел это? Я хотел бы знать, что я делаю что-то неправильно. Любые идеи очень приветствуются.

ответ

4

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

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

  1. Замедление сохраняет.Если вы сохраняете слишком быстро, только последний приходит к получателю. Я создал очередь NSArray, и каждый раз, когда я хочу сохранить совпадение, я добавляю новую matchData в эту очередь. У меня есть цикл таймера, который выполняет фактический saveCurrentTurnWithMatchData, выталкивает элемент из стека, если сохранение было успешным, а затем настраивает новый таймер, чтобы называть себя снова немного позже. Я использую 2-секундные интервалы, которые, кажется, работают хорошо.

  2. Прилагайте каждую новую часть данных, не перезаписывайте. Поместите порядковый номер на каждую часть данных. Таким образом, если вы сохраните номера 1, 2, 3 и 4, но получатель получит уведомление только за # 4, записи для 1, 2 и 3 находятся в объекте совпадения. Получателю необходимо отслеживать последнюю прочитанную запись, а затем перебирать любые новые записи с этой точки, когда она получает обновленную matchData.

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

  4. Обратите внимание, что даже при использовании этого механизма уведомления получателю являются неустойчивыми. Вообще говоря, они поступают в партии 4+. Тогда ничего не происходит до тех пор, пока не произойдет 3 или 4 сейва, которые снова появятся вместе. Сделать 1 сохранение и дать игре сидеть в течение 10 минут, вероятно, никогда не будет генерировать уведомление на машине получателя. Но, если вы сохраняете 4 или 6 раз подряд, все они, как правило, появляются всплеск.

  5. Иногда уведомления останавливаются на несколько часов. Не уверен, что это недостаток в песочнице или недостаток игрового центра в целом. Никаких сбоев нет, сообщения перестают работать некоторое время. Иногда, на следующее утро, они появляются в очередях. Иногда нет. В конце концов, я прекратил полагаться на уведомления. Я настроил еще один таймер, чтобы постоянно загружать матч. Он проверяет, стал ли он моей очереди или нет, он проверяет, были ли добавлены новые обновления в matchData. Затем звонки player:receivedTurnEventForMatch:didBecomeActive. До receivedTurnEventForMatch: знает, он был запущен из-за события, и он весело рассказывает о своем бизнесе. Боец Если вы не получите сообщение об ошибке, кажется вполне уверенным, что обновленное соответствие немедленно доступно для других игроков, чтобы их потреблять ... им просто нужно знать, чтобы их использовать. Рамки обмена сообщениями, однако, должны рассматриваться как абсолютно ненадежные и не гарантированные. Следовательно, таймер цикла для непрерывного опроса матча.

Редактировать: возможно, как только я осуществил # 2, # 1 не имеет значения. Любое уведомление, получаемое получателем, приведет к чтению всех новых записей в данных. Но это «упрочение» развивалось в течение последних нескольких месяцев, когда я боролся с недостатками Game Center. Я просто не добрался до удаления №1.

+0

Это действительно интересно. Спасибо за обмен вашего опыта. Удивительно, что так сложно найти информацию об этом, что происходит с другими людьми. Я собираюсь оставить этот вопрос еще немного в отчаянной надежде, что есть решение. Если ничего не появится, я отмечу это как ответ. – dontangg

+0

У меня такие же проблемы. Возможно, мне придется обратиться к таймеру (№5). Я действительно не хочу, но похоже, что это мой единственный вариант. Вы можете увидеть мой вопрос здесь: http://stackoverflow.com/questions/34570404/how-do-i-reply-to-a-gkturnbasedexchange-gklocalplayerlistener-delegate-received. Вы все еще замечаете такое поведение? – STANGMMX

Смежные вопросы