সংরক্ষিত গেম

এই নির্দেশিকাটি আপনাকে দেখাবে কিভাবে C++ SDK-তে Google Play Games Services দ্বারা প্রদত্ত স্ন্যাপশট API ব্যবহার করে সংরক্ষিত গেম বাস্তবায়ন করতে হয়। এই API-গুলো PgsSnapshotsClient এ পাওয়া যাবে।

শুরু করার আগে

  • এই বৈশিষ্ট্যটি সম্পর্কে জানতে, সংরক্ষিত গেমসমূহ দেখুন।
  • Google Play Games Services ব্যবহার করার জন্য আপনার অ্যাপ ইনস্টল ও সেট আপ করতে 'Set Up Google Play services SDK' গাইডে দেওয়া নির্দেশাবলী অনুসরণ করুন।

  • Google Play Console গাইডের নির্দেশনাগুলো অনুসরণ করে আপনার গেমের জন্য সেভ করা গেমের সাপোর্ট নির্ধারণ করুন।

  • গুণমান চেকলিস্টে বর্ণিত সুপারিশগুলো ভালোভাবে জেনে নিন।

স্ন্যাপশট ক্লায়েন্টটি পান

স্ন্যাপশট এপিআই ব্যবহার শুরু করতে, আপনার গেমকে প্রথমে একটি PgsSnapshotsClient হ্যান্ডেল পেতে হবে। অ্যান্ড্রয়েড অ্যাক্টিভিটি পাস করে PgsSnapshotsClient_create() মেথডটি কল করার মাধ্যমে আপনি এটি করতে পারেন।

দ্রষ্টব্য: C++ SDK ফাংশনগুলো কলব্যাকের মাধ্যমে অ্যাসিঙ্ক্রোনাসভাবে ফলাফল প্রদান করে।

// Assuming 'android_activity' is a jobject referencing your Android Activity
PgsSnapshotsClient* snapshots_client = PgsSnapshotsClient_create(android_activity);

// ... use the client ...

// When done, destroy the client to free resources
// PgsSnapshotsClient_destroy(snapshots_client);

সংরক্ষিত গেমগুলি প্রদর্শন করুন

আপনার গেমে যেখানেই খেলোয়াড়দের তাদের অগ্রগতি সংরক্ষণ বা পুনরুদ্ধার করার বিকল্প দেওয়া হয়, সেখানেই আপনি স্ন্যাপশট এপিআই (snapshots API) সংহত করতে পারেন। উন্নয়ন সহজ করার জন্য, স্ন্যাপশট এপিআই একটি ডিফল্ট সংরক্ষিত গেম নির্বাচনের ইউজার ইন্টারফেস (UI) প্রদান করে। এই UI চালু করতে, PgsSnapshotsClient_showSelectSnapshotUI কল করুন।

// Callback function to handle the result of showing the UI
void OnShowSavedGamesUI(PgsStatusCode status_code, void* user_data) {
  if (status_code == PGS_STATUS_SUCCESS) {
    // UI was shown successfully. The player can now interact with it.
    // The game doesn't receive direct data back from this callback about
    // which snapshot was selected. Your game should typically provide options
    // to load or open snapshots by name after the UI is dismissed.
  } else {
    // Handle error or failure to show UI
  }
}

// Function to show the default Saved Games UI
void ShowSavedGamesUI(PgsSnapshotsClient* client, jobject activity) {
  const char* title = "See My Saves";
  bool allow_add_button = true;
  bool allow_delete_button = true;
  int max_snapshots = 5;

  PgsSnapshotsClient_showSelectSnapshotUI(
      client,
      activity,
      title,
      allow_add_button,
      allow_delete_button,
      max_snapshots,
      OnShowSavedGamesUI,
      NULL // user_data
  );
}

// Example usage:
// ShowSavedGamesUI(snapshots_client, android_activity);

সংরক্ষিত গেম লিখুন

