このガイドでは、C++ アプリで保存済みゲームサービスを使用してプレーヤーのゲームの進行状況データを保存および読み込む方法について説明します。このサービスを使用すると、ゲームプレイ中の任意の時点でプレーヤーのゲームの進行状況を自動的に読み込み、保存できます。このサービスを使用すると、プレーヤーはユーザー インターフェースをトリガーして、既存のセーブゲームを更新または復元したり、新しいセーブゲームを作成したりすることもできます。
始める前に
セーブ ゲームに関するコンセプトをまだ確認されていない場合は、確認することをおすすめします。
Saved Games API を使用してコーディングを開始する前に:
- C++ Play Games SDK をインストールします。
- C++ 開発環境をセットアップします。
- C++ コードサンプルをダウンロードして確認する。
- Google Play Console で保存済みゲームサービスを有効にする。
データ形式とクロス プラットフォームの互換性
Google のサーバーに保存する保存済みゲームデータは、std::vector<uint8_t>
形式にする必要があります。保存済みゲーム サービスは、クロスプラットフォームの互換性を確保するためにデータをエンコードします。Android アプリケーションは、クロスプラットフォームの互換性の問題なしに、この同じデータをバイト配列として読み取ることができます。
保存済みゲームデータのデータ形式を選択する際は、プラットフォーム固有の形式を使用しないでください。複数のプラットフォームで強力なライブラリ サポートが提供されているデータ形式(XML や JSON など)を使用することを強くおすすめします。
保存済みゲーム サービスを有効にする
保存済みゲーム サービスを使用するには、まずアクセスを有効にする必要があります。これを行うには、gpg::GameServices::Builder
でサービスを作成するときに EnableSnapshots()
を呼び出します。これにより、次回の認証イベントで、セーブしたゲームに必要な追加の認証スコープが有効になります。
保存済みゲームを表示する
ゲーム内で、プレーヤーがトリガーして保存済みゲームを保存または復元できるオプションを用意できます。プレーヤーがこのオプションを選択すると、既存の保存スロットが表示される画面がゲームに表示され、プレーヤーはこれらのスロットのいずれかに保存または読み込みを行うか、新しい保存済みゲームを作成できます。そのためには、次のメソッドを使用します。
SnapshotManager::ShowSelectUIOperation(...)
保存済みゲーム選択 UI により、プレーヤーは、新しい保存済みゲームの作成、既存の保存済みゲームの詳細表示、以前の保存済みゲームの読み込みを行えます。
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);
}
次の例は、デフォルトの保存済みゲーム UI を表示し、プレーヤーの UI 選択を処理する方法を示しています。
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
がユーザーが現在作成した実際のスナップショット数より大きい場合、デフォルトのスナップショット UI には、既存のゲームを選択するのではなく、新しいセーブ ゲームを作成するボタンが表示されます。(表示されている場合、ボタンは UI の下部にあります)。プレーヤーがこのボタンをクリックすると、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 のサーバーに commit できます。
カスタム結合を実行する
競合ポリシーとして SnapshotConflictPolicy::MANUAL
を指定した場合、ゲームは、保存済みゲームに対してさらに読み取りまたは書き込みオペレーションを実行する前に、検出されたデータ競合を解決する必要があります。
この場合、データ競合が検出されると、サービスは SnapshotManager::OpenResponse
を介して次のパラメータを返します。
- この競合を一意に識別する
conflict_id
(この値は、保存済みゲームの最終バージョンを commit するときに使用します)。 - 競合する保存済みゲームのベース バージョン。
- 競合する保存済みゲームのリモート バージョン。
ゲームは、保存するデータを決定し、SnapshotManager::ResolveConflictBlocking()
メソッドを呼び出して、最終バージョンを Google のサーバーに commit または解決する必要があります。
//Resolve conflict
gpg::SnapshotManager::OpenResponse resolveResponse =
manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
openResponse.conflict_id);
保存済みゲームを作成する
保存済みゲームを書き込むには、まずその保存済みゲームを表す SnapshotMetadata
オブジェクトを開き、検出されたデータ競合を解決してから、SnapshotManager::Commit()
メソッドを呼び出して保存済みゲームの変更を commit します。
次の例は、変更を作成し、保存済みゲームを 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();
最後に、保存したゲームの変更を commit します。
gpg::SnapshotManager::CommitResponse commitResponse = service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
data パラメータには、保存するセーブゲーム データがすべて含まれます。この変更には、プレイ時間や保存済みゲームの説明など、保存済みゲームの追加メタデータも含まれています。
コミット オペレーションが正常に完了すると、保存済みゲーム選択 UI に保存済みゲームが表示されます。