Trò chơi lưu được tiến trình chơi

Tài liệu này sẽ hướng dẫn bạn cách triển khai trò chơi đã lưu bằng API ảnh chụp nhanh do Dịch vụ trò chơi của Google Play cung cấp trong SDK C++. Bạn có thể tìm thấy các API này trong PgsSnapshotsClient.

Trước khi bắt đầu

Tải ứng dụng chụp nhanh

Để có thể sử dụng API ảnh chụp nhanh, trước tiên, trò chơi của bạn phải có được một đối tượng PgsSnapshotsClient. Bạn có thể thực hiện việc này bằng cách gọi phương thức PgsSnapshotsClient_create(), truyền vào Hoạt động Android.

Lưu ý: Các hàm C++ SDK trả về kết quả không đồng bộ thông qua các lệnh gọi lại.

// Assuming 'android_activity' is a jobject referencing your Android Activity
PgsSnapshotsClient* snapshots_client = PgsSnapshotsClient_create(android_activity);

// ... use the client ...

// When done, destroy the client to free resources
// PgsSnapshotsClient_destroy(snapshots_client);

Hiển thị trò chơi đã lưu

Bạn có thể tích hợp API ảnh chụp nhanh bất cứ khi nào trò chơi của bạn cung cấp cho người chơi tùy chọn lưu hoặc khôi phục tiến trình của họ. Để đơn giản hoá quá trình phát triển, API ảnh chụp nhanh cung cấp giao diện người dùng (UI) lựa chọn trò chơi đã lưu mặc định. Để chạy giao diện người dùng này, hãy gọi PgsSnapshotsClient_showSelectSnapshotUI.

// Callback function to handle the result of showing the UI
void OnShowSavedGamesUI(PgsStatusCode status_code, void* user_data) {
  if (status_code == PGS_STATUS_SUCCESS) {
    // UI was shown successfully. The player can now interact with it.
    // The game doesn't receive direct data back from this callback about
    // which snapshot was selected. Your game should typically provide options
    // to load or open snapshots by name after the UI is dismissed.
  } else {
    // Handle error or failure to show UI
  }
}

// Function to show the default Saved Games UI
void ShowSavedGamesUI(PgsSnapshotsClient* client, jobject activity) {
  const char* title = "See My Saves";
  bool allow_add_button = true;
  bool allow_delete_button = true;
  int max_snapshots = 5;

  PgsSnapshotsClient_showSelectSnapshotUI(
      client,
      activity,
      title,
      allow_add_button,
      allow_delete_button,
      max_snapshots,
      OnShowSavedGamesUI,
      NULL // user_data
  );
}

// Example usage:
// ShowSavedGamesUI(snapshots_client, android_activity);

Viết trò chơi đã lưu

Cách lưu trữ nội dung vào trò chơi đã lưu:

  1. Mở ảnh chụp nhanh không đồng bộ bằng PgsSnapshotsClient_open(). Chỉ định create_if_not_found là true nếu bạn muốn tạo một bản lưu mới.
  2. Kết quả được cung cấp bằng PgsSnapshotsClient_OpenCallback. Nếu thành công và không có xung đột, bạn sẽ nhận được một PgsSnapshot*.
  3. Chuẩn bị dữ liệu bạn muốn lưu dưới dạng một mảng byte (uint8_t*).
  4. Tạo một đối tượng PgsSnapshotMetadataChange* để mô tả thao tác lưu.
  5. Gọi PgsSnapshotsClient_commitAndClose để gửi các thay đổi đến máy chủ của Google.

    // Callback for commitAndClose
    void OnSnapshotCommitted(PgsStatusCode status_code, PgsSnapshotMetadata* metadata, void* user_data) {
        if (status_code == PGS_STATUS_SUCCESS) {
        // Save successful
        if (metadata) {
        // Metadata for the committed snapshot
        PgsSnapshotMetadata_Release(metadata);
      }
    } else {
        // Handle error
      }
    }
    
    // Function to write data to a snapshot
    void WriteSnapshot(PgsSnapshotsClient* client, PgsSnapshot* snapshot,
                   const uint8_t* data, size_t data_size,
                   const char* description /*, Bitmap coverImage */) {
    
    PgsSnapshotMetadataChange* metadataChange = NULL; // Placeholder
    
      // Commit the operation
      PgsSnapshotsClient_commitAndClose(
          client,
          snapshot,
          metadataChange,
          data,
          data_size,
          OnSnapshotCommitted,
          NULL // user_data
      );
    
      // if (metadataChange) PgsSnapshotMetadataChange_Release(metadataChange);
    }
    
    // Callback for opening the snapshot before writing
    void OnSnapshotOpenForWrite(PgsStatusCode status_code,
                            PgsSnapshot* snapshot,
                            PgsSnapshotConflict* conflict,
                            void* user_data) {
      if (status_code == PGS_STATUS_SUCCESS) {
        if (snapshot) {
          // Successfully opened/created. Now write to it.
         const char* save_data_str = "MY_GAME_SAVE_DATA";
         const uint8_t* data = (const uint8_t*)save_data_str;
         size_t data_size = strlen(save_data_str);
    
          WriteSnapshot((PgsSnapshotsClient*)user_data, snapshot, data, data_size, "My Save Description");
          // PgsSnapshot_destroy(snapshot) is likely called after commitAndClose by the SDK
        } else if (conflict) {
          // Handle conflict before writing, or open with a policy that auto-resolves.
          PgsSnapshotConflict_destroy(conflict);
        }
      } else {
        // Handle error opening
      }
    }
    
    // Example: Open and write to a snapshot
    void OpenAndWriteExample(PgsSnapshotsClient* client, const char* snapshot_name) {
    PgsSnapshotsClient_open(
      client,
      snapshot_name,
      true, // create_if_not_found
      kPgsSnapshotConflictPolicyManual, // Or another policy
      OnSnapshotOpenForWrite,
      client // user_data
    );
    }

