Thêm trò chơi đã lưu vào trò chơi của bạn

Hướng dẫn này sẽ chỉ cho bạn cách lưu và tải dữ liệu tiến trình chơi của người chơi bằng cách sử dụng dịch vụ Trò chơi đã lưu trong ứng dụng C++. Bạn có thể sử dụng dịch vụ này để tự động tải và lưu tiến trình chơi của người chơi bất cứ lúc nào trong khi chơi. Dịch vụ này cũng có thể cho phép người chơi kích hoạt giao diện người dùng để cập nhật hoặc khôi phục trò chơi đã lưu hiện có, hoặc tạo trò chơi mới.

Trước khi bắt đầu

Nếu chưa từng có kinh nghiệm, bạn có thể xem lại các khái niệm về trò chơi đã lưu.

Trước khi bắt đầu lập trình bằng API Trò chơi đã lưu, bạn hãy:

Định dạng dữ liệu và khả năng tương thích trên nhiều nền tảng

Dữ liệu trò chơi đã lưu mà bạn lưu vào máy chủ của Google phải ở định dạng std::vector<uint8_t>. Dịch vụ trò chơi đã lưu sẽ xử lý việc mã hóa dữ liệu của bạn cho khả năng tương thích trên nhiều nền tảng; các ứng dụng Android có thể đọc trong cùng dữ liệu này dưới dạng một mảng byte mà không gặp bất kỳ vấn đề nào về khả năng tương thích trên nhiều nền tảng.

Tránh sử dụng các định dạng dành riêng cho nền tảng khi chọn một định dạng dữ liệu cho dữ liệu Trò chơi đã lưu của bạn. Bạn nên sử dụng một định dạng dữ liệu, chẳng hạn như XML hoặc JSON. Định dạng này hỗ trợ thư viện hiệu quả trên nhiều nền tảng.

Bật dịch vụ Trò chơi đã lưu

Để có thể sử dụng dịch vụ Trò chơi đã lưu, trước tiên, bạn phải bật quyền truy cập vào dịch vụ này. Để thực hiện việc này, hãy gọi EnableSnapshots() khi bạn tạo dịch vụ bằng gpg::GameServices::Builder. Thao tác này sẽ bật các phạm vi xác thực bổ sung mà Trò chơi đã lưu yêu cầu vào sự kiện xác thực tiếp theo.

Hiển thị trò chơi đã lưu

Trong trò chơi, bạn có thể cung cấp một tuỳ chọn mà người chơi có thể kích hoạt để lưu hoặc khôi phục trò chơi đã lưu. Khi người chơi chọn tuỳ chọn này, trò chơi sẽ hiển thị một màn hình hiển thị các vị trí lưu hiện có, và cho phép người chơi lưu hoặc tải từ một trong các vị trí lưu này, hoặc tạo một trò chơi đã lưu mới. Hãy làm theo các bước sau:

  SnapshotManager::ShowSelectUIOperation(...)

Giao diện người dùng chọn Trò chơi đã lưu cho phép người chơi tạo trò chơi đã lưu mới, xem chi tiết về trò chơi đã lưu hiện có và tải những trò chơi đã lưu trước đó.

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

Ví dụ sau minh hoạ cách hiển thị giao diện người dùng của Trò chơi đã lưu mặc định và xử lý lựa chọn giao diện người dùng:

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

Nếu trong ví dụ trên, ALLOW_CREATE_SNAPSHOTtrueMAX_SNAPSHOTS lớn hơn số lượng ảnh chụp nhanh thực tế mà người dùng hiện đã tạo, thì giao diện người dùng mặc định sẽ cung cấp cho người chơi một nút để tạo trò chơi lưu mới, thay vì chọn trò chơi hiện có. (Khi hiển thị, nút ở dưới cùng của giao diện người dùng.) Khi người chơi nhấp vào nút này, phản hồi SnapshotSelectUIResponse sẽ hợp lệ nhưng không có dữ liệu.

Mở và đọc trò chơi đã lưu

Để truy cập một trò chơi đã lưu và đọc hoặc sửa đổi nội dung của trò chơi đó, trước tiên, hãy mở đối tượng SnapshotMetadata đại diện cho trò chơi đã lưu đó. Tiếp theo, hãy gọi phương thức SnapshotManager::Read*().

Ví dụ sau đây cho thấy cách mở một trò chơi đã lưu:

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

Phát hiện và giải quyết xung đột dữ liệu

Khi bạn mở một đối tượng SnapshotMetadata, dịch vụ Trò chơi đã lưu sẽ phát hiện xem có trò chơi đã lưu xung đột hay không. Xung đột dữ liệu có thể xảy ra khi trò chơi đã lưu trên thiết bị cục bộ của người chơi không đồng bộ với phiên bản lưu trữ từ xa trong máy chủ của Google.

Chính sách xung đột mà bạn chỉ định khi mở trò chơi đã lưu sẽ cho dịch vụ Trò chơi đã lưu biết cách tự động giải quyết xung đột dữ liệu. Chính sách có thể là một trong những trạng thái sau đây:

Chính sách xung đột Mô tả
SnapshotConflictPolicy::MANUAL Cho biết rằng dịch vụ Trò chơi đã lưu sẽ không thực hiện thao tác giải quyết nào. Thay vào đó, trò chơi của bạn sẽ thực hiện một hợp nhất tuỳ chỉnh.
SnapshotConflictPolicy::LONGEST_PLAYTIME Cho biết dịch vụ Trò chơi đã lưu sẽ chọn trò chơi đã lưu có giá trị thời gian chơi lớn nhất.
SnapshotConflictPolicy::BASE_WINS Cho biết dịch vụ Trò chơi đã lưu sẽ chọn trò chơi đã lưu cơ sở.
SnapshotConflictPolicy::REMOTE_WINS Cho biết dịch vụ Trò chơi đã lưu sẽ chọn trò chơi đã lưu từ xa. Phiên bản từ xa là phiên bản của trò chơi đã lưu được phát hiện trên một trong các thiết bị của người chơi và có dấu thời gian gần đây hơn so với phiên bản cơ sở.

Nếu bạn đã chỉ định một chính sách xung đột khác với GPGSnapshotConflictPolicyManual, dịch vụ Trò chơi đã lưu sẽ hợp nhất trò chơi đã lưu và trả về phiên bản cập nhật thông qua giá trị SnapshotManager::OpenResponse thu được. Trò chơi của bạn có thể mở trò chơi đã lưu, ghi vào trò chơi, sau đó gọi phương thức SnapshotManager::Commit(...) để gửi trò chơi đã lưu tới máy chủ của Google.

Thực hiện hợp nhất tùy chỉnh

Nếu bạn đã chỉ định SnapshotConflictPolicy::MANUAL làm chính sách xung đột, thì trò chơi của bạn phải giải quyết mọi xung đột dữ liệu đã phát hiện trước khi thực hiện thêm hoạt động đọc hoặc ghi trên trò chơi đã lưu.

Trong trường hợp này, khi phát hiện thấy xung đột dữ liệu, dịch vụ sẽ trả về các thông số sau thông qua SnapshotManager::OpenResponse:

  • conflict_id để xác định duy nhất xung đột này (bạn sẽ sử dụng giá trị này khi gửi phiên bản cuối cùng của trò chơi đã lưu);
  • Phiên bản cơ sở xung đột của trò chơi đã lưu; và,
  • Phiên bản từ xa xung đột của trò chơi đã lưu.

Trò chơi của bạn phải quyết định dữ liệu nào được lưu, sau đó gọi phương thức SnapshotManager::ResolveConflictBlocking() để gửi/giải quyết phiên bản cuối cùng cho các máy chủ của Google.

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

Viết trò chơi đã lưu

Để viết một trò chơi đã lưu, trước tiên, hãy mở đối tượng SnapshotMetadata đại diện cho trò chơi đã lưu đó, giải quyết mọi xung đột dữ liệu đã phát hiện, sau đó gọi phương thức SnapshotManager::Commit() để xác nhận các thay đổi đối với trò chơi đã lưu.

Ví dụ sau cho thấy cách bạn có thể tạo thay đổi và thực hiện trò chơi đã lưu.

  1. Trước tiên, hãy mở ảnh chụp nhanh mà chúng ta muốn chỉnh sửa và đảm bảo rằng tất cả các xung đột đã được giải quyết bằng cách chọn cơ sở.

    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. Tiếp theo, hãy tạo thay đổi đối với trò chơi đã lưu, bao gồm dữ liệu hình ảnh dùng cho ảnh bìa:

    gpg::SnapshotMetadataChange::Builder builder;
    gpg::SnapshotMetadataChange metadata_change =
        builder.SetDescription("CollectAllTheStar savedata")
                 .SetCoverImageFromPngData(pngData).Create();
    
  3. Cuối cùng, hãy xác nhận những thay đổi đối với trò chơi đã lưu.

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

    Thông số dữ liệu này chứa tất cả dữ liệu trò chơi đã lưu mà bạn đang lưu trữ. Thay đổi này cũng chứa siêu dữ liệu trò chơi đã lưu bổ sung, chẳng hạn như thời gian chơi và nội dung mô tả về trò chơi đã lưu.

Nếu thao tác cam kết hoàn tất thành công, người chơi có thể thấy trò chơi đã lưu trong giao diện người dùng chọn Trò chơi đã lưu.