En esta guía, se muestra cómo implementar juegos guardados con la API de snapshots que proporcionan los Servicios de juego de Google Play en el SDK de C++. Puedes encontrar las APIs en PgsSnapshotsClient.
Antes de comenzar
- Para obtener más información sobre la función, consulta Juegos guardados.
Sigue las instrucciones para instalar y configurar tu app para usar los Servicios de Google Play Games en la guía Cómo configurar el SDK de los Servicios de Google Play.
Define la compatibilidad con los juegos guardados para tu juego siguiendo las instrucciones de la guía de Google Play Console.
Familiarízate con las recomendaciones que se describen en la lista de tareas de calidad.
Obtén el cliente de instantáneas
Para comenzar a usar la API de snapshots, el juego primero debe obtener un identificador de PgsSnapshotsClient. Para ello, llama al método PgsSnapshotsClient_create() y pasa la actividad de Android.
Nota: Las funciones del SDK de C++ devuelven resultados de forma asíncrona a través de devoluciones de llamada.
// 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);
Muestra los juegos guardados
Puedes integrar la API de snapshots en cualquier lugar que tu juego les brinde a los jugadores la opción de guardar o restablecer su progreso.
Para simplificar el desarrollo, la API de snapshots proporciona una interfaz de usuario (IU) de selección de juegos guardados predeterminada. Para iniciar esta IU, llama a 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);
Escribe los juegos guardados
Para almacenar contenido en un juego guardado, haz lo siguiente:
- Abre una instantánea de forma asíncrona con
PgsSnapshotsClient_open(). Especificacreate_if_not_foundcomo verdadero si deseas crear un nuevo guardado. - El resultado se proporciona en
PgsSnapshotsClient_OpenCallback. Si la operación se realiza correctamente y no hay conflictos, recibirás unPgsSnapshot*. - Prepara los datos que deseas guardar como un array de bytes (
uint8_t*). - Crea un objeto
PgsSnapshotMetadataChange*para describir el guardado. Llama a
PgsSnapshotsClient_commitAndClosepara enviar los cambios a los servidores de 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 ); }
Carga los juegos guardados
Para recuperar los juegos guardados, haz lo siguiente:
- Abre la instantánea de forma asíncrona por nombre con
PgsSnapshotsClient_open(). En
PgsSnapshotsClient_OpenCallback, si la operación se realiza correctamente, accede a los datos. La API proporciona una forma de obtener los datos y el tamaño deuint8_t*, aunque en este documento no se detalla el método para leer bytes dePgsSnapshoto de unPgsSnapshotContentsasociado.// 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 ); }
Controla los conflictos de juegos guardados
Cuando se llama a la devolución de llamada PgsSnapshotsClient_open, si el parámetro conflict no es NULL, se produjo un conflicto. Usa PgsSnapshotsClient_resolveConflict para resolverlo.
/// @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);