2014-05-24 65 views
4

我正在開發一款使用Google Play遊戲服務的Android遊戲。Google Play遊戲服務解鎖成就 - 每次在遊戲中存儲解鎖或解鎖()?

當玩家達到例如10000點時,成就獲得解鎖。 所以當玩家達到10000點,我打電話

Games.Achievements.unlock(...) 

的問題是,當用戶在另一場比賽再次達到10000點做什麼。我必須檢查此成就是否已解鎖,或者我可以再次調用unlock()嗎?

我知道Play Services彈出窗口只有在成就第一次解鎖後纔會顯示。但我擔心api電話的配額。如果我例如存儲從共享偏好解鎖成就,那麼我會做這樣的事情:

if(myAchievementIsLocked){ 
    Games.Achievements.unlock(...) 
} 

什麼是最佳實踐?我在看一些樣品,但沒有找到我正在尋找的答案。

回答

5

據我所知,unlock()將首先檢查當地的Play遊戲應用程序,以查看該成就是否已解鎖,並且只有在不存在時纔會將請求發送到服務器。這意味着調用unlock()已經解鎖的成就不會影響任何配額,除了第一次在設備上調用配額 - 因爲Play遊戲的設備實例可能尚未同步服務器的成就。

另一方面,可以在登錄後檢查所有成就的狀態並保留其狀態的本地副本 - 如果玩家未登錄(確實應該這樣做,以便您可以解鎖在下次登錄時獲得的成就)。除了API文檔,這個過程沒有任何文檔記載,但沒有完整的例子,所以我會在這裏給你一個:)

請確保您異步運行此方法(使用AsyncTask或單獨的線程),因爲它會需要一些時間來完成(等待來自服務器的響應)。此外,只有在玩家成功登錄後才能進行此操作 - onSignInSucceeded()是一個不錯的選擇。

更新遊戲服務遊戲11.8.0

public void loadAchievements() { 
    mAchievementsClient.load(true).addOnCompleteListener(new OnCompleteListener<AnnotatedData<AchievementBuffer>>() { 
     @Override 
     public void onComplete(@NonNull Task<AnnotatedData<AchievementBuffer>> task) { 
      AchievementBuffer buff = task.getResult().get(); 
      Log.d("BUFF", "onComplete: "); 
      int bufSize = buff.getCount(); 
      for (int i=0; i < bufSize; i++) { 
       Achievement ach = buff.get(i); 
       String id = ach.getAchievementId(); 
       boolean unlocked = ach.getState() == Achievement.STATE_UNLOCKED; 
      } 
      buff.release(); 
     } 
    }); 

較早玩發球局

public void loadAchievements() { 

    boolean fullLoad = false; // set to 'true' to reload all achievements (ignoring cache) 
    float waitTime = 60.0f; // seconds to wait for achievements to load before timing out 

    // load achievements 
    PendingResult p = Games.Achievements.load(playHelper.getApiClient(), fullLoad); 
    Achievements.LoadAchievementsResult r = (Achievements.LoadAchievementsResult)p.await(waitTime, TimeUnit.SECONDS); 
    int status = r.getStatus().getStatusCode(); 
    if (status != GamesStatusCodes.STATUS_OK) { 
     r.release(); 
     return;   // Error Occured 
    } 

    // cache the loaded achievements 
    AchievementBuffer buf = r.getAchievements(); 
    int bufSize = buf.getCount(); 
    for (int i = 0; i < bufSize; i++) { 
     Achievement ach = buf.get(i); 

     // here you now have access to the achievement's data 
     String id = ach.getAchievementId(); // the achievement ID string 
     boolean unlocked = ach.getState == Achievement.STATE_UNLOCKED; // is unlocked 
     boolean incremental = ach.getType() == Achievement.TYPE_INCREMENTAL; // is incremental 
     if (incremental) 
      int steps = ach.getCurrentSteps(); // current incremental steps 
    } 
    buf.close(); 
    r.release(); 
    } 

API documentation對這些過程的詳細信息。

所以使用這種方法可以創建成就的本地副本(只需更改for循環的內部以將成就值保存到某個本地結構)並根據需要引用它。

+1

自從我一直在尋找它之後,我已經用最新的sdk網絡電話對它進行了更新。這個答案的某些部分幫助我實現了我正在嘗試做的事情。 – axierjhtjz

1

對已經解鎖的成就調用.unlock(...)應該不成問題。我的猜測是,在.unlock(...)方法中已經有某種「檢查解鎖」的處理了。

+1

這也是我的猜測......但我在問,因爲官方文件在這個問題上並不那麼確切。 – alyo