בעקבות הוצאה משימוש של Google Sign-In API, אנחנו מסירים את ה-SDK בגרסה Games v1 בשנת 2026. אחרי פברואר 2025, לא תהיה לך אפשרות לפרסם ב-Google Play משחקים ששולבו לאחרונה עם ה-SDK בגרסה Games v1. מומלץ להשתמש ב-SDK בגרסה Games v2.
משחקים קיימים עם שילובים קודמים של Games v1 ימשיכו לפעול למשך כמה שנים, אבל מומלץ לעבור לגרסה 2 החל מיוני 2025.
המדריך הזה מיועד לשימוש ב-Play Games Services SDK בגרסה 1. C++ SDK for
Play Games Services v2 עדיין לא זמין.
במדריך הזה מוסבר איך לשמור ולטעון נתוני התקדמות של שחקן במשחק באמצעות שירות המשחקים השמורים באפליקציית C++. אתם יכולים להשתמש בשירות הזה כדי לטעון ולשמור באופן אוטומטי את ההתקדמות של השחקנים במשחק בכל שלב במהלך המשחק. השירות הזה יכול גם לאפשר לשחקנים להפעיל ממשק משתמש כדי לעדכן או לשחזר משחק שמור קיים, או ליצור משחק שמור חדש.
לפני שמתחילים
אם עדיין לא עשיתם זאת, כדאי לעיין במושגים בנושא משחקים שמורים.
לפני שמתחילים לכתוב קוד באמצעות Saved Games API:
- מתקינים את C++ Play Games SDK.
- הגדרת סביבת הפיתוח בשפת C++
- מורידים את קוד ה-C++ לדוגמה ובודקים אותו.
- מפעילים את שירות המשחקים השמורים ב-Google Play Console.
פורמטים של נתונים ותאימות בין פלטפורמות
נתוני משחקים שמורים שאתם שומרים בשרתים של Google צריכים להיות בפורמט std::vector<uint8_t>. שירות המשחקים השמורים דואג לקידוד הנתונים שלכם לצורך תאימות בין פלטפורמות שונות. אפליקציות ל-Android יכולות לקרוא את אותם נתונים כמערך בייטים בלי בעיות תאימות בין פלטפורמות.
כשבוחרים פורמט נתונים לנתוני המשחקים השמורים, מומלץ להימנע משימוש בפורמטים ספציפיים לפלטפורמה. מומלץ מאוד להשתמש בפורמט נתונים כמו XML או JSON, שיש לו תמיכה חזקה בספרייה בפלטפורמות שונות.
הפעלת השירות 'משחקים שמורים'
כדי להשתמש בשירות 'משחקים שמורים', צריך קודם להפעיל את הגישה אליו. כדי לעשות את זה, מתקשרים אל EnableSnapshots() כשיוצרים את השירות באמצעות gpg::GameServices::Builder. באירוע האימות הבא, יופעלו היקפי ההרשאות הנוספים שנדרשים על ידי התכונה 'משחקים שמורים'.
הצגת משחקים שמורים
במשחק, אתם יכולים לספק לשחקנים אפשרות להפעיל שמירה או שחזור של משחקים שמורים. כששחקנים בוחרים באפשרות הזו, המשחק צריך להציג מסך עם משבצות שמירה קיימות, ולאפשר לשחקנים לשמור את המשחק באחת מהמשבצות האלה או לטעון משחק שמור מאחת מהמשבצות האלה, או ליצור משחק שמור חדש. כדי לעשות זאת, משתמשים בשיטה הבאה:
SnapshotManager::ShowSelectUIOperation(...)
ממשק המשתמש של בחירת המשחקים השמורים מאפשר לשחקנים ליצור משחק שמור חדש, לראות פרטים על משחקים שמורים קיימים ולטעון משחקים שמורים קודמים.
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);
}
בדוגמה הבאה מוצג איך להציג את ממשק המשתמש של ברירת המחדל של משחקים שמורים ולטפל בבחירת ממשק המשתמש של השחקן:
service_->Snapshots().ShowSelectUIOperation(
ALLOW_CREATE_SNAPSHOT,
ALLOW_DELETE_SNAPSHOT,
MAX_SNAPSHOTS,
SNAPSHOT_UI_TITLE,
[this](gpg::SnapshotManager::SnapshotSelectUIResponse const & response) {
…
}
אם בדוגמה שלמעלה, ALLOW_CREATE_SNAPSHOT הוא true ו-MAX_SNAPSHOTS גדול ממספר קובצי ה-snapshot שהמשתמש יצר בפועל, ממשק המשתמש של ה-snapshot מספק לשחקנים לחצן ליצירת שמירה חדשה של המשחק, במקום לבחור שמירה קיימת. (כשהלחצן מוצג, הוא מופיע בתחתית ממשק המשתמש). כששחקן לוחץ על הלחצן הזה, התגובה SnapshotSelectUIResponse תקינה אבל לא מכילה נתונים.
פתיחה וקריאה של משחקים שמורים
כדי לגשת למשחק שמור ולקרוא או לשנות את התוכן שלו, קודם צריך לפתוח את האובייקט SnapshotMetadata שמייצג את המשחק השמור. לאחר מכן, מפעילים את ה-method SnapshotManager::Read*().
בדוגמה הבאה אפשר לראות איך פותחים משחק שמור:
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);
…
}
זיהוי ופתרון של סתירות בנתונים
כשפותחים אובייקט SnapshotMetadata, שירות המשחקים השמורים בודק אם קיים משחק שמור שמתנגש עם האובייקט. יכול להיות שיהיו התנגשויות בנתונים אם המשחק השמור שמאוחסן במכשיר המקומי של השחקן לא מסונכרן עם הגרסה המרוחקת שמאוחסנת בשרתי Google.
מדיניות הטיפול בקונפליקטים שאתם מציינים כשאתם פותחים משחק שמור, קובעת איך שירות המשחקים השמורים יפתור באופן אוטומטי קונפליקט בנתונים. המדיניות יכולה להיות אחת מהאפשרויות הבאות:
| מדיניות בנושא קונפליקטים | תיאור |
|---|---|
SnapshotConflictPolicy::MANUAL |
מציין ששירות המשחקים השמורים לא צריך לבצע פעולת פתרון. במקום זאת, המשחק יבצע מיזוג בהתאמה אישית. |
SnapshotConflictPolicy::LONGEST_PLAYTIME |
מציין ששירות המשחקים השמורים צריך לבחור את המשחק השמור עם ערך זמן המשחק הגדול ביותר. |
SnapshotConflictPolicy::BASE_WINS |
מציין ששירות המשחקים השמורים צריך לבחור את המשחק השמור הבסיסי. |
SnapshotConflictPolicy::REMOTE_WINS |
מציין ששירות המשחקים השמורים צריך לבחור את המשחק השמור המרוחק. הגרסה המרוחקת היא גרסה של המשחק השמור שמזוהה באחד מהמכשירים של השחקן, וחותמת הזמן שלה עדכנית יותר מזו של גרסת הבסיס. |
אם ציינתם מדיניות אחרת לטיפול בסתירות ולא GPGSnapshotConflictPolicyManual, שירות המשחקים השמורים ימזג את המשחק השמור ויחזיר את הגרסה המעודכנת באמצעות הערך SnapshotManager::OpenResponse שיתקבל. המשחק יכול לפתוח את המשחק השמור, לכתוב בו ואז לקרוא לשיטה SnapshotManager::Commit(...) כדי לשמור את המשחק בשרתי Google.
ביצוע מיזוג מותאם אישית
אם ציינתם SnapshotConflictPolicy::MANUAL כמדיניות לפתרון קונפליקטים, המשחק צריך לפתור כל קונפליקט נתונים שזוהה לפני ביצוע פעולות קריאה או כתיבה נוספות במשחק השמור.
במקרה כזה, כשמזוהה התנגשות בנתונים, השירות מחזיר את הפרמטרים הבאים דרך SnapshotManager::OpenResponse:
conflict_idכדי לזהות באופן ייחודי את הקונפליקט הזה (תשתמשו בערך הזה כשמבצעים קומיט של הגרסה הסופית של המשחק השמור);- גרסת הבסיס המתנגשת של המשחק השמור; ו
- הגרסה המרוחקת של המשחק השמור שמתנגשת עם הגרסה המקומית.
המשחק צריך להחליט אילו נתונים לשמור, ואז להפעיל את השיטה
SnapshotManager::ResolveConflictBlocking() כדי לבצע או לפתור את הגרסה הסופית בשרתים של Google.
//Resolve conflict
gpg::SnapshotManager::OpenResponse resolveResponse =
manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
openResponse.conflict_id);
כתיבת משחקים שמורים
כדי לכתוב משחק שמור, קודם פותחים את האובייקט SnapshotMetadata שמייצג את המשחק השמור, פותרים את כל הסתירות בנתונים שזוהו ואז קוראים לשיטה SnapshotManager::Commit() כדי לבצע את השינויים במשחק השמור.
בדוגמה הבאה אפשר לראות איך יוצרים שינוי ומבצעים קומיט של משחק שמור.
קודם פותחים את התמונה המהירה שרוצים לערוך ומוודאים שכל הקונפליקטים נפתרו על ידי בחירת הבסיס.
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 } });לאחר מכן, יוצרים שינוי במשחק השמור שכולל את נתוני התמונה שמשמשים לתמונת השער:
gpg::SnapshotMetadataChange::Builder builder; gpg::SnapshotMetadataChange metadata_change = builder.SetDescription("CollectAllTheStar savedata") .SetCoverImageFromPngData(pngData).Create();לבסוף, מאשרים את השינויים במשחק השמור.
gpg::SnapshotManager::CommitResponse commitResponse = service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());פרמטר הנתונים מכיל את כל הנתונים של שמירת המשחק שאתם מאחסנים. השינוי כולל גם מטא-נתונים נוספים של המשחק השמור, כמו זמן המשחק ותיאור של המשחק השמור.
אם פעולת השמירה הושלמה בהצלחה, השחקנים יכולים לראות את המשחק השמור בממשק המשתמש של בחירת המשחקים השמורים.