Dem Spiel gespeicherte Spiele hinzufügen

Nach der Einstellung der Google-Anmeldung-API wird das games v1 SDK im Jahr 2026 entfernt. Ab Februar 2025 kannst du bei Google Play keine Titel mehr veröffentlichen, die neu in Games SDK V1 integriert wurden. Wir empfehlen, stattdessen das Games SDK V2 zu verwenden.
Bestehende Titel mit den vorherigen Games v1-Integrationen funktionieren zwar noch einige Jahre, aber wir empfehlen Ihnen, ab Juni 2025 zu Version 2 zu migrieren.
Dieser Leitfaden bezieht sich auf die Verwendung des Play-Spieldienste v1 SDK. Das C++ SDK für Play-Spieldienste v2 ist noch nicht verfügbar.

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

Hinweis

Wir empfehlen Ihnen, sich mit den Konzepten für gespeicherte Spiele vertraut zu machen, sofern Sie dies nicht schon getan haben.

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

Datenformate und plattformübergreifende Kompatibilität

Gespeicherte Spieldaten, die Sie auf den Google-Servern speichern, müssen das Format std::vector<uint8_t> haben. Der Dienst „Gespeicherte Spiele“ übernimmt die Codierung Ihrer Daten für die plattformübergreifende Kompatibilität. Android-Anwendungen können diese Daten als Byte-Array ohne Probleme bei der plattformübergreifenden Kompatibilität lesen.

Vermeiden Sie plattformspezifische Formate, wenn Sie ein Datenformat für Ihre gespeicherten Spieldaten auswählen. Wir empfehlen dringend, ein Datenformat wie XML oder JSON zu verwenden, das auf mehreren Plattformen gut unterstützt wird.

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 Autorisierungsbereiche, die für gespeicherte Spiele erforderlich sind, beim nächsten Autorisierungsereignis aktiviert.

Gespeicherte Spiele anzeigen

In Ihrem Spiel können Sie 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. Spieler sollten dann entweder in einem dieser Speicherplätze speichern oder aus einem dieser Speicherplätze laden oder ein neues gespeichertes Spiel erstellen können. Gehen Sie dazu so vor:

  SnapshotManager::ShowSelectUIOperation(...)

In der Benutzeroberfläche für gespeicherte Spiele können Spieler ein neues gespeichertes Spiel erstellen, Details zu vorhandenen gespeicherten Spielen aufrufen und frühere 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);
}

Das folgende Beispiel zeigt, wie die standardmäßige UI für gespeicherte Spiele aufgerufen und die Auswahl des Spielers in der UI verarbeitet 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 gleich true ist und MAX_SNAPSHOTS größer als die tatsächliche Anzahl der Snapshots ist, die der Nutzer derzeit erstellt hat, bietet die Standard-Snapshot-Benutzeroberfläche den Spielern eine Schaltfläche zum Erstellen eines neuen Speicherstands an, anstatt einen vorhandenen auszuwählen. (Wenn sie angezeigt wird, befindet sich die Schaltfläche unten auf der Benutzeroberfläche.) Wenn ein Spieler 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, müssen Sie zuerst das SnapshotMetadata-Objekt öffnen, das dieses gespeicherte Spiel darstellt. Rufen Sie als Nächstes die Methode SnapshotManager::Read*() auf.

Das folgende Beispiel zeigt, wie ein gespeichertes Spiel geöffnet wird:

  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 gespeichertes Spiel mit Konflikten vorhanden ist. Datenkonflikte können auftreten, wenn das auf dem lokalen Gerät eines Spielers gespeicherte Spiel nicht mit der Remote-Version auf den Google-Servern synchronisiert ist.

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

Konfliktrichlinie Beschreibung
SnapshotConflictPolicy::MANUAL Gibt an, dass der Dienst „Gespeicherte Spiele“ keine Auflösungsaktion ausführen soll. Stattdessen wird in Ihrem Spiel ein benutzerdefinierter Merge ausgeführt.
SnapshotConflictPolicy::LONGEST_PLAYTIME Gibt an, dass der Dienst „Gespeicherte Spiele“ das gespeicherte Spiel mit dem größten Wert für die Spielzeit auswählen soll.
SnapshotConflictPolicy::BASE_WINS Gibt an, dass der Dienst „Gespeicherte Spiele“ das grundlegende gespeicherte Spiel auswählen soll.
SnapshotConflictPolicy::REMOTE_WINS Gibt an, dass der Dienst „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 aktuelleren 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 SnapshotManager::OpenResponse-Wert zurück. Ihr Spiel kann das gespeicherte Spiel öffnen, Daten hineinschreiben und dann die Methode SnapshotManager::Commit(...) aufrufen, um das gespeicherte Spiel auf die Server von Google zu übertragen.

Benutzerdefinierten Merge durchfü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 zur eindeutigen Identifizierung dieses Konflikts (diesen Wert verwenden Sie beim Committen der endgültigen Version des gespeicherten Spiels).
  • Die in Konflikt stehende Basisversion des gespeicherten Spiels und
  • Die in Konflikt stehende Remote-Version 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 speichern.

    //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 Methode SnapshotManager::Commit() auf, um die Änderungen am gespeicherten Spiel zu übernehmen.

Das folgende Beispiel zeigt, wie Sie eine Änderung erstellen und ein gespeichertes Spiel übertragen.

  1. Öffnen Sie zuerst den Snapshot, den Sie bearbeiten möchten, und sorgen Sie dafür, dass alle Konflikte durch Auswahl der Basis behoben werden.

    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 des gespeicherten Spiels, die die für das Titelbild verwendeten Bilddaten enthält:

    gpg::SnapshotMetadataChange::Builder builder;
    gpg::SnapshotMetadataChange metadata_change =
        builder.SetDescription("CollectAllTheStar savedata")
                 .SetCoverImageFromPngData(pngData).Create();
    
  3. Übernehmen Sie schließlich die Änderungen am gespeicherten Spiel.

    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 Metadaten zum gespeicherten Spiel, z. B. die Spieldauer und eine Beschreibung des gespeicherten Spiels.

Wenn der Commit-Vorgang erfolgreich abgeschlossen wurde, können Spieler das gespeicherte Spiel in der Benutzeroberfläche zur Auswahl gespeicherter Spiele sehen.