【问题标题】:Google Play Game Services unlock achievement - store unlock in game or call unlock() every time?Google Play 游戏服务解锁成就 - 在游戏中存储解锁或每次调用 unlock()?
【发布时间】:2014-05-24 17:46:26
【问题描述】:

我正在开发一款使用 Google Play 游戏服务的 Android 游戏。

当玩家达到例如 10000 点时,成就会被解锁。 所以当玩家达到 10000 点时,我会调用

Games.Achievements.unlock(...)

问题是当用户在另一场比赛中再次达到 10000 分时该怎么办。我是否必须检查此成就是否已解锁,或者我可以再次调用 unlock() 吗?

我知道只有在首次解锁成就时才会显示 Play Services 弹出窗口。但我担心 api 调用的配额。例如,如果我从共享偏好中存储成就解锁,那么我会这样做:

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

最佳做法是什么?我正在查看一些示例,但没有找到我正在寻找的答案。

【问题讨论】:

    标签: java android google-play-services


    【解决方案1】:

    据我所知,unlock() 将首先与本地 Play 游戏应用程序检查成就是否已解锁,只有在未解锁的情况下才会将请求发送到服务器。这意味着在已解锁的成就上调用 unlock() 不应影响任何配额,除非是在设备上首次调用它 - 因为设备的 Play 游戏实例可能尚未从服务器同步该成就。

    另一方面,可以在登录后检查所有成就的状态并保留其状态的本地副本 - 如果玩家未登录,您确实应该这样做(这样您就可以解锁下次登录时获得的任何成就)。除了 API 文档之外,这个过程在任何地方都没有很好的记录,但是没有完整的例子,所以我在这里给你一个:)

    确保您以异步方式运行此方法(使用AsyncTask 或单独的线程),因为它需要一些时间才能完成(等待来自服务器的响应)。此外,只有在玩家成功登录时才执行此操作 - onSignInSucceeded() 是它的好地方。

    Play Service Games 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();
            }
        });
    

    较早的 Play 服务游戏

      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 循环的内部以将成就值保存到某个本地结构)并根据需要引用它。

    【讨论】:

    • 自从我一直在寻找它以来,我已经用最新的 sdk 网络调用对其进行了更新。这个答案的某些部分帮助我实现了我想要做的事情。
    【解决方案2】:

    在已经解锁的成就上调用 .unlock(...) 应该不是问题。我的猜测是 .unlock(...) 方法中已经有某种“检查是否解锁”处理。

    【讨论】:

    • 这也是我的猜测……但我之所以这么问,是因为官方文档在这个问题上并不那么精确。
    猜你喜欢
    • 2014-01-11
    • 2014-07-08
    • 1970-01-01
    • 2023-04-01
    • 2014-12-15
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多