Play Games Services ל-C++‎

ה-SDK של Google Play Games Services ב-C++ מספק ממשק API ב-C++ לשימוש עם שירותי Google Play Games, והוא מיועד למפתחים שיש להם הטמעה קיימת של C++ במשחק שלהם.

נכון לעכשיו, ערכת ה-SDK מטמיעה את השירותים הבאים:

  • הרשאה
  • הישגים
  • לוחות לידרבורד
  • אירועים
  • Saved Games
  • Nearby Connections (Android בלבד)
  • נתונים סטטיסטיים של שחקנים

מושגים

באופן כללי, כדי להשתמש ב-SDK:

  1. מגדירים הגדרות פלטפורמה ל-Android.
  2. משתמשים ב-GameServices::Builder כדי להגדיר ולבנות אובייקט GameServices. האובייקט GameServices ינסה להיכנס באופן אוטומטי ויחזיר את התוצאה באמצעות קריאה חוזרת (callback) של OnAuthActionFinished(). שימו לב לתוצאה שחוזרת מהשיחה החוזרת. אם ניסיון הכניסה האוטומטי נכשל, תוכלו להציג לחצן כדי לאפשר למשתמשים להיכנס לחשבון.
  3. אחרי קבלת התוצאה OnAuthActionFinished(), אפשר להשתמש באובייקט GameServices ובמנהלים הצאצאים שלו כדי לבצע קריאות לשירותי Play Games, כולל:

    • כניסה (אחרי שההרשאה נכשלה): StartAuthorizationUI()
    • ביטול הנעילה של הישגים: Achievements().Unlock()
    • הצגת ההישגים באמצעות ממשק משתמש מובנה: Achievements().ShowAllUI()
    • שליחת תוצאה גבוהה: Leaderboards().SubmitScore()
    • יציאה מהחשבון: SignOut()
  4. כשמסיימים להשתמש באובייקט GameServices, צריך לאפס אותו או להשמיד אותו.

ברמה מפורטת יותר:

  1. אתחול של הגדרות פלטפורמה: אובייקט שמכיל מידע על אתחול ספציפי לפלטפורמה. ב-Android, הגדרת הפלטפורמה מכילה את Java VM ואת הפונקציה Activity הנוכחית:

    // In android_main(), create a platform configuration
    // and bind the object activity.
    // Alternately, attach the activity in JNI_Onload().
    gpg::AndroidPlatformConfiguration platform_configuration;
    platform_configuration.SetActivity(state->activity->clazz);
    
  2. יוצרים אובייקט GameServices: האובייקט הזה הוא נקודת הכניסה הראשית לפונקציונליות של Google Play Games Services. מכונות GameServices נוצרות באמצעות GameServices::Builder.

    ברוב הטמעות, אובייקט GameServices מסוים יישאר כל עוד סביבת C שלכם קיימת. אין צורך לאתחל אותו מחדש כש-Activity ב-Android מושהה וממשיך.

    // Creates a GameServices object that has lambda callbacks.
    game_services_ = gpg::GameServices::Builder()
            .SetDefaultOnLog(gpg::LogLevel::VERBOSE)
            .SetOnAuthActionStarted([started_callback](gpg::AuthOperation op) {
                is_auth_in_progress_ = true;
                started_callback(op);
            })
            .SetOnAuthActionFinished([finished_callback](gpg::AuthOperation op,
                                                         gpg::AuthStatus status) {
                LOGI("Sign in finished with a result of %d", status);
                is_auth_in_progress_ = false;
                finished_callback(op, status);
            })
            .Create(pc);
    
  3. משתמשים ב-Manager classes כדי לנהל את האובייקט GameServices. הגישה למנהלים מתבצעת ממכונת GameServices ומקבץ את הפונקציונליות הקשורה לקבוצות. דוגמאות לכך כוללות את מנהלי ההישגים ואת לוחות הדירוג. הם לא מכילים מצב שגלוי למשתמשים. המנהלים מוחזרים לפי הפניה, והמכונה המכילה את GameServices שולטת במחזור החיים שלהם. הלקוח שלכם אף פעם לא צריך לשמור על פרטי כניסה לחשבון ניהול. במקום זאת, הלקוח צריך לשמור את המכונה GameServices.

    מנהלי מודולים מחזירים נתונים באמצעות אובייקטים מסוג ערך בלתי ניתן לשינוי. הערכים האלה משקפים תצוגה עקבית של נתוני הבסיס בנקודת הזמן שבה בוצעה השאילתה.

    // Submit a high score
    game_services_->Leaderboards().SubmitScore(leaderboard_id, score);
    
    // Show the default Achievements UI
    game_services_->Achievements().ShowAllUI();
    
  4. כשמסיימים להשתמש באובייקט GameServices, צריך לבצע ניקוי על ידי קריאה ל-reset() ב-unique_ptr שבבעלותו, או לאפשר ל-unique_ptr להשמיד אותו באופן אוטומטי כשהוא יוצא מההיקף.

מודל של שרשור

אלא אם צוין אחרת, לכל השיטות של GameServices ושל Manager יש הטמעות אסינכרוניות ללא סיכון לשרשור (thread-safe). אפשר להפעיל אותן בכל חוט ללא נעילת צדדים חיצוניים, והן יפעלו בסדר שתואם לסדר ההפעלה שלהן.

יש שתי וריאציות עיקריות של שיטות גישה (אלה שקוראות את המצב). הסוג הראשון של שיטות (עם שמות כמו FetchProperty()) מספק את התוצאות שלו באופן אסינכרוני ל-callback שסופק. הסוג השני (עם שמות כמו FetchPropertyBlocking()) מחזיר את התוצאות שלו באופן סינכרוני לשרשור הקורא.

// Blocking callback
gpg::AchievementManager::FetchAllResponse fetchResponse =
        game_services_->Achievements().FetchAllBlocking(std::chrono::milliseconds(1000));

// Non-blocking callback
game_services_->Achievements().FetchAll(gpg::DataSource::CACHE_OR_NETWORK,
    [] (gpg::AchievementManager::FetchAllResponse response) {
    LogI("Achievement response status: %d", response.status);});

כל הקריאות החוזרות של המשתמשים מופעלות בשרשור ייעודי. ה-thread הזה עשוי להיות שונה מכל מושג פלטפורמה של 'thread ראשי' או 'thread של ממשק משתמש'. כדאי גם לוודא שהפעלת קריאות החזרה (callbacks) של המשתמשים מתבצעת במהירות. שרשור של קריאת חזרה שנתקע עלול לגרום לבעיות שגלויות למשתמשים (לדוגמה, עיכוב בהשלמת בקשת יציאה).

מידע ספציפי לפלטפורמה

כדי להתחיל להשתמש ב-Play Games C++ SDK ב-Android, אפשר להמשיך למדריך למתחילים.

מקורות מידע נוספים

מומלץ לקרוא את מסמכי התיעוד של הכיתה שכלולים ב-Google Play Game Services C++ SDK כדי לקבל פרטים נוספים, ולעיין בדוגמאות שממחישות איך משתמשים ב-SDK.

אם המשחק שלכם משתמש בשרת לקצה העורפי, תוכלו לעיין במאמר הפעלת גישה בצד השרת לשירותי Google Play Games.