Panduan ini menunjukkan cara menerapkan game tersimpan menggunakan snapshot API
yang disediakan oleh Layanan game Google Play di C++ SDK. API ini dapat ditemukan
di PgsSnapshotsClient.
Sebelum memulai
- Untuk informasi tentang fitur ini, lihat Game tersimpan.
Ikuti petunjuk penginstalan dan penyiapan aplikasi untuk menggunakan Layanan game Google Play di panduan Menyiapkan SDK layanan Google Play.
Tentukan dukungan game tersimpan untuk game Anda dengan mengikuti petunjuk di panduan Konsol Google Play.
Pahami rekomendasi yang dijelaskan dalam Checklist Kualitas.
Mendapatkan klien snapshot
Untuk mulai menggunakan snapshot API, game Anda harus mendapatkan handle
PgsSnapshotsClient terlebih dahulu. Anda dapat melakukannya dengan memanggil
metode PgsSnapshotsClient_create(), lalu meneruskan Aktivitas Android.
Catatan: Fungsi C++ SDK menampilkan hasil secara asinkron melalui callback.
// 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);
Menampilkan game tersimpan
Anda dapat mengintegrasikan snapshot API di mana pun game Anda menyediakan opsi
kepada pemain untuk menyimpan atau memulihkan progresnya.
Untuk menyederhanakan pengembangan, snapshot API menyediakan antarmuka pengguna (UI)
pilihan game tersimpan default. Untuk meluncurkan UI ini, panggil
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);
Menulis game tersimpan
Untuk menyimpan konten ke game tersimpan:
- Buka snapshot secara asinkron menggunakan
PgsSnapshotsClient_open(). Tentukancreate_if_not_foundsebagai benar jika Anda ingin membuat penyimpanan baru. - Hasilnya diberikan dalam
PgsSnapshotsClient_OpenCallback. Jika berhasil dan tidak ada konflik, Anda akan mendapatkanPgsSnapshot*. - Siapkan data yang ingin Anda simpan sebagai array byte (
uint8_t*). - Buat objek
PgsSnapshotMetadataChange*untuk mendeskripsikan penyimpanan. Panggil
PgsSnapshotsClient_commitAndCloseuntuk mengirim perubahan ke server 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 ); }
Memuat game tersimpan
Untuk mengambil game tersimpan:
- Buka snapshot secara asinkron menurut nama menggunakan
PgsSnapshotsClient_open(). Di
PgsSnapshotsClient_OpenCallback, jika berhasil, akses data. API ini menyediakan cara untuk mendapatkan data dan ukuranuint8_t*, meskipun metode untuk membaca byte dariPgsSnapshotatauPgsSnapshotContentsterkait tidak dijelaskan dalam dokumen ini.// 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 ); }
Menangani konflik game tersimpan
Saat callback PgsSnapshotsClient_open dipanggil, jika parameter conflict
bukan NULL, konflik telah terjadi. Gunakan
PgsSnapshotsClient_resolveConflict untuk menyelesaikan konflik.
/// @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);