Questa guida mostra come implementare il servizio Partite salvate utilizzando l'API Snapshots fornita dall'SDK Google Play Games Services in C++. Le API sono disponibili
in PgsSnapshotsClient.
Prima di iniziare
- Per informazioni sulla funzionalità, consulta Partite salvate.
Segui le istruzioni per installare e configurare l'app in modo che utilizzi i servizi per i giochi di Google Play nella guida Configura l'SDK Google Play Services.
Definisci il supporto per le partite salvate per il tuo gioco seguendo le istruzioni nella guida di Google Play Console.
Acquisisci familiarità con i consigli descritti in Elenco di controllo della qualità.
Scaricare il client di Snapshots
Per iniziare a utilizzare l'API Snapshots, il tuo gioco deve prima ottenere un
PgsSnapshotsClient handle. Puoi ottenerlo chiamando il
PgsSnapshotsClient_create() metodo e passando l'attività Android.
Nota: le funzioni dell'SDK C++ restituiscono i risultati in modo asincrono tramite i 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);
Visualizzare le partite salvate
Puoi integrare l'API Snapshots ovunque il tuo gioco offra ai giocatori l'opzione di salvare o ripristinare i loro progressi.
Per semplificare lo sviluppo, l'API Snapshots fornisce un'interfaccia utente (UI) predefinita per la selezione delle partite salvate. Per avviare questa UI, chiama
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);
Scrivere le partite salvate
Per archiviare i contenuti in una partita salvata:
- Apri in modo asincrono uno snapshot utilizzando
PgsSnapshotsClient_open(). Specificacreate_if_not_foundcome true se vuoi creare un nuovo salvataggio. - Il risultato viene fornito in
PgsSnapshotsClient_OpenCallback. Se l'operazione riesce e non si verifica alcun conflitto, riceverai unPgsSnapshot*. - Prepara i dati che vuoi salvare come array di byte (
uint8_t*). - Crea un oggetto
PgsSnapshotMetadataChange*per descrivere il salvataggio. Chiama
PgsSnapshotsClient_commitAndCloseper inviare le modifiche ai server di 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 ); }
Caricare le partite salvate
Per recuperare le partite salvate:
- Apri in modo asincrono lo snapshot per nome utilizzando
PgsSnapshotsClient_open(). In
PgsSnapshotsClient_OpenCallback, se l'operazione riesce, accedi ai dati. L'API fornisce un modo per ottenere i dati e le dimensioniuint8_t*, anche se il metodo per leggere i byte daPgsSnapshoto da unPgsSnapshotContentsassociato non è descritto in dettaglio in questo documento.// 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 ); }
Gestire i conflitti delle partite salvate
Quando viene chiamato il callback PgsSnapshotsClient_open, se il parametro conflict
non è NULL, si è verificato un conflitto. Utilizza
PgsSnapshotsClient_resolveConflict per risolvere il conflitto.
/// @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);