在遊戲中新增遊戲進度存檔

本指南說明如何使用以下程式碼來儲存及載入玩家的遊戲進度資料: C++ 應用程式中的「遊戲進度存檔」服務。您可以使用 服務,可隨時自動載入並儲存玩家遊戲進度 遊戲過程這項服務也能讓玩家觸發使用者 介面更新/還原現有的遊戲存檔,或建立新遊戲。

事前準備

如果您還沒有這樣做,建議您詳閱 遊戲進度存檔概念

開始使用 Saved Games API 編寫程式碼之前:

資料格式和跨平台相容性

您儲存至 Google 伺服器的「遊戲進度存檔」資料必須存放在 std::vector<uint8_t> 格式。遊戲進度存檔服務會負責編碼 確保資料能支援跨平台相容性Android 應用程式可讀取 與位元組陣列相同的資料,沒有任何跨平台相容性問題。

為 。我們強烈建議您採用資料格式,例如 XML 或 JSON 會在多個平台上提供強大的程式庫支援。

啟用「遊戲進度存檔」服務

如要使用「遊戲進度存檔」服務,您必須先啟用 基礎架構方法是在建立 Service 時呼叫 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);
}

以下範例說明如何開啟預設的「遊戲進度存檔」 UI 並處理玩家的 UI 選項:

  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());
    

    資料參數包含您要儲存的所有遊戲進度存檔資料。 這項變更也包含遊戲進度存檔的中繼資料,例如時間 以及遊戲進度存檔的說明。

如果已成功完成修訂作業,玩家將會看到 。