En esta guía, se muestra cómo guardar y cargar los datos del progreso del juego de un jugador con 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 del jugador en cualquier momento durante el juego. Este servicio también puede permitir que los jugadores activen 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 consultar los conceptos de juegos de Juegos guardados.
Antes de comenzar a programar con la API de Saved Games, haz lo siguiente:
- Instala el SDK de Play Juegos para C++.
- Configura tu entorno de desarrollo de C++.
- Descarga y revisa la muestra de código C++.
- Habilita el servicio de Juegos guardados en Google Play Console.
Formatos de datos y compatibilidad multiplataforma
Los datos de los 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 tus datos para la compatibilidad multiplataforma. Las aplicaciones para Android pueden leer estos mismos datos como un array de bytes sin problemas de compatibilidad multiplataforma.
Evita usar formatos específicos de la plataforma cuando elijas un formato de datos para tus datos de Juegos guardados. Te recomendamos que uses un formato de datos, como XML o JSON, que tenga una compatibilidad sólida con bibliotecas en varias plataformas.
Habilita 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 de autenticación.
Cómo mostrar 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 seleccionen esta opción, el juego debería mostrar una pantalla que muestre los espacios de guardado existentes y permitir que los jugadores guarden en uno de estos espacios, carguen desde uno de ellos o creen un juego guardado nuevo. Usa el siguiente método para hacerlo:
SnapshotManager::ShowSelectUIOperation(...)
La IU de selección de juegos guardados permite que los jugadores creen un nuevo juego guardado, consulten los detalles de los juegos guardados existentes y carguen 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 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 el usuario creó actualmente, la IU predeterminada de Snapshot les proporciona a los jugadores un botón para crear un nuevo guardado en lugar de seleccionar uno existente. (Cuando se muestra, el botón está en la parte inferior de la IU). Cuando un usuario hace clic en este botón, la respuesta SnapshotSelectUIResponse
es válida, pero no tiene datos.
Cómo abrir y leer juegos guardados
Para acceder a un juego guardado y leer o modificar su contenido, primero abre el objeto SnapshotMetadata
que lo representa. 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);
…
}
Detecta y resuelve conflictos de datos
Cuando abres un objeto SnapshotMetadata
, el servicio de Juegos guardados detecta si existe un juego guardado en conflicto. Es posible que se produzcan conflictos de datos cuando el juego guardado que se almacenó en el dispositivo local del jugador no se sincronice con la versión remota que se almacenó en los servidores de Google.
La política de conflictos 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 Conflictos | Descripción |
---|---|
SnapshotConflictPolicy::MANUAL |
Indica que el servicio de juegos guardados no debe realizar ninguna acción de resolución. En su lugar, tu juego realizará una combinación personalizada. |
SnapshotConflictPolicy::LONGEST_PLAYTIME |
Indica que el servicio de juegos guardados debe elegir el juego guardado con el valor de tiempo de juego más alto. |
SnapshotConflictPolicy::BASE_WINS |
Indica que el servicio de juegos guardados debe elegir el juego guardado básico. |
SnapshotConflictPolicy::REMOTE_WINS |
Indica que el servicio de juegos guardados debe elegir el juego guardado remoto. 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. Tu juego puede abrir el juego guardado, escribir en él y, luego, 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 la política de conflicto, tu juego debe resolver cualquier conflicto de datos detectado 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);
Escribe los juegos guardados
Para escribir un juego guardado, primero abre el objeto SnapshotMetadata
que lo representa, resuelve cualquier conflicto de datos detectado y, luego, llama al método SnapshotManager::Commit()
para confirmar los cambios del juego guardado.
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 que se resuelvan todos los conflictos eligiendo la base.
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 que se usan 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 del juego guardado.
gpg::SnapshotManager::CommitResponse commitResponse = service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
El parámetro data contiene todos los datos de guardado del juego que almacenas. El cambio también contiene metadatos adicionales del juego guardado, como el tiempo de juego y una descripción del juego guardado.
Si la operación de confirmación se completó correctamente, los jugadores pueden ver el juego guardado en la IU de selección de Juegos guardados.