Добавление сохраненных игр в вашу игру

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

Прежде чем вы начнете

Если вы еще этого не сделали, вам может быть полезно ознакомиться с концепциями игры «Сохраненные игры» .

Прежде чем вы начнете писать код с помощью API сохраненных игр:

Форматы данных и кроссплатформенная совместимость

Данные сохраненных игр, которые вы сохраняете на серверах Google, должны быть в формате std::vector<uint8_t> . Служба сохраненных игр позаботится о кодировании ваших данных для кросс-платформенной совместимости; Приложения Android могут считывать те же данные, что и массив байтов, без каких-либо проблем с межплатформенной совместимостью.

Избегайте использования форматов для конкретных платформ при выборе формата данных для ваших сохраненных игр. Мы настоятельно рекомендуем вам использовать формат данных, такой как XML или JSON, который имеет надежную поддержку библиотеки на нескольких платформах.

Включение службы сохраненных игр

Прежде чем вы сможете использовать службу «Сохраненные игры», вы должны сначала разрешить к ней доступ. Для этого вызовите EnableSnapshots() при создании службы с помощью gpg::GameServices::Builder . Это активирует дополнительные области авторизации, необходимые для сохраненных игр, при следующем событии аутентификации.

Отображение сохраненных игр

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

  SnapshotManager::ShowSelectUIOperation(...)

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

  SnapshotManager::SnapshotSelectUIResponse response;
  if (IsSuccess(response.status)) {
  if (response.data.Valid()) {
    LogI("Description: %s", response.data.Description().c_str());
    LogI("FileName %s", response.data.FileName().c_str());
    //Opening the snapshot data
    …
  } else {
    LogI("Creating new snapshot");
    …
  }
} else {
  LogI("ShowSelectUIOperation returns an error %d", response.status);
}

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

  service_->Snapshots().ShowSelectUIOperation(
  ALLOW_CREATE_SNAPSHOT,
  ALLOW_DELETE_SNAPSHOT,
  MAX_SNAPSHOTS,
  SNAPSHOT_UI_TITLE,
  [this](gpg::SnapshotManager::SnapshotSelectUIResponse const & response) {
  …
      }

Если в приведенном выше примере ALLOW_CREATE_SNAPSHOT имеет значение true , а MAX_SNAPSHOTS больше фактического количества снимков, созданных пользователем в данный момент, пользовательский интерфейс Snapshot по умолчанию предоставляет игрокам кнопку для создания новой сохраненной игры, а не для выбора существующей. (При отображении кнопка находится в нижней части пользовательского интерфейса.) Когда игрок нажимает эту кнопку, ответ SnapshotSelectUIResponse действителен, но не содержит данных.

Открытие и чтение сохраненных игр

Чтобы получить доступ к сохраненной игре и прочитать или изменить ее содержимое, сначала откройте объект SnapshotMetadata , представляющий эту сохраненную игру. Затем вызовите метод SnapshotManager::Read*() .

В следующем примере показано, как открыть сохраненную игру:

  LogI("Opening file");
  service_->Snapshots()
  .Open(current_snapshot_.FileName(),
               gpg::SnapshotConflictPolicy::BASE_WINS,
        [this](gpg::SnapshotManager::OpenResponse const & response) {
           LogI("Reading file");
           gpg::SnapshotManager::ReadResponse responseRead =
           service_->Snapshots().ReadBlocking(response.data);
          …
        }

Обнаружение и разрешение конфликтов данных

Когда вы открываете объект SnapshotMetadata , служба «Сохраненные игры» определяет, существует ли конфликтующая сохраненная игра. Конфликты данных могут возникать, когда сохраненная игра, хранящаяся на локальном устройстве игрока, не синхронизирована с удаленной версией, хранящейся на серверах Google.

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

Конфликтная политика Описание
SnapshotConflictPolicy::MANUAL Указывает, что служба «Сохраненные игры» не должна выполнять никаких действий по устранению неполадок. Вместо этого ваша игра выполнит пользовательское слияние .
SnapshotConflictPolicy::LONGEST_PLAYTIME Указывает, что служба сохраненных игр должна выбрать сохраненную игру с наибольшим значением времени воспроизведения.
SnapshotConflictPolicy::BASE_WINS Указывает, что служба сохраненных игр должна выбрать базовую сохраненную игру.
SnapshotConflictPolicy::REMOTE_WINS Указывает, что служба сохраненных игр должна выбрать удаленную сохраненную игру. Удаленная версия — это версия сохраненной игры, обнаруженная на одном из устройств игрока и имеющая более позднюю отметку времени, чем базовая версия.

Если вы указали политику конфликтов, отличную от GPGSnapshotConflictPolicyManual , служба сохраненных игр объединит сохраненную игру и вернет обновленную версию через результирующее значение SnapshotManager::OpenResponse . Ваша игра может открыть сохраненную игру, записать в нее данные, а затем вызвать метод SnapshotManager::Commit(...) для фиксации сохраненной игры на серверах Google.

Выполнение пользовательского слияния

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

В этом случае при обнаружении конфликта данных сервис возвращает следующие параметры через SnapshotManager::OpenResponse :

  • conflict_id для уникальной идентификации этого конфликта (вы будете использовать это значение при фиксации окончательной версии сохраненной игры);
  • Конфликтующая базовая версия сохраненной игры; и,
  • Конфликтующая удаленная версия сохраненной игры.

Ваша игра должна решить, какие данные сохранять, а затем вызвать метод SnapshotManager::ResolveConflictBlocking() , чтобы зафиксировать/разрешить окончательную версию на серверах Google.

    //Resolve conflict
    gpg::SnapshotManager::OpenResponse resolveResponse =
        manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
                                  openResponse.conflict_id);

Запись сохраненных игр

Чтобы записать сохраненную игру, сначала откройте объект SnapshotMetadata , представляющий эту сохраненную игру, разрешите все обнаруженные конфликты данных, а затем вызовите метод SnapshotManager::Commit() , чтобы зафиксировать изменения сохраненной игры.

В следующем примере показано, как можно создать изменение и зафиксировать сохраненную игру.

  1. Во-первых, откройте снимок, который мы хотим отредактировать, и убедитесь, что все конфликты разрешены, выбрав базу.

    service_->Snapshots().Open(
          file_name,
          gpg::SnapshotConflictPolicy::BASE_WINS,
          [this](gpg::SnapshotManager::OpenResponse const &response) {
            if (IsSuccess(response.status)) {
              // metadata : gpg::SnapshotMetadata
              metadata = response.data;
            } else {
              // Handle snapshot open error here
            }
          });
    
  2. Затем создайте сохраненное изменение игры, которое включает данные изображения, используемые для изображения обложки:

    gpg::SnapshotMetadataChange::Builder builder;
    gpg::SnapshotMetadataChange metadata_change =
        builder.SetDescription("CollectAllTheStar savedata")
                 .SetCoverImageFromPngData(pngData).Create();
    
  3. Наконец, зафиксируйте сохраненные изменения игры.

    gpg::SnapshotManager::CommitResponse commitResponse =
        service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
    

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

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