本指南介绍了如何使用 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_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
对象时,游戏存档服务会检测
是否存在有冲突的游戏存档。保存
存储在玩家本地设备上的游戏与远程版本不同步
存储在 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()
方法提交已保存的内容
游戏变革。
以下示例展示了如何创建更改并提交 游戏存档。
首先,打开我们要修改的快照,并确保所有冲突都已 通过选择底基来解析。
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 } });
接下来,创建一项游戏存档更改,其中包括用于 封面图片:
gpg::SnapshotMetadataChange::Builder builder; gpg::SnapshotMetadataChange metadata_change = builder.SetDescription("CollectAllTheStar savedata") .SetCoverImageFromPngData(pngData).Create();
最后,提交游戏存档更改。
gpg::SnapshotManager::CommitResponse commitResponse = service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
data 参数包含您要存储的所有游戏存档数据。 此更改还包含其他游戏存档元数据,例如时间 以及已保存游戏的说明
如果提交操作成功完成,玩家可以看到 保存游戏存档。