সংরক্ষিত গেমে বিষয়বস্তু সংরক্ষণ করতে:

  1. PgsSnapshotsClient_open() ব্যবহার করে অ্যাসিঙ্ক্রোনাসভাবে একটি স্ন্যাপশট খুলুন। যদি আপনি একটি নতুন সেভ তৈরি করতে চান, তাহলে create_if_not_found true হিসেবে উল্লেখ করুন।
  2. ফলাফলটি PgsSnapshotsClient_OpenCallback এ প্রদান করা হয়। সফল হলে এবং কোনো দ্বন্দ্ব না থাকলে, আপনি একটি PgsSnapshot* পাবেন।
  3. যে ডেটা সংরক্ষণ করতে চান, তা একটি বাইট অ্যারে ( uint8_t* ) হিসেবে প্রস্তুত করুন।
  4. সংরক্ষণটি বর্ণনা করার জন্য একটি PgsSnapshotMetadataChange* অবজেক্ট তৈরি করুন।
  5. Google-এর সার্ভারে পরিবর্তনগুলো পাঠাতে PgsSnapshotsClient_commitAndClose কল করুন।

    // Callback for commitAndClose
    void OnSnapshotCommitted(PgsStatusCode status_code, PgsSnapshotMetadata* metadata, void* user_data) {
        if (status_code == PGS_STATUS_SUCCESS) {
        // Save successful
        if (metadata) {
        // Metadata for the committed snapshot
        PgsSnapshotMetadata_Release(metadata);
      }
    } else {
        // Handle error
      }
    }
    
    // Function to write data to a snapshot
    void WriteSnapshot(PgsSnapshotsClient* client, PgsSnapshot* snapshot,
                   const uint8_t* data, size_t data_size,
                   const char* description /*, Bitmap coverImage */) {
    
    PgsSnapshotMetadataChange* metadataChange = NULL; // Placeholder
    
      // Commit the operation
      PgsSnapshotsClient_commitAndClose(
          client,
          snapshot,
          metadataChange,
          data,
          data_size,
          OnSnapshotCommitted,
          NULL // user_data
      );
    
      // if (metadataChange) PgsSnapshotMetadataChange_Release(metadataChange);
    }
    
    // Callback for opening the snapshot before writing
    void OnSnapshotOpenForWrite(PgsStatusCode status_code,
                            PgsSnapshot* snapshot,
                            PgsSnapshotConflict* conflict,
                            void* user_data) {
      if (status_code == PGS_STATUS_SUCCESS) {
        if (snapshot) {
          // Successfully opened/created. Now write to it.
         const char* save_data_str = "MY_GAME_SAVE_DATA";
         const uint8_t* data = (const uint8_t*)save_data_str;
         size_t data_size = strlen(save_data_str);
    
          WriteSnapshot((PgsSnapshotsClient*)user_data, snapshot, data, data_size, "My Save Description");
          // PgsSnapshot_destroy(snapshot) is likely called after commitAndClose by the SDK
        } else if (conflict) {
          // Handle conflict before writing, or open with a policy that auto-resolves.
          PgsSnapshotConflict_destroy(conflict);
        }
      } else {
        // Handle error opening
      }
    }
    
    // Example: Open and write to a snapshot
    void OpenAndWriteExample(PgsSnapshotsClient* client, const char* snapshot_name) {
    PgsSnapshotsClient_open(
      client,
      snapshot_name,
      true, // create_if_not_found
      kPgsSnapshotConflictPolicyManual, // Or another policy
      OnSnapshotOpenForWrite,
      client // user_data
    );
    }

সংরক্ষিত গেম লোড করুন

