Gespeicherte Spiele hinzufügen

In diesem Leitfaden wird beschrieben, wie Sie die Spielfortschrittsdaten eines Spielers mithilfe des Dienstes „Gespeicherte Spiele“ in einer C++-Anwendung speichern und laden können. Mit diesem Dienst können Sie den Spielfortschritt des Spielers während des Spiels automatisch laden und speichern lassen. Mit diesem Dienst können Spieler auch eine Benutzeroberfläche auslösen, um ein vorhandenes Spiel zu aktualisieren oder wiederherzustellen oder ein neues Spiel zu erstellen.

Hinweis

Falls Sie es noch nicht getan haben, kann es hilfreich sein, sich die Spielekonzepte für gespeicherte Spiele durchzulesen.

Bevor Sie mit der Saved Games API programmieren, sollten Sie Folgendes tun:

Datenformate und plattformübergreifende Kompatibilität

Gespeicherte Spiele-Daten, die Sie auf den Servern von Google speichern, müssen das Format std::vector<uint8_t> haben. Der Dienst „Gespeicherte Spiele“ übernimmt die Codierung Ihrer Daten für plattformübergreifende Kompatibilität. Android-Apps können diese Daten als Bytearray ohne plattformübergreifende Kompatibilitätsprobleme lesen.

Verwende keine plattformspezifischen Formate, wenn du ein Datenformat für deine gespeicherten Spieledaten auswählst. Wir empfehlen dringend, ein Datenformat wie XML oder JSON zu verwenden, das eine starke Unterstützung der Bibliothek auf mehreren Plattformen bietet.

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 deinem Spiel ein Bildschirm angezeigt werden, auf dem vorhandene Speicherbereiche angezeigt werden. Außerdem müssen die Spieler die Möglichkeit haben, in einem dieser Bereiche zu speichern oder sie zu laden oder ein neues gespeichertes Spiel zu erstellen. Verwenden Sie dazu die folgende Methode:

  SnapshotManager::ShowSelectUIOperation(...)

Über die UI zur Auswahl von gespeicherten Spielen können Spieler ein neues gespeichertes Spiel erstellen, Details zu vorhandenen gespeicherten Spielen ansehen 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 Standardbenutzeroberfläche für gespeicherte Spiele aufgerufen und die UI-Auswahl des Players verwaltet wird:

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

Wenn im obigen Beispiel ALLOW_CREATE_SNAPSHOT true ist und MAX_SNAPSHOTS größer ist als die tatsächliche Anzahl der Snapshots, die der Nutzer derzeit erstellt hat, wird in der Standard-Snapshot-Benutzeroberfläche eine Schaltfläche zum Erstellen eines neuen Spiels angezeigt, anstatt ein vorhandenes auszuwählen. Die Schaltfläche befindet sich unten auf der Benutzeroberfläche. Wenn ein Spieler auf diese Schaltfläche klickt, ist die Antwort SnapshotSelectUIResponse gültig, hat aber keine Daten.

Gespeicherte Spiele öffnen und lesen

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

Das folgende Beispiel zeigt, 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 Sie ein SnapshotMetadata-Objekt öffnen, erkennt der Dienst „Gespeicherte Spiele“, ob ein in Konflikt stehendes gespeichertes Spiel vorhanden ist. Datenkonflikte können auftreten, wenn das gespeicherte Spiel auf dem lokalen Gerät eines Spielers nicht mit der Remote-Version synchronisiert ist, die auf den Servern von Google gespeichert ist.

Die Konfliktrichtlinie, die Sie beim Öffnen eines gespeicherten Spiels angeben, teilt dem Dienst „Gespeicherte Spiele“ mit, wie ein Datenkonflikt automatisch gelöst werden soll. Folgende Richtlinien können verwendet werden:

Richtlinien zu Konflikten Beschreibung
SnapshotConflictPolicy::MANUAL Gibt an, dass der Dienst „Gespeicherte Spiele“ keine Lösungsaktion ausführen soll. Stattdessen wird im Spiel eine benutzerdefinierte Zusammenführung durchgeführt.
SnapshotConflictPolicy::LONGEST_PLAYTIME Gibt an, dass der Dienst für gespeicherte Spiele das Spiel mit dem größten Wert für die Spielzeit verwenden soll.
SnapshotConflictPolicy::BASE_WINS Gibt an, dass der Dienst für gespeicherte Spiele das gespeicherte Basisspiel auswählen soll.
SnapshotConflictPolicy::REMOTE_WINS Gibt an, dass der Dienst für gespeicherte Spiele das remote gespeicherte Spiel auswählen soll. Die Remote-Version 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, führt der Dienst „Gespeicherte Spiele“ das gespeicherte Spiel zusammen und gibt die aktualisierte Version über den resultierenden Wert SnapshotManager::OpenResponse zurück. Ihr Spiel kann das gespeicherte Spiel öffnen, in dieses schreiben und dann die Methode SnapshotManager::Commit(...) aufrufen, um das gespeicherte Spiel auf die Server von Google zu übertragen.

Benutzerdefinierte Zusammenführung

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

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

  • Einen conflict_id, um diesen Konflikt eindeutig zu identifizieren. Diesen Wert verwenden Sie, wenn Sie die endgültige Version des gespeicherten Spiels festschreiben.
  • Die in Konflikt stehende Basisversion des gespeicherten Spiels
  • Die in Konflikt stehende Remote-Version des gespeicherten Spiels.

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

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

Gespeicherte Spiele schreiben

Zum Schreiben eines gespeicherten Spiels öffnen Sie zuerst das SnapshotMetadata-Objekt, das das gespeicherte Spiel darstellt, lösen Sie alle Datenkonflikte und rufen Sie dann die Methode SnapshotManager::Commit() auf, um Ihre gespeicherten Spieländerungen zu speichern.

Das folgende Beispiel zeigt, wie Sie eine Änderung erstellen und ein gespeichertes Spiel mit Commit speichern können.

  1. Öffnen Sie zuerst den Snapshot, den Sie bearbeiten möchten, und prüfen Sie, ob alle Konflikte durch Auswahl der Basis behoben wurden.

    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 gespeicherte Spieländerung mit den Bilddaten, die für das Coverbild verwendet werden:

    gpg::SnapshotMetadataChange::Builder builder;
    gpg::SnapshotMetadataChange metadata_change =
        builder.SetDescription("CollectAllTheStar savedata")
                 .SetCoverImageFromPngData(pngData).Create();
    
  3. Übernehmen Sie abschließend die gespeicherten Spieländerungen.

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

    Der Parameter „data“ enthält alle gespeicherten Spieldaten. Die Änderung enthält auch zusätzliche gespeicherte Spielmetadaten, z. B. die gespielte Zeit und eine Beschreibung für das gespeicherte Spiel.

Wenn der Commit-Vorgang erfolgreich abgeschlossen wurde, können Spieler das gespeicherte Spiel in der Auswahloberfläche der gespeicherten Spiele sehen.