将游戏存档添加到您的游戏中

本指南介绍了如何使用 Google 文档保存和加载玩家的游戏进度数据, 游戏存档服务您可以使用 服务,以便随时自动加载和保存玩家的游戏进度 。这项服务还能让玩家 更新或恢复现有游戏存档或创建新的游戏存档界面。

准备工作

建议您查看 游戏存档游戏概念

开始使用 Saved Games 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_SNAPSHOTtrueMAX_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 对象时,游戏存档服务会检测 是否存在有冲突的游戏存档。保存 存储在玩家本地设备上的游戏与远程版本不同步 存储在 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 参数包含您要存储的所有游戏存档数据。 此更改还包含其他游戏存档元数据,例如时间 以及已保存游戏的说明

如果提交操作成功完成,玩家可以看到 保存游戏存档。