Tải trò chơi đã lưu

Cách truy xuất trò chơi đã lưu:

  1. Mở ảnh chụp nhanh không đồng bộ theo tên bằng cách sử dụng PgsSnapshotsClient_open().
  2. Trong PgsSnapshotsClient_OpenCallback, nếu thành công, hãy truy cập vào dữ liệu. API này cung cấp một cách để lấy dữ liệu và kích thước uint8_t*, mặc dù phương thức đọc byte từ PgsSnapshot hoặc PgsSnapshotContents được liên kết không được trình bày chi tiết trong tài liệu này.

    // Assuming functions exist to read data from PgsSnapshotContents
    // For example, PgsSnapshotContents* PgsSnapshot_getContents(PgsSnapshot* snapshot);
    // For example, bool PgsSnapshotContents_readFully(PgsSnapshotContents* contents, uint8_t** out_data, size_t* out_size);
    // For example, void PgsSnapshotContents_releaseData(uint8_t* data);
    
    void OnSnapshotOpenForRead(PgsStatusCode status_code,
                           PgsSnapshot* snapshot,
                           PgsSnapshotConflict* conflict,
                           void* user_data) {
        if (status_code == PGS_STATUS_SUCCESS) {
        if (snapshot) {
        // Successfully opened. Now read from it.
        // THE FOLLOWING IS HYPOTHETICAL based on common patterns:
        // PgsSnapshotContents* contents = PgsSnapshot_getContents(snapshot);
        // uint8_t* data = NULL;
        // size_t data_size = 0;
        // if (contents && PgsSnapshotContents_readFully(contents, &data, &data_size)) {
        //   // Successfully read data
        //   Log("Snapshot data loaded, size: %zu", data_size);
        //   ... process data ...
        //   PgsSnapshotContents_releaseData(data);
        // }
        // PgsSnapshotContents_destroy(contents); // If necessary
          PgsSnapshot_destroy(snapshot);
        } else if (conflict) {
          // Handle conflict
          Log("Snapshot open resulted in a conflict.");
          PgsSnapshotConflict_destroy(conflict);
        }
      } else {
        // Handle error opening
        Log("Error while opening Snapshot: %d", status_code);
      }
    }
    
    // Example: Load a specific saved game
    void LoadSnapshotByName(PgsSnapshotsClient* client, const char* snapshot_name) {
      int conflictResolutionPolicy = kPgsSnapshotConflictPolicyMostRecentlyModified;
    
      PgsSnapshotsClient_open(
          client,
          snapshot_name,
          false, // create_if_not_found
          conflictResolutionPolicy,
          OnSnapshotOpenForRead,
          NULL // user_data
      );
    }

Xử lý xung đột với trò chơi đã lưu

Khi lệnh gọi lại PgsSnapshotsClient_open được gọi, nếu tham số conflict không phải là NULL, thì đã xảy ra xung đột. Hãy dùng PgsSnapshotsClient_resolveConflict để giải quyết xung đột.

/// @brief Asynchronously resolves a snapshot conflict.
///
/// @param snapshots_client The client handle.
/// @param conflict_id The ID of the conflict to resolve.
/// @param snapshot_id The ID of the snapshot to use for resolution.
/// @param metadata_change The metadata changes to apply to the snapshot, or
/// NULL for no changes.
/// @param contents The contents to resolve the conflict with.
/// @param callback Function to be called with result of asynchronous
/// operation. See PgsSnapshotsClient_OpenCallback.
/// @param user_data Arbitrary data pointer to be passed back to callback.
void PgsSnapshotsClient_resolveConflict(
    PgsSnapshotsClient* snapshots_client,
    const char* conflict_id,
    const char* snapshot_id,
    PgsSnapshotMetadataChange* metadata_change,
    PgsSnapshotContents* contents,
    PgsSnapshotsClient_OpenCallback callback,
    void* user_data);