Este guia mostra como salvar e carregar os dados de progresso de um jogador usando o serviço de Jogos salvos em um aplicativo C++. Você pode usar esse serviço para carregar e salvar automaticamente o progresso do jogador 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 cuida da codificação
dos seus dados para compatibilidade entre plataformas. Os aplicativos Android podem ler
esses mesmos dados como uma matriz de bytes sem problemas de compatibilidade entre plataformas.
Evite usar formatos específicos da plataforma ao escolher um formato de dados para Jogos salvos. Recomendamos o uso de um formato de dados, como XML ou JSON, que tenha suporte de biblioteca em várias plataformas.
Ativar o serviço de jogos salvos
Antes de usar o serviço de Jogos salvos, é necessário ativar o acesso a
ele. Para fazer isso, chame EnableSnapshots()
ao criar o serviço com
gpg::GameServices::Builder
. Isso vai ativar os escopos de autenticação adicionais
necessários pelos jogos salvos no próximo evento de autenticação.
Mostrar jogos salvos
No jogo, você pode oferecer uma opção que os jogadores podem acionar para salvar ou restaurar jogos salvos. Quando os jogadores selecionam essa opção, o jogo mostra uma tela com os slots de salvamento disponíveis e permite que os jogadores salvem ou carreguem um deles ou criem um novo jogo salvo. Use o seguinte método para fazer isso:
SnapshotManager::ShowSelectUIOperation(...)
A IU de seleção de jogos salvos permite que os jogadores criem um novo jogo salvo, confiram detalhes sobre os já existentes e carreguem os 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 a seguir ilustra como abrir a interface padrão de jogos salvos e processar a seleção de interface 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 que o usuário criou
no momento, a interface padrão do snapshot vai oferecer aos jogadores um botão para criar um novo
jogo salvo, em vez de selecionar um existente. Quando exibido, o botão
fica na parte de baixo da interface. Quando um jogador clica nesse botão, a
resposta SnapshotSelectUIResponse
é válida, mas não tem dados.
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 salvo. 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);
…
}
Detectar e resolver conflitos de dados
Quando você abre um objeto SnapshotMetadata
, o serviço de Jogos salvos detecta
se um jogo salvo em conflito existe. Conflitos de dados podem ocorrer quando o jogo
salvo no dispositivo local de um jogador está dessincronizado 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 de Jogos salvos 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 precisa realizar uma ação de resolução. Em vez disso, o jogo vai realizar uma fusão personalizada. |
SnapshotConflictPolicy::LONGEST_PLAYTIME |
Indica que o serviço Jogos salvos precisa escolher o jogo salvo com o maior valor de tempo de jogo. |
SnapshotConflictPolicy::BASE_WINS |
Indica que o serviço Jogos salvos precisa escolher o jogo salvo base. |
SnapshotConflictPolicy::REMOTE_WINS |
Indica que o serviço Jogos salvos precisa escolher o jogo salvo remotamente. 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ê tiver especificado uma política de conflito diferente de GPGSnapshotConflictPolicyManual
,
o serviço de jogos salvos vai mesclar o jogo salvo e retornar a versão atualizada
pelo valor SnapshotManager::OpenResponse
resultante. O jogo pode abrir
o jogo salvo, gravar nele e chamar o método SnapshotManager::Commit(...)
para confirmar o jogo salvo nos servidores do Google.
Realizar 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 realizar 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 SnapshotManager::OpenResponse
:
- Um
conflict_id
para identificar exclusivamente esse conflito. Você vai 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.
O jogo precisa decidir quais dados salvar e, em seguida, chamar o
método SnapshotManager::ResolveConflictBlocking()
para confirmar/resolver a versão
final nos servidores do Google.
//Resolve conflict
gpg::SnapshotManager::OpenResponse resolveResponse =
manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
openResponse.conflict_id);
Gravar jogos salvos
Para gravar um jogo salvo, primeiro abra o objeto SnapshotMetadata
que representa
esse jogo salvo, 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 escolha a base para garantir que todos os conflitos sejam resolvidos.
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 salvo que inclua os dados de 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 salvamento do jogo que você está armazenando. A mudança também contém outros metadados do jogo salvo, como o tempo de jogo e uma descrição.
Se a operação de confirmação for concluída, os jogadores poderão ver o jogo salvo na interface de seleção de jogos salvos.