Este guia mostra como salvar e carregar os dados de progresso de um jogador usando o serviço de Jogos salvos em um app em C++. Você pode usar esse serviço para carregar e salvar automaticamente o progresso do jogo a qualquer momento durante o jogo. Esse serviço também permite que os jogadores acionem uma interface do usuário para atualizar ou restaurar um jogo salvo ou criar um novo.
Antes de começar
Caso ainda não tenha feito isso, recomendamos consultar os conceitos de jogos salvos.
Antes de começar a programar usando a API Saved Games:
- Instale o SDK do Play Games para C++.
- Configure o ambiente de desenvolvimento em C++.
- Faça o download e analise o exemplo de código C++.
- Ative o serviço de Jogos salvos no Google Play Console.
Formatos de dados e compatibilidade entre plataformas
Os dados de Jogos salvos que você salva nos servidores do Google precisam estar no
formato std::vector<uint8_t>
. O serviço de Jogos salvos codifica seus dados
para compatibilidade com várias plataformas. Os apps Android podem ler
nesses mesmos dados como uma matriz de bytes sem problemas de compatibilidade com várias plataformas.
Evite usar formatos específicos da plataforma ao escolher um formato para os dados de Jogos salvos. Recomendamos que você use um formato de dados, como XML ou JSON, que tenha forte compatibilidade com bibliotecas em várias plataformas.
Como ativar o serviço de Jogos salvos
Antes de usar o serviço de Jogos salvos, ative o
acesso a ele. Para fazer isso, chame EnableSnapshots()
ao criar o serviço com
gpg::GameServices::Builder
. Isso ativará os escopos de autenticação adicionais
exigidos pelos Jogos salvos no próximo evento de autenticação.
Mostrando jogos salvos
No seu jogo, você pode fornecer uma opção que os jogadores podem acionar para salvar ou restaurar jogos salvos. Quando os jogadores selecionam essa opção, o jogo precisa mostrar uma tela que mostra slots salvos e permite que os jogadores salvem ou carreguem usando um desses slots ou criem um novo jogo salvo. Para isso, use o seguinte método:
SnapshotManager::ShowSelectUIOperation(...)
A IU de seleção de Jogos salvos permite que os jogadores criem um novo jogo salvo, visualizem detalhes sobre os já existentes e carreguem jogos 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);
}
O exemplo abaixo ilustra como exibir a IU padrão de Jogos salvos e processar a seleção da IU do jogador:
service_->Snapshots().ShowSelectUIOperation(
ALLOW_CREATE_SNAPSHOT,
ALLOW_DELETE_SNAPSHOT,
MAX_SNAPSHOTS,
SNAPSHOT_UI_TITLE,
[this](gpg::SnapshotManager::SnapshotSelectUIResponse const & response) {
…
}
Se, no exemplo acima, ALLOW_CREATE_SNAPSHOT
for true
e MAX_SNAPSHOTS
for maior que o número real de snapshots criados atualmente pelo usuário, a IU de snapshots padrão fornecerá um botão para criar um novo
jogo de salvamento em vez de selecionar um existente. Quando exibido, o botão
está na parte de baixo da IU. Quando um jogador clica nesse botão, a
resposta de SnapshotSelectUIResponse
é válida, mas não tem dados.
Como abrir e ler jogos salvos
Para acessar um jogo salvo e ler ou modificar o conteúdo dele, primeiro abra
o objeto SnapshotMetadata
que representa esse jogo. Em seguida, chame o
método SnapshotManager::Read*()
.
O exemplo a seguir mostra como abrir um jogo salvo:
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);
…
}
Como detectar e resolver conflitos de dados
Quando você abre um objeto SnapshotMetadata
, o serviço de Jogos salvos detecta
se existe um jogo salvo conflitante. Os conflitos de dados podem ocorrer quando o jogo salvo
armazenado no dispositivo local de um jogador está fora de sincronia com a versão remota
armazenada nos servidores do Google.
A política de conflito especificada ao abrir um jogo salvo informa ao serviço Saved Games como resolver automaticamente um conflito de dados. A política pode ser uma das seguintes:
Política de conflito | Descrição |
---|---|
SnapshotConflictPolicy::MANUAL |
Indica que o serviço de Jogos salvos não deve executar nenhuma ação de resolução. Em vez disso, o jogo vai fazer uma combinação personalizada. |
SnapshotConflictPolicy::LONGEST_PLAYTIME |
Indica que o serviço de Jogos salvos precisa escolher o jogo salvo com o maior valor de tempo de jogo. |
SnapshotConflictPolicy::BASE_WINS |
Indica que o serviço de Jogos salvos precisa escolher o jogo salvo base. |
SnapshotConflictPolicy::REMOTE_WINS |
Indica que o serviço de Jogos salvos precisa escolher o jogo salvo remoto. A versão remota é uma versão do jogo salvo detectada em um dos dispositivos do jogador e tem um carimbo de data/hora mais recente do que a versão base. |
Se você especificar uma política de conflito diferente de GPGSnapshotConflictPolicyManual
,
o serviço de Jogos salvos mesclará o jogo salvo e retornará a versão atualizada
usando o valor SnapshotManager::OpenResponse
resultante. Seu jogo pode abrir
o jogo salvo, gravar nele e chamar o método SnapshotManager::Commit(...)
para confirmá-lo nos servidores do Google.
Como fazer uma mesclagem personalizada
Se você especificou SnapshotConflictPolicy::MANUAL
como a política de conflito,
seu jogo precisa resolver qualquer conflito de dados detectado antes de executar outras
operações de leitura ou gravação no jogo salvo.
Nesse caso, quando um conflito de dados é detectado, o serviço retorna os
seguintes parâmetros por meio de SnapshotManager::OpenResponse
:
- Um
conflict_id
para identificar exclusivamente esse conflito. Você usará esse valor ao confirmar a versão final do jogo salvo. - a versão base conflitante do jogo salvo; e
- A versão remota conflitante do jogo salvo.
Seu jogo precisa decidir quais dados salvar e chamar o
método SnapshotManager::ResolveConflictBlocking()
para confirmar/resolver a versão
final para os servidores do Google.
//Resolve conflict
gpg::SnapshotManager::OpenResponse resolveResponse =
manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
openResponse.conflict_id);
Como escrever jogos salvos
Para criar um jogo salvo, primeiro abra o objeto SnapshotMetadata
que representa
esse jogo, resolva os conflitos de dados detectados e chame o
método SnapshotManager::Commit()
para confirmar as mudanças
salvas.
O exemplo a seguir mostra como criar uma mudança e confirmar um jogo salvo.
Primeiro, abra o snapshot que queremos editar e confira se todos os conflitos foram resolvidos escolhendo a 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 } });
Em seguida, crie uma mudança de jogo salva que inclua os dados da imagem usados para a imagem de capa:
gpg::SnapshotMetadataChange::Builder builder; gpg::SnapshotMetadataChange metadata_change = builder.SetDescription("CollectAllTheStar savedata") .SetCoverImageFromPngData(pngData).Create();
Por fim, confirme as mudanças salvas no jogo.
gpg::SnapshotManager::CommitResponse commitResponse = service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
O parâmetro de dados contém todos os dados de jogos salvos. A mudança também contém outros metadados de jogos salvos, como o tempo jogado e uma descrição do jogo salvo.
Se a operação de confirmação for concluída com êxito, os jogadores vão poder ver o jogo salvo na IU de seleção de Jogos salvos.