সংরক্ষিত গেম পুনরুদ্ধার করতে:

  1. PgsSnapshotsClient_open() ব্যবহার করে নাম দিয়ে অ্যাসিঙ্ক্রোনাসভাবে স্ন্যাপশটটি খুলুন।
  2. PgsSnapshotsClient_OpenCallback এ, সফল হলে, ডেটা অ্যাক্সেস করুন। এপিআই-টি uint8_t* ডেটা এবং সাইজ পাওয়ার একটি উপায় প্রদান করে, যদিও PgsSnapshot বা এর সাথে যুক্ত PgsSnapshotContents থেকে বাইট পড়ার পদ্ধতি এই ডকুমেন্টে বিস্তারিতভাবে বর্ণনা করা হয়নি।

    // Assuming functions exist to read data from PgsSnapshotContents
    // For example, PgsSnapshotContents* PgsSnapshot_getContents(PgsSnapshot* snapshot);
    // For example, bool PgsSnapshotContents_readFully(PgsSnapshotContents* contents, uint8_t** out_data, size_t* out_size);
    // For example, void PgsSnapshotContents_releaseData(uint8_t* data);
    
    void OnSnapshotOpenForRead(PgsStatusCode status_code,
                           PgsSnapshot* snapshot,
                           PgsSnapshotConflict* conflict,
                           void* user_data) {
        if (status_code == PGS_STATUS_SUCCESS) {
        if (snapshot) {
        // Successfully opened. Now read from it.
        // THE FOLLOWING IS HYPOTHETICAL based on common patterns:
        // PgsSnapshotContents* contents = PgsSnapshot_getContents(snapshot);
        // uint8_t* data = NULL;
        // size_t data_size = 0;
        // if (contents && PgsSnapshotContents_readFully(contents, &data, &data_size)) {
        //   // Successfully read data
        //   Log("Snapshot data loaded, size: %zu", data_size);
        //   ... process data ...
        //   PgsSnapshotContents_releaseData(data);
        // }
        // PgsSnapshotContents_destroy(contents); // If necessary
          PgsSnapshot_destroy(snapshot);
        } else if (conflict) {
          // Handle conflict
          Log("Snapshot open resulted in a conflict.");
          PgsSnapshotConflict_destroy(conflict);
        }
      } else {
        // Handle error opening
        Log("Error while opening Snapshot: %d", status_code);
      }
    }
    
    // Example: Load a specific saved game
    void LoadSnapshotByName(PgsSnapshotsClient* client, const char* snapshot_name) {
      int conflictResolutionPolicy = kPgsSnapshotConflictPolicyMostRecentlyModified;
    
      PgsSnapshotsClient_open(
          client,
          snapshot_name,
          false, // create_if_not_found
          conflictResolutionPolicy,
          OnSnapshotOpenForRead,
          NULL // user_data
      );
    }

সংরক্ষিত গেমের দ্বন্দ্ব সমাধান করুন

যখন PgsSnapshotsClient_open কলব্যাকটি কল করা হয়, যদি conflict প্যারামিটারটি NULL না হয়, তাহলে একটি দ্বন্দ্ব ঘটেছে। দ্বন্দ্বটি সমাধান করতে PgsSnapshotsClient_resolveConflict ব্যবহার করুন।

/// @brief Asynchronously resolves a snapshot conflict.
///
/// @param snapshots_client The client handle.
/// @param conflict_id The ID of the conflict to resolve.
/// @param snapshot_id The ID of the snapshot to use for resolution.
/// @param metadata_change The metadata changes to apply to the snapshot, or
/// NULL for no changes.
/// @param contents The contents to resolve the conflict with.
/// @param callback Function to be called with result of asynchronous
/// operation. See PgsSnapshotsClient_OpenCallback.
/// @param user_data Arbitrary data pointer to be passed back to callback.
void PgsSnapshotsClient_resolveConflict(
    PgsSnapshotsClient* snapshots_client,
    const char* conflict_id,
    const char* snapshot_id,
    PgsSnapshotMetadataChange* metadata_change,
    PgsSnapshotContents* contents,
    PgsSnapshotsClient_OpenCallback callback,
    void* user_data);