במדריך הזה מוסבר איך לשמור ולטעון את נתוני ההתקדמות של שחקן במשחק באמצעות שירות 'משחקים שמורים' באפליקציית C++. אפשר להשתמש שירות לטעינה ולשמירה אוטומטית של ההתקדמות במשחק של שחקן בכל שלב במהלך המשחק. השירות הזה יכול גם לאפשר לנגנים להפעיל משתמש כדי לעדכן או לשחזר משחק שמור קיים, או ליצור משחק חדש.
לפני שמתחילים
אם עדיין לא עשית זאת, מומלץ לעיין מושגים של משחקים שמורים.
לפני שמתחילים לכתוב קוד באמצעות Save 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
גדול יותר מהמספר בפועל של תמונות המצב שיש למשתמש כרגע
וממשק המשתמש המוגדר כברירת מחדל להצגת תמונת מצב מספק לנגנים לחצן ליצירת
לשמור את המשחק, במקום לבחור משחק קיים. (כשהתצוגה מוצג, הלחצן
שנמצא בחלק התחתון של ממשק המשתמש.) כשנגן לוחץ על הלחצן,
התשובה SnapshotSelectUIResponse
תקינה אבל אין בה נתונים.
פתיחה וקריאה של משחקים שמורים
כדי לגשת למשחק שמור ולקרוא או לשנות את התוכן שלו, צריך לפתוח קודם
את האובייקט SnapshotMetadata
שמייצג את המשחק השמור. בשלב הבא, קוראים
אמצעי תשלום אחד (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());
פרמטר הנתונים מכיל את כל נתוני המשחק השמורים שאתם מאחסנים. השינוי מכיל גם מטא-נתונים שמורים נוספים של המשחק, כמו שעה הופעל ותיאור של המשחק השמור.
אם פעולת ההתחייבות הושלמה בהצלחה, השחקנים יוכלו לראות המשחק השמור בממשק המשתמש של בחירת 'משחקים שמורים'.