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 Integrationen für Spiele v1 funktionieren zwar noch einige Jahre, aber wir empfehlen Ihnen, ab Juni 2025 zu Version 2 zu migrieren.
In diesem Leitfaden wird die Verwendung des Play Games Services SDK V1 beschrieben. Das C++ SDK für Play Games Services 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

Falls Sie es noch nicht getan haben, sollten Sie sich mit den Grundlagen für gespeicherte Spiele vertraut machen.

Bevor Sie mit der Programmierung mit der Saved Games API beginnen:

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. Verwenden Sie dazu die folgende Methode:

  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 Standard-Benutzeroberfläche für gespeicherte Spiele aufgerufen und die Auswahl des Spielers auf der Benutzeroberfläche 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 die Schaltfläche angezeigt wird, befindet sie sich 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 repräsentiert. 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, gibt dem Dienst „Gespeicherte Spiele“ an, 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 Konfliktrichlinie 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 den Servern von Google zu speichern.

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.

In Ihrem Spiel muss festgelegt werden, 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. zu übernehmen.

    //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 ü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. Erstelle 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 abschließend die gespeicherten Ä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 Metadaten zu gespeicherten Spielen, 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.