Google Play Game Services

Although there’s no multiplayer for iOS, there’s still the leaderboards, cloud save, and achievements.

Yep, but that have majority of available crossplatform solutions - multiplayer for iOS could transform Google Play Services to a killer app.

Hi,

I’ve only used the leadboard and achievement part of the Google Play Games Service and a proper documentation for the whole thing is missing too but … maybe this is interesting for you guys?

Feel free to ask if anything is unclear :slight_smile:

1 Like

Hey Ben!
i cant well eng but write my problem.

i copy your codes and change all package reference correctly, but i have problem,

i call the “updateTopScoreLeaderboard” method correctly in the cocos2dx project. but, it is not work at all

no error, no crash. but NOTHING HAPPEN

i dont know how solve it

could you help me? or anybody?

my C++ jni code

`void HelloWorldScene::upscore(int score)
{
JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t
                                   , "ancl122/cocos2dx/hellocpp.HelloCpp"
                                   , "updateTopScoreLeaderboard"
                                   , "(I)V"))
{
    t.env->CallStaticVoidMethod(t.classID, t.methodID, score);
    // Release
    t.env->DeleteLocalRef(t.classID);
}
CCLog("upscore");

}`

Hi All,
I do exactly in my project as Ben suggested, but the App crushed with a error like this:
java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
any idea about this? Thanks!

Terry Jiang wrote:

Hi All,
I do exactly in my project as Ben suggested, but the App crushed with a error like this:
java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
any idea about this? Thanks!

You need to sign-in first, and when the game is connected you can show leaderboards/achievements.

For example:

public static void gameServicesSignIn()
{
context.runOnUiThread(new Runnable() {
public void run() {
context.beginUserInitiatedSignIn();
}
});
}

public static void gameServicesSubmitScore(String leaderboardId, int score)
{
if (context.isSignedIn())
{
context.getGamesClient().submitScore(leaderboardId, score);
}
}

public static void gameServicesUpdateAchievement(String achievementId, int percentage)
{
if (context.isSignedIn())
{
if (percentage == 100)
context.getGamesClient().unlockAchievement(achievementId);
else if (percentage > 0)
context.getGamesClient().incrementAchievement(achievementId, percentage);
}
}

public static void gameServicesShowLeaderboards()
{
if (context.isSignedIn())
{
context.runOnUiThread(new Runnable() {
public void run() {
(context.startActivityForResult(context.getGamesClient().getAllLeaderboardsIntent(), 5001);
}
});
}
else
gameServicesSignIn();
}

public static void gameServicesShowAchievements()
{
if (context.isSignedIn())
{
context.runOnUiThread(new Runnable() {
public void run() {
(context.startActivityForResult(context.getGamesClient().getAchievementsIntent(), 5001);
}
});
}
else
gameServicesSignIn();
}

You call gameServicesSignIn() first, and then later you can interact with the play game services other functions, but before you submit a score or do other things always check is the player signed in with: isSignedIn(). Otherwise the game will crash.

Thank you very much. It works well.

Attila Szilágyi wrote:

Terry Jiang wrote:
> Hi All,
> I do exactly in my project as Ben suggested, but the App crushed with a error like this:
> java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
> any idea about this? Thanks!
>
You need to sign-in first, and when the game is connected you can show leaderboards/achievements.
>
For example:
>
public static void gameServicesSignIn()
{
context.runOnUiThread(new Runnable() {
public void run() {
context.beginUserInitiatedSignIn();
}
});
}
>
public static void gameServicesSubmitScore(String leaderboardId, int score)
{
if (context.isSignedIn())
{
context.getGamesClient().submitScore(leaderboardId, score);
}
}
>
public static void gameServicesUpdateAchievement(String achievementId, int percentage)
{
if (context.isSignedIn())
{
if (percentage == 100)
context.getGamesClient().unlockAchievement(achievementId);
else if (percentage > 0)
context.getGamesClient().incrementAchievement(achievementId, percentage);
}
}
>
public static void gameServicesShowLeaderboards()
{
if (context.isSignedIn())
{
context.runOnUiThread(new Runnable() {
public void run() {
(context.startActivityForResult(context.getGamesClient().getAllLeaderboardsIntent(), 5001);
}
});
}
else
gameServicesSignIn();
}
>
public static void gameServicesShowAchievements()
{
if (context.isSignedIn())
{
context.runOnUiThread(new Runnable() {
public void run() {
(context.startActivityForResult(context.getGamesClient().getAchievementsIntent(), 5001);
}
});
}
else
gameServicesSignIn();
}
>
You call gameServicesSignIn() first, and then later you can interact with the play game services other functions, but before you submit a score or do other things always check is the player signed in with: isSignedIn(). Otherwise the game will crash.

I have a problem when logging into google play or activating the showScores the screen flickers after awhile my app crashes when trying to postScores even thought the score get posted before the crash.

cocos2d-x3.0rc0 google play service have some problem.

do everybody integrate google play game service to cocos2d-x3.0rc0 ?

@explosis

hi explosis,
i followed all your steps but i am getting many errors and not able to solve them past 3 days.
i did everything possible. i also googled a lot to solve those errors but nothing was useful.

the following are the errors which i get

  1. GameHelperUtils cannot be resolved
  2. GameHelperUtils cannot be resolved to a variable
  3. the constructor AdRequest is not visible
  4. the method getgamesClient() is undefined for type AppName
  5. the type AppName must implement the inherited abstract method GameHelper.GameHelperListener.onSignInFailed()
  6. the type AppName must implement the inherited abstract method GameHelper.GameHelperListener.onSignInSucceeded()

when i added the jar files for leaderboard integration i started getting error for admob also which i have described as error3.

thanks in advance and hope you will help me to solve the issue

1 Like

hi ben,
i followed all your steps but i am getting many errors and not able to solve them past 3 days.
i did everything possible. i also googled a lot to solve those errors but nothing was useful.

the following are the errors which i get

  1. GameHelperUtils cannot be resolved
  2. GameHelperUtils cannot be resolved to a variable
  3. the constructor AdRequest is not visible
  4. the method getgamesClient() is undefined for type AppName
  5. the type AppName must implement the inherited abstract method GameHelper.GameHelperListener.onSignInFailed()
  6. the type AppName must implement the inherited abstract method GameHelper.GameHelperListener.onSignInSucceeded()

when i added the jar files for leaderboard integration i started getting error for admob also which i have described as error3.

thanks in advance and hope you will help me to solve the issue

@jay_dubal

Ben has done it a long time back … in the meantime API has change and new api have 3 files, “BasgeGameActivity.java, GameHelper.java and a new file GameHelperUtils.java” in "/home/user/Desktop/android-samples-master/eclipse_compat/libraries/BaseGameUtils/src/com/google/example/games ".
I got the same error while trying with new API. I switched to old one, that I downloaded longtime back
So,either you get old API (BaseGameUtils sample) or copy GameHelperUtils.java along with other two java src files. Analyse them and get things done.

Maybe you can check this - https://github.com/cpinan/Cocos2dX_GooglePlayGamesServices
It’s a template that works with Cocos2d-x and Google Play Game Services for ios an android and also implements admob.

how to integrate it for android??!

The tutorial guide is for https://github.com/cpinan/Cocos2dX_GooglePlayGamesServices.

GameHelper.java (https://gist.github.com/EmmanuelVinas/ef09a35bcc805ba6deb3)

a1
a2
a3
a4
a5

1 Like

do you have a working code? it’s kinda hard to follow…

1 Like

Hi Michael, did you manage to make your Leaderboard right by using this links?? coz Im kinda stuck following Ben’s instructions

i’ll try this! :smiley:

i get this error:

what could it mean??

im using android API 20 as of writing, im still downloading android API 19

Does this work for 2.2.x also?

[quote="explosis, post:3, topic:7190"]
- Add these new methods to appname.java:
[/quote]

Now in updated google play services and cocos2d-x 3.2 you should write those methods like this:

 public static void gameServicesSignIn(JSONObject parameters) {
        ((AppActivity)mContext).runOnUiThread(new Runnable() {
            public void run() {
                ((AppActivity)mContext).beginUserInitiatedSignIn();
            }
        });

    }

    public static void updateTopScoreLeaderboard(JSONObject parameters) {
        
        int score = 0;

        try { 
            score = parameters.getInt("score");
            String msg = "score = " + score;
            Log.w("LeaderboardsActivity", msg);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        Games.Leaderboards.submitScore(((AppActivity)mContext).getApiClient(), LEADERBOARD_ID, score);
    }

    public static void updateAchievement(String id, int percentage) {
        
        Games.Achievements.increment(((AppActivity)mContext).getApiClient(), id,percentage);
    }

    public static void showLeaderboards(JSONObject parameters) {
        ((AppActivity)mContext).runOnUiThread(new Runnable() {
            public void run() {
                ((AppActivity)mContext).startActivityForResult(Games.Leaderboards.getLeaderboardIntent(((AppActivity)mContext).getApiClient(),
                        LEADERBOARD_ID), REQUEST_LEADERBOARD);
            }
        });
    }

    public static void showAchievements() {
        ((AppActivity)mContext).runOnUiThread(new Runnable() {
            public void run() {
                ((AppActivity)mContext).startActivityForResult(Games.Achievements.getAchievementsIntent(((AppActivity)mContext).getApiClient()), REQUEST_ACHIEVEMENTS);
            }
        });
    }

    public static void loadFriends(JSONObject parameters) {
        if (mFriends.size() > 0) {
            mFriends.clear();
        }

        ((AppActivity)mContext).runOnUiThread(new Runnable() {
            public void run() {
                 Games.Players.loadInvitablePlayers(((AppActivity)mContext).getApiClient(), FRIENDS_PER_PAGE, false).setResultCallback(new ResultCallback<LoadPlayersResult>(){

                        @Override
                        public void onResult(LoadPlayersResult result) {

                            Log.w("GOOGLE SERVICES ****** ", "onResult");
                            PlayerBuffer playerBuffer = result.getPlayers();
                            for (Player player : playerBuffer) {
                                mFriends.add(player);
                                Log.i("GOOGLE SERVICES ---- ", String.format("Found player with id [%s] and display name [%s]", player.getPlayerId(), player.getDisplayName()));
                            }
                            
                            if (playerBuffer.getCount() == FRIENDS_PER_PAGE) {
                                Log.w("GOOGLE SERVICES +++=== ", "loadMoreInvitablePlayers");
                                Games.Players.loadMoreInvitablePlayers(((AppActivity)mContext).getApiClient(), FRIENDS_PER_PAGE);
                            } else {
                                // call out and return all the friends 
                                Log.w("GOOGLE SERVICES======== ", "call out and return all the friends");
                                for (Player friend : mFriends) {
                                    Log.i("GOOGLE SERVICES", String.format("Found player with id [%s] and display name [%s]", friend.getPlayerId(), friend.getDisplayName()));
                                }
                            }
                        } // onResult

                 }); // loadInvitablePlayers
            } // run
        }); // runOnUiThread
    }
        
    @Override
    public void onSignInFailed() {
        Log.w("LeaderboardsActivity", "LeaderboardsActivity :: onSignInFailed");
        
    }

    @Override
    public void onSignInSucceeded() {
        Log.w("LeaderboardsActivity", "LeaderboardsActivity :: onSignInSucceeded");    
    }

I use EasyNDK that’s why my methods have argument JSONObject parameters. Also please note that loadFriends does load only 20 friends as a result of loadInvitablePlayers whereas FRIENDS_PER_PAGE = 10 and also it never calls loadMoreInvitablePlayers. So in this part @billy1380 was wrong that it loads all friends.

1 Like