Добавьте сохраненные игры в свою игру

В связи с прекращением поддержки API Google Sign-In , мы удаляем SDK для игр версии 1 в 2026 году. После февраля 2025 года вы не сможете публиковать в Google Play игры, которые были интегрированы с SDK для игр версии 1. Мы рекомендуем использовать вместо него SDK для игр версии 2.
Хотя существующие игры с интеграцией предыдущих версий v1 будут продолжать работать еще пару лет, мы рекомендуем перейти на версию v2, начиная с июня 2025 года.
Данное руководство предназначено для использования SDK Play Games Services v1. SDK C++ для Play Games Services v2 пока недоступен.

В этом руководстве показано, как сохранять и загружать данные о прогрессе игрока в игре с помощью службы «Сохраненные игры» в приложении на 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 больше фактического количества снимков, созданных пользователем, то в стандартном интерфейсе создания снимков игрокам предоставляется кнопка для создания нового сохранения, а не для выбора существующего. (При отображении кнопка находится внизу интерфейса.) Когда игрок нажимает на эту кнопку, ответ 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 служба Saved Games определяет наличие конфликтующих сохранений. Конфликты данных могут возникать, когда сохраненная игра, хранящаяся на локальном устройстве игрока, не синхронизирована с удаленной версией, хранящейся на серверах 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());
    

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

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