Dem Spiel gespeicherte Spiele hinzufügen

In diesem Leitfaden erfahren Sie, wie Sie den Spielfortschritt eines Spielers mit dem Dienst „Gespeicherte Spiele“ in einer C++-Anwendung speichern und laden. Mit diesem Dienst können Sie den Spielfortschritt eines Spielers jederzeit während des Spiels automatisch laden und speichern. Mit diesem Dienst können Spieler auch eine Benutzeroberfläche aufrufen, um ein vorhandenes Spiel zu aktualisieren oder wiederherzustellen oder ein neues zu erstellen.

Hinweis

Sehen Sie sich gegebenenfalls die Spielkonzepte für gespeicherte Spiele an.

Bevor du mit der Saved Games API programmierst, solltest du Folgendes beachten:

Datenformate und plattformübergreifende Kompatibilität

Gespeicherte Spieldaten, die Sie auf den Google-Servern speichern, müssen im std::vector<uint8_t>-Format vorliegen. Der Dienst „Gespeicherte Spiele“ codiert Ihre Daten für die plattformübergreifende Kompatibilität. Android-Anwendungen können diese Daten dann als Byte-Array ohne plattformübergreifende Kompatibilitätsprobleme einlesen.

Verwenden Sie keine plattformspezifischen Formate, wenn Sie ein Datenformat für Ihre gespeicherten Spieledaten auswählen. Wir empfehlen Ihnen dringend, ein Datenformat wie XML oder JSON zu verwenden, das auf mehreren Plattformen eine umfassende Bibliotheksunterstützung bietet.

Dienst „Gespeicherte Spiele“ aktivieren

Bevor Sie den Dienst „Gespeicherte Spiele“ verwenden können, müssen Sie den Zugriff darauf aktivieren. Rufen Sie dazu EnableSnapshots() auf, wenn Sie den Dienst mit gpg::GameServices::Builder erstellen. Dadurch werden die zusätzlichen Authentifizierungsbereiche aktiviert, die für gespeicherte Spiele beim nächsten Authentifizierungsereignis erforderlich sind.

Gespeicherte Spiele anzeigen

Sie können in Ihrem Spiel eine Option anbieten, mit der Spieler gespeicherte Spiele speichern oder wiederherstellen können. Wenn Spieler diese Option auswählen, sollte in Ihrem Spiel ein Bildschirm mit vorhandenen Speicherplätzen angezeigt werden. Dort können die Spieler entweder in einem dieser Speicherplätze speichern oder einen davon laden oder einen neuen Spielstand erstellen. Gehen Sie dazu so vor:

  SnapshotManager::ShowSelectUIOperation(...)

Über die Auswahloberfläche für gespeicherte Spiele können Spieler ein neues Spiel speichern, Details zu vorhandenen gespeicherten Spielen aufrufen und vorherige gespeicherte Spiele laden.

  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);
}

Im folgenden Beispiel wird gezeigt, wie die Standard-Benutzeroberfläche für gespeicherte Spiele aufgerufen und die Auswahl des Spielers verarbeitet wird:

  service_->Snapshots().ShowSelectUIOperation(
  ALLOW_CREATE_SNAPSHOT,
  ALLOW_DELETE_SNAPSHOT,
  MAX_SNAPSHOTS,
  SNAPSHOT_UI_TITLE,
  [this](gpg::SnapshotManager::SnapshotSelectUIResponse const & response) {
  
      }

Wenn in diesem Beispiel ALLOW_CREATE_SNAPSHOT = true und MAX_SNAPSHOTS > der tatsächliche Wert der Anzahl der Snapshots ist, die der Nutzer derzeit erstellt hat, sehen Spieler in der Standard-Snapshot-Benutzeroberfläche eine Schaltfläche, um einen neuen Spielstand zu erstellen, anstatt einen vorhandenen auszuwählen. Die Schaltfläche wird unten in der Benutzeroberfläche angezeigt. Wenn ein Nutzer auf diese Schaltfläche klickt, ist die SnapshotSelectUIResponse-Antwort gültig, enthält aber keine Daten.

Gespeicherte Spiele öffnen und lesen

Wenn Sie auf ein gespeichertes Spiel zugreifen und seinen Inhalt lesen oder ändern möchten, öffnen Sie zuerst das SnapshotMetadata-Objekt, das dieses gespeicherte Spiel darstellt. Rufen Sie als Nächstes die Methode SnapshotManager::Read*() auf.

Im folgenden Beispiel wird gezeigt, wie Sie ein gespeichertes Spiel öffnen:

  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);
          
        }

Datenkonflikte erkennen und beheben

Wenn du ein SnapshotMetadata-Objekt öffnest, erkennt der Dienst für gespeicherte Spiele, ob ein Konflikt mit einem anderen gespeicherten Spiel besteht. Datenkonflikte können auftreten, wenn das auf dem lokalen Gerät eines Spielers gespeicherte Spiel nicht mit der Remoteversion synchronisiert ist, die auf den Google-Servern gespeichert ist.

