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

Hướng dẫn này trình bày cách lưu và tải dữ liệu tiến trình chơi của người chơi bằ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 tại bất kỳ thời điểm 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ạn bắt đầu lập trình bằng API Trò chơi đã lưu:

Đị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ã hoá dữ liệu của bạn để tương thích trên nhiều nền tảng; các ứng dụng Android có thể đọc cùng dữ liệu này dưới dạng một mảng byte mà không gặp vấn đề gì 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 định dạng dữ liệu cho dữ liệu Trò chơi đã lưu. Bạn nên sử dụng một định dạng dữ liệu, chẳng hạn như XML hoặc JSON, có khả năng hỗ trợ thư viện mạnh mẽ trên nhiều nền tảng.

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

Trước khi 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 tại sự kiện xác thực tiếp theo.

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

Trong trò chơi của mình, 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 của bạn sẽ hiển thị một màn hình cho thấy các vị trí lưu hiện có và cho phép người chơi lưu vào hoặc tải từ một trong các vị trí này, hoặc tạo một trò chơi đã lưu mới. Hãy sử dụng phương thức sau để thực hiện việc này:

  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 đây minh hoạ cách hiển thị giao diện người dùng Trò chơi đã lưu mặc định và xử lý lựa chọn giao diện người dùng của người chơi:

  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 Ảnh chụp nhanh mặc định sẽ cung cấp cho người chơi một nút để tạo một trò chơi đã lưu mới, thay vì chọn một trò chơi đã lưu hiện có. (Khi hiển thị, nút này nằm ở cuối 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 vào 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 biết 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ở một 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 chính sách sau:

Chính sách về xung đột Mô tả
SnapshotConflictPolicy::MANUAL Cho biết dịch vụ Trò chơi đã lưu không được thực hiện hành động phân giải. Thay vào đó, trò chơi của bạn sẽ thực hiện một hoạt động 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 mới 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, thì 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(...) để xác nhận trò chơi đã lưu vào máy chủ của Google.

Thực hiện hợp nhất tuỳ chỉnh

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

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

  • conflict_id để xác định riêng xung đột này (bạn sẽ sử dụng giá trị này khi xác nhận 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 cần lưu, sau đó gọi phương thức SnapshotManager::ResolveConflictBlocking() để xác nhận/giải quyết phiên bản cuối cùng cho 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

Để ghi 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 được 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 đây cho thấy cách bạn có thể tạo một thay đổi và xác nhậ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 tất cả xung đột đều đượ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 một thay đổi trò chơi đã lưu bao gồm dữ liệu hình ảnh dùng cho hình ả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 các thay đổi đối với trò chơi đã lưu.

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

    Tham số dữ liệu 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 bổ sung của trò chơi đã lưu, chẳng hạn như thời gian chơi và nội dung mô tả trò chơi đã lưu.

Nếu thao tác xác nhận 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 lựa chọn Trò chơi đã lưu.