简体   繁体   English

Google Play游戏服务解锁成就 - 每次都在游戏中解锁或致电解锁()?

[英]Google Play Game Services unlock achievement - store unlock in game or call unlock() every time?

I am developing an Android game which uses Google Play Game Services. 我正在开发一款使用Google Play游戏服务的Android游戏。

When a player reach for example 10000 points an achievement gets unlocked. 当玩家达到例如10000点时,成就将被解锁。 So when the player reaches 10000 points I call 所以当玩家达到10000点时我会打电话

Games.Achievements.unlock(...)

The question is what to do when the user reaches 10000 points again in another game. 问题是当用户在另一场比赛中再次达到10000分时该怎么办。 Do I have to check if this achievement is already unlocked or can I just call unlock() again? 我是否必须检查此成就是否已解锁,还是可以再次调用unlock()?

I know that the Play Services popup is diplayed only when the achievement gets first unlocked. 我知道只有在首次解锁成就时才会显示Play服务弹出窗口。 But I am concerned about the quota of api calls. 但我担心api电话的配额。 If I for example store the achievement unlock from shared preferences then I would do something like this: 如果我例如从共享偏好中存储成就解锁,那么我会做这样的事情:

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

What are the best practices? 什么是最佳做法? I was looking at some samples but didn't find the answers which I was looking for. 我正在看一些样品,但没有找到我正在寻找的答案。

As far as I can tell, unlock() will check with the local Play Games app first to see if the achievement is already unlocked, and only if it is not will it send the request to the server. 据我所知, unlock()将首先检查本地Play游戏应用程序以查看该成就是否已解锁,并且只有在不成功时它才会将请求发送到服务器。 This means that calling unlock() on an already unlocked achievement should not affect any quotas apart from the first time it is called on a device - since the device's instance of the Play Games may not have synced that achievement from the server yet. 这意味着在已经解锁的成就上调用unlock()不应该影响任何配额,除了第一次在设备上调用它 - 因为设备的Play游戏实例可能尚未从服务器同步该成就。

On the other hand, it is possible to check the state of all achievements after signing-in and keeping a local copy of their states - which indeed you should do if the player is NOT signed-in (so that you can unlock any achievements earned at the next sign-in). 另一方面,可以在登录后检查所有成就的状态并保留其状态的本地副本 - 如果玩家未登录,您确实应该这样做(这样您就可以解锁所获得的任何成就)在下一次登录)。 This process is not documented well anywhere except for the API documentation but there are no full examples, so I will give you one here :) 除了API文档之外,这个过程没有很好的记录,但是没有完整的例子,所以我会在这里给你一个:)

Ensure that you run this method asynchronously (using AsyncTask or a separate thread) as it will take some time to complete (waiting for responses from the server). 确保以异步方式运行此方法(使用AsyncTask或单独的线程),因为它需要一些时间才能完成(等待来自服务器的响应)。 Also, do this only when the player is signed in successfully - onSignInSucceeded() is a good place for it. 此外,只有当玩家成功登录时才这样做 - onSignInSucceeded()是一个好地方。

Update for Play Service Games 11.8.0 Play服务游戏更新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();
        }
    });

Older Play Service Games 较旧的游戏服务游戏

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

See the API documentation for more info on these processes. 有关这些过程的更多信息,请参阅API文档

So using this method you could create a local copy of the achievements (just alter the internals of the for loop to save the achievement values to some local structure) and refer to it as needed. 因此,使用此方法,您可以创建成就的本地副本(只需更改for循环的内部以将成就值保存到某个本地结构)并根据需要引用它。

Calling .unlock(...) on an already unlocked achievement shouldn't be a problem. 在已经解锁的成就上调用.unlock(...)应该不是问题。 My guess is there is already some sort of "check if unlocked" handling in the .unlock(...) method. 我的猜测是.unlock(...)方法中已经存在某种“检查是否解锁”处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM