En esta guía, se muestra cómo guardar y cargar los datos de progreso del juego de un jugador mediante el servicio de Juegos guardados en una aplicación de C++. Puedes usar este servicio para cargar y guardar automáticamente el progreso del juego en cualquier momento durante el juego. Este servicio también puede permitir a los jugadores activar una interfaz de usuario para actualizar o restablecer un juego guardado existente, o crear uno nuevo.
Antes de comenzar
Si aún no lo hiciste, puede resultarte útil revisar los conceptos de juegos guardados.
Antes de comenzar a programar con la API de Saved Games:
- Instala el SDK de Play Juegos para C++.
- Configura tu entorno de desarrollo de C++.
- Descarga y revisa el código de muestra de C++.
- Habilita el servicio de Juegos guardados en Google Play Console.
Formatos de datos y compatibilidad multiplataforma
Los datos de Juegos guardados que guardas en los servidores de Google deben estar en formato std::vector<uint8_t>
. El servicio de Juegos guardados se encarga de codificar los datos a fin de mejorar la compatibilidad entre plataformas. Las aplicaciones para Android pueden leer estos mismos datos como un arreglo de bytes sin problemas de compatibilidad entre plataformas.
Evita usar formatos específicos de la plataforma cuando elijas un formato de datos para los datos de los juegos guardados. Te recomendamos que uses un formato de datos, como XML o JSON, que sea compatible con bibliotecas sólidas en varias plataformas.
Cómo habilitar el servicio de juegos guardados
Antes de poder usar el servicio de Juegos guardados, debes habilitar el acceso a él. Para ello, llama a EnableSnapshots()
cuando crees el servicio con gpg::GameServices::Builder
. Esto habilitará los permisos de autenticación adicionales que requieren los Juegos guardados en el próximo evento.
Se muestran los juegos guardados
En tu juego, puedes proporcionar una opción que los jugadores puedan activar para guardar o restablecer los juegos guardados. Cuando los jugadores seleccionan esta opción, el juego debe abrir una pantalla que muestra las ranuras de guardado existentes y permitir que los jugadores guarden o carguen una de estas ranuras, o bien que creen un juego guardado nuevo. Usa el siguiente método para hacerlo:
SnapshotManager::ShowSelectUIOperation(...)
La IU de selección de Juegos guardados permite a los jugadores crear un juego guardado nuevo, ver los detalles de los juegos guardados existentes y cargar los juegos guardados anteriores.
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);
}
En el siguiente ejemplo, se muestra cómo abrir la IU predeterminada de los juegos guardados y controlar la selección de la IU del jugador:
service_->Snapshots().ShowSelectUIOperation(
ALLOW_CREATE_SNAPSHOT,
ALLOW_DELETE_SNAPSHOT,
MAX_SNAPSHOTS,
SNAPSHOT_UI_TITLE,
[this](gpg::SnapshotManager::SnapshotSelectUIResponse const & response) {
…
}
Si, en el ejemplo anterior, ALLOW_CREATE_SNAPSHOT
es true
y MAX_SNAPSHOTS
es mayor que la cantidad real de instantáneas que creó el usuario, la IU de Snapshot predeterminada les brinda a los jugadores un botón para crear un juego de guardado nuevo en lugar de seleccionar uno existente. (Cuando se muestra, el botón está en la parte inferior de la IU). Cuando un jugador hace clic en este botón, la respuesta SnapshotSelectUIResponse
es válida, pero no tiene datos.
Abrir y leer los juegos guardados
Para acceder a un juego guardado y leer o modificar su contenido, primero abre el objeto SnapshotMetadata
que representa ese juego guardado. A continuación, llama al método SnapshotManager::Read*()
.
En el siguiente ejemplo, se muestra cómo abrir un juego guardado:
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);
…
}
Detección y resolución de conflictos de datos
Cuando abres un objeto SnapshotMetadata
, el servicio de Juegos guardados detecta si existe un juego guardado en conflicto. Los conflictos de datos pueden ocurrir cuando el juego guardado que se almacena en el dispositivo local de un jugador no está sincronizado con la versión remota almacenada en los servidores de Google.
La política de conflicto que especificas cuando abres un juego guardado le indica al servicio de juegos guardados cómo resolver automáticamente un conflicto de datos. La política puede ser una de las siguientes:
Política de conflicto | Descripción |
---|---|
SnapshotConflictPolicy::MANUAL |
Indica que el servicio de Juegos guardados no debe realizar ninguna acción de resolución. En cambio, el juego realizará una combinación personalizada. |
SnapshotConflictPolicy::LONGEST_PLAYTIME |
Indica que el servicio de juegos guardados debe elegir el juego guardado con el mayor valor de tiempo de juego. |
SnapshotConflictPolicy::BASE_WINS |
Indica que el servicio de Juegos guardados debe elegir el juego guardado base. |
SnapshotConflictPolicy::REMOTE_WINS |
Indica que el servicio de Juegos guardados debe elegir el juego remoto guardado. La versión remota es una versión del juego guardado que se detecta en uno de los dispositivos del jugador y tiene una marca de tiempo más reciente que la versión base. |
Si especificaste una política de conflicto distinta de GPGSnapshotConflictPolicyManual
, el servicio de Juegos guardados combinará el juego guardado y mostrará la versión actualizada a través del valor SnapshotManager::OpenResponse
resultante. El juego puede abrir el juego guardado, escribir en él y llamar al método SnapshotManager::Commit(...) para confirmar el juego guardado en los servidores de Google.
Cómo realizar una combinación personalizada
Si especificaste SnapshotConflictPolicy::MANUAL
como política de conflicto, tu juego debe resolver cualquier conflicto de datos que se detecte antes de realizar más operaciones de lectura o escritura en el juego guardado.
En este caso, cuando se detecta un conflicto de datos, el servicio muestra los siguientes parámetros a través de SnapshotManager::OpenResponse
:
- Un
conflict_id
para identificar de forma exclusiva este conflicto (usarás este valor cuando confirmes la versión final del juego guardado) - La versión base en conflicto del juego guardado
- La versión remota en conflicto del juego guardado.
Tu juego debe decidir qué datos guardar y, luego, llamar al método SnapshotManager::ResolveConflictBlocking()
para confirmar o resolver la versión final en los servidores de Google.
//Resolve conflict
gpg::SnapshotManager::OpenResponse resolveResponse =
manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
openResponse.conflict_id);
Cómo escribir juegos guardados
Para escribir un juego guardado, primero abre el objeto SnapshotMetadata
que representa ese juego, resuelve cualquier conflicto de datos detectado y, luego, llama al método SnapshotManager::Commit()
para confirmar los cambios.
En el siguiente ejemplo, se muestra cómo puedes crear un cambio y confirmar un juego guardado.
Primero, abre la instantánea que queremos editar y asegúrate de resolver todos los conflictos.
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 } });
A continuación, crea un cambio de juego guardado que incluya los datos de imagen usados para la imagen de portada:
gpg::SnapshotMetadataChange::Builder builder; gpg::SnapshotMetadataChange metadata_change = builder.SetDescription("CollectAllTheStar savedata") .SetCoverImageFromPngData(pngData).Create();
Por último, confirma los cambios guardados del juego.
gpg::SnapshotManager::CommitResponse commitResponse = service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
El parámetro de datos contiene todos los datos guardados del juego que almacenas. El cambio también contiene metadatos adicionales guardados sobre el juego, como el tiempo de juego jugado y una descripción del juego guardado.
Si la operación de confirmación se completó correctamente, los jugadores podrán ver el juego guardado en la IU de selección de Juegos guardados.