Die Konfliktrichtlinie, die Sie beim Öffnen eines gespeicherten Spiels angeben, gibt dem Dienst „Gespeicherte Spiele“ an, wie ein Datenkonflikt automatisch gelöst werden soll. Die Richtlinie kann eine der folgenden sein:

Richtlinie zu Konflikten Beschreibung
SnapshotConflictPolicy::MANUAL Gibt an, dass der Dienst „Gespeicherte Spiele“ keine Maßnahmen zur Problembehebung ausführen soll. Stattdessen wird in Ihrem Spiel eine benutzerdefinierte Zusammenführung durchgeführt.
SnapshotConflictPolicy::LONGEST_PLAYTIME Gibt an, dass der Dienst für gespeicherte Spiele das gespeicherte Spiel mit der längsten Spielzeit auswählen soll.
SnapshotConflictPolicy::BASE_WINS Gibt an, dass der Dienst „Gespeicherte Spiele“ das Basisspiel auswählen soll.
SnapshotConflictPolicy::REMOTE_WINS Gibt an, dass der Dienst „Gespeicherte Spiele“ das extern gespeicherte Spiel auswählen soll. Die Remoteversion ist eine Version des gespeicherten Spiels, die auf einem der Geräte des Spielers erkannt wird und einen neueren Zeitstempel als die Basisversion hat.

Wenn Sie eine andere Konfliktrichtlinie als GPGSnapshotConflictPolicyManual angegeben haben, wird das gespeicherte Spiel vom Dienst für gespeicherte Spiele zusammengeführt und die aktualisierte Version über den resultierenden SnapshotManager::OpenResponse-Wert zurückgegeben. Ihr Spiel kann das gespeicherte Spiel öffnen, darauf schreiben und dann die Methode SnapshotManager::Commit(...) aufrufen, um das gespeicherte Spiel auf den Google-Servern zu speichern.

Benutzerdefinierte Zusammenführung ausführen

Wenn Sie SnapshotConflictPolicy::MANUAL als Konfliktrichtlinie angegeben haben, muss Ihr Spiel alle erkannten Datenkonflikte beheben, bevor weitere Lese- oder Schreibvorgänge für das gespeicherte Spiel ausgeführt werden.

Wenn in diesem Fall ein Datenkonflikt erkannt wird, gibt der Dienst die folgenden Parameter über SnapshotManager::OpenResponse zurück:

  • Eine conflict_id, um diesen Konflikt eindeutig zu identifizieren (Sie verwenden diesen Wert, wenn Sie die endgültige Version des gespeicherten Spiels committen);
  • Die in Konflikt stehende Basisversion des gespeicherten Spiels
  • Die in Konflikt stehende Remoteversion des gespeicherten Spiels.

Ihr Spiel muss entscheiden, welche Daten gespeichert werden sollen, und dann die Methode SnapshotManager::ResolveConflictBlocking() aufrufen, um die endgültige Version auf den Google-Servern zu committen/aufzulösen.

    //Resolve conflict
    gpg::SnapshotManager::OpenResponse resolveResponse =
        manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
                                  openResponse.conflict_id);

Gespeicherte Spiele schreiben

Wenn Sie ein gespeichertes Spiel schreiben möchten, öffnen Sie zuerst das SnapshotMetadata-Objekt, das dieses gespeicherte Spiel darstellt, beheben Sie alle erkannten Datenkonflikte und rufen Sie dann die SnapshotManager::Commit()-Methode auf, um die Änderungen am gespeicherten Spiel zu bestätigen.

Das folgende Beispiel zeigt, wie Sie eine Änderung vornehmen und ein gespeichertes Spiel committen.

  1. Öffnen Sie zuerst den Snapshot, den Sie bearbeiten möchten, und achten Sie darauf, dass alle Konflikte behoben sind, indem Sie die Basis auswählen.

    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. Erstellen Sie als Nächstes eine Änderung für ein gespeichertes Spiel, die die Bilddaten enthält, die für das Titelbild verwendet werden:

    gpg::SnapshotMetadataChange::Builder builder;
    gpg::SnapshotMetadataChange metadata_change =
        builder.SetDescription("CollectAllTheStar savedata")
                 .SetCoverImageFromPngData(pngData).Create();
    
  3. Speichern Sie abschließend die Änderungen am Spiel.

    gpg::SnapshotManager::CommitResponse commitResponse =
        service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
    

    Der Datenparameter enthält alle gespeicherten Spieldaten. Die Änderung enthält auch zusätzliche Metadaten für gespeicherte Spiele, z. B. die Spielzeit und eine Beschreibung des gespeicherten Spiels.

Wenn der Commit-Vorgang erfolgreich abgeschlossen wurde, sehen Spieler das gespeicherte Spiel in der Auswahloberfläche für gespeicherte Spiele.