Adicionar jogos salvos ao jogo

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:

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.

  1. 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
            }
          });
    
  2. 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();
    
  3. 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.