يوضّح لك هذا الدليل كيفية تنفيذ الألعاب المحفوظة باستخدام واجهة برمجة التطبيقات الخاصة باللقطات التي توفّرها "خدمات ألعاب Google Play" في حزمة تطوير البرامج (SDK) بلغة ++C. يمكن العثور على واجهات برمجة التطبيقات
في PgsSnapshotsClient.
قبل البدء
- للحصول على معلومات حول الميزة، يُرجى الاطّلاع على مقالة حفظ التقدم في الألعاب.
اتّبِع التعليمات الخاصة بتثبيت تطبيقك وإعداده لاستخدام "خدمات ألعاب Google Play" في الـ دليل إعداد حزمة تطوير البرامج (SDK) لخدمات Google Play.
حدِّد إمكانية حفظ التقدم في لعبتك باتّباع التعليمات الواردة في دليل Google Play Console.
تعرَّف على الاقتراحات الموضّحة في قائمة التحقّق من الجودة.
الحصول على برنامج اللقطات
لبدء استخدام واجهة برمجة التطبيقات الخاصة باللقطات، يجب أن تحصل لعبتك أولاً على معرّف
PgsSnapshotsClient. يمكنك إجراء ذلك من خلال استدعاء طريقة
PgsSnapshotsClient_create()، مع تمرير نشاط Android.
ملاحظة: تعرض دوال حزمة تطوير البرامج (SDK) بلغة ++C النتائج بشكل غير متزامن من خلال عمليات معاودة الاتصال.
// 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);
عرض الألعاب المحفوظة
يمكنك دمج واجهة برمجة التطبيقات الخاصة باللقطات في أي مكان تتيح فيه لعبتك للاعبين خيار حفظ مستوى تقدّمهم أو استعادته.
لتبسيط عملية التطوير، توفّر واجهة برمجة التطبيقات الخاصة باللقطات واجهة مستخدم (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);
تعديل بيانات الألعاب المحفوظة
لتخزين المحتوى في لعبة محفوظة، اتّبِع الخطوات التالية:
- افتح لقطة بشكل غير متزامن باستخدام
PgsSnapshotsClient_open(). حدِّدcreate_if_not_foundعلى أنّها صحيحة إذا أردت إنشاء عملية حفظ جديدة. - يتم توفير النتيجة في الـ
PgsSnapshotsClient_OpenCallback. في حال نجاح العملية وعدم حدوث أي تعارض، ستحصل علىPgsSnapshot*. - أعِدّ البيانات التي تريد حفظها كمصفوفة بايت (
uint8_t*). - أنشئ عنصر
PgsSnapshotMetadataChange*لوصف عملية الحفظ. استدعِ
PgsSnapshotsClient_commitAndCloseلإرسال التغييرات إلى خوادم Google.// 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 ); }
تحميل الألعاب المحفوظة
لاسترداد الألعاب المحفوظة، اتّبِع الخطوات التالية:
- افتح اللقطة بشكل غير متزامن حسب الاسم باستخدام
PgsSnapshotsClient_open(). في
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);