Google Play Game Services

Hi,

Has someone already tried to integrate Google Play Game Services in cocos2dx?

Hello everyone!

I am also interested in using this API from cocos2dx, but I’m just a beginner and have never worked with interactions between cocos2dx and native languages​​, so I have no idea how.
I find it a very powerful tool because it is cross-platform and free, which is the spirit of cocos2dx!
I hope someone will share an extension/tutorial or just a bit of help!

So BUMP!

Here’s what I did:

  • Setup your app on the Google Play Game Services console like the guide from google says. Record the id of your app after creation
  • Download the BasicGameUtils project that google provides for doing a lot of the game services operations.

Now go into your project

  • Add android-support-v4.jar and google-play-services.jar to your libs directory. android-support can be found in the BasicGameUtils project and google-play-services.jar is in
    your android sdk/extras/google directory (This should have been downloaded via the Android SDK Manager)

  • Edit AndroidManifest.xml and add <meta-data android:name="com.google.android.gms.games.APP_ID" android:value="string/app_id" />@ to the application section.

  • Edit your res/values/strings.xml and add <string name="app_id">xxxxxxxxxxx</string> with the id you recorded from above

  • Go into your /src/com/company/appname/ directory and add two files, BaseGameActivity.java and GameHelper.java. Copy the code for each of those from the BaseGameUtils classes,
    BasgeGameActivity and GameHelper.

  • Change the package names on your new BaseGameActivity and GameHelper and fix any other imports that aren’t resolving

  • Change
    public abstract class BaseGameActivity extends FragmentActivity implements

to

public abstract class BaseGameActivity extends Cocos2dxActivity implements

in BaseGameActivity.java

Do these steps in your appname.java file:

  • Change public class appname extends Cocos2dxActivity to public class appname extends BaseGameActivity

  • Add static Context mContext near the top if you haven’t already

  • Add mContext = appname.this; in your onCreate

  • Add these new methods to appname.java:

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

      }
    
      public static void updateTopScoreLeaderboard(int score) {
          ((appname)mContext).getGamesClient().submitScore("leaderboardid",
                  score);
      }
    
      public static void updateAchievement(String id, int percentage) {
    
          ((appname)mContext).getGamesClient().incrementAchievement(id,percentage);
      }
    
      public static void showLeaderboards() {
          ((appname)mContext).runOnUiThread(new Runnable() {
              public void run() {
                  ((appname)mContext).startActivityForResult(((appname)mContext).getGamesClient().getLeaderboardIntent("leaderboardidfromgoogleplay"), 5001);
              }
          });
      }
    
      public static void showAchievements() {
          ((appname)mContext).runOnUiThread(new Runnable() {
              public void run() {
                  ((appname)mContext).startActivityForResult(((appname)mContext).getGamesClient().getAchievementsIntent(), 5001);
              }
          });
      }
    
  • These new methods are going to be called via JNI to do their various operations.

Now go into your C*+ Scene code and make the JNI calls to these new methods. If you haven’t done JNI before, you can look at the SimpleAudioEngine JNI classes for examples on how to do this.
For me, I created a new C*+ helper class that only makes calls to static methods in my appname.java

This is pretty rough but it should get you started. Someone else could probably make some better Helper classes to encapsulate all of this logic.

4 Likes

Thank you very much. I am going to try this!

Hi Ben,

Thanks for the insight. A quick question: do end users get to see your developer e-mail address when they sign up for Google Play Game Services? The developer portal suggests that they will when you are in the initial game setup flow, and there wasn’t a way to clarify/change/opt-out of this. To be honest it put me off integrating it at all…

Thanks for your help,

Ben

Hi Ben,
I haven’t seen anything yet that has revealed my developer information during the initial connect/sign-in. The connect screen definitely shows the name of the app (which I think comes from the Google Play Game Console) and it asks what kind of the access the app should have and whether stuff gets posted to your g+ page. I am using a different email to sign in vs. the account I used to setup the services on google play.

An easy test for you would be to download the sample app from google, create a game console app for that sample app, and then run it locally. This way you could see what it looks like with little effort. Google does provide step by step instructions for getting the sample app connected to the game console.

-Ben

Hey Ben,

That’s good to hear, thanks for that. My idiot brain didn’t think to download the sample - I was actually trawling Google Play for other games which have already implemented, with varying levels of success. Anyway, this all sounds good so it’s time to get integrating. Thanks for your help!

Ben

Hi Ben,
Thank you very much.

i’m not good english.
An error has occurred.

error point in source code >
——myAppName.java—————

public class myAppName extends BaseGameActivity {
…
…
…
private static Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView;

…
…
…

protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mCocos2dxGLSurfaceView = onCreateView(); //-> ERROR

ERROR MESSAGE : The method onCreateView(String, Context, AttributeSet) in the type FragmentActivity is not applicable for the arguments ()

help me ~~

@Ben Higgins Thank you very much!

infinity brad you need to modify the google utility class BaseGameActivity to inherit from Cocos2dxActivity asBen Higgins suggested.

On another note, in gamecenter there is a method that returns all the friends of a given player, I put together a method that does that same thing… it kind of falls appart if the user has too many friends but this is the code if anyone is interested

    private static List mFriends = new ArrayList();
    private static final int FRIENDS_PER_PAGE = 10;

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

        ((appname)mContext).runOnUiThread(new Runnable() {
                public void run() {     
            ((appname)mContext).getGamesClient().loadInvitablePlayers(new OnPlayersLoadedListener() {

                @Override
                public void onPlayersLoaded(int statusCode, PlayerBuffer playerBuffer) {

                    if (statusCode == GamesClient.STATUS_OK) {
                        for (Player player : playerBuffer) {
                            mFriends.add(player);
                        }

                        if (playerBuffer.getCount() == FRIENDS_PER_PAGE) {
                            ((appname)mContext).getGamesClient().loadMoreInvitablePlayers(this, FRIENDS_PER_PAGE);
                        } else {
                            // call out and return all the friends 

                            for (Player friend : mFriends) {
                                Log.i(TAG, String.format("Found player with id [%s] and display name [%s]", friend.getPlayerId(), friend.getDisplayName()));
                            }
                        }
                    }
                }
            }, FRIENDS_PER_PAGE, false);
        });
    }

Hi all,

I have been trying to integrate Google Play Games, just the way Ben Higgins said, but I’m getting an exception “NoClassDefFoundError” and the app is crashing when trying to open.

In the LogCat there are a lot of messages similar to this:

Could not find method com.mypackage.GameHelper.onActivityResult, referenced from method com.mypackage.BaseGameActivity.onActivityResult

And then the crash:

FATAL EXCEPTION: main java.lang.NoClassDefFoundError: com.mypackage.GameHelper at com.mypackage.BaseGameActivity.<init>(BaseGameActivity.java:65) at com.mypackage.SpeedOfLight.<init>(SpeedOfLight.java:32) at java.lang.Class.newInstanceImpl(Native Method) at java.lang.Class.newInstance(Class.java:1319) at android.app.Instrumentation.newActivity(Instrumentation.java:1054) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) at android.app.ActivityThread.access$600(ActivityThread.java:141) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method)

Maybe you didn’t copy over the GameHelper class from the BaseGameUtils sample app and rename it to your package?

Hi Ben,

Thanks for your fast reply!

I copied GameHelper class from the project “BaseGameUtils” into my package, and it renamed itself to my package. The project builds without problem, the error is in execution time.

I also tried the “TypeANumber” sample project and it works perfectly.

I found another person with the same problem here:

But there is neither a solution.

Thanks

Hmmm… the real issue might be the google play jar files aren’t being packaged with your app. You could open up the apk file and make sure that GameHelper and the google play jars are in there.

In our game I ended up editing the BaseGameActivity so that it inherits from Cocos2dxActivity. That gets around the problem.

1 Like

You are right Ben, the libs weren’t there. It was caused because in the Properties / Java Build Path / Order and Export tab, it was not checked the “Android Private Libraries” option.

Thank you very much! :smiley:

Have people gotten this working for iOS too? Or only Android?

This seems to be a new thing in the android developer tools in general. Originally all files in the private android libraries were copied with no issues. To check if the jars that you have in the libs folder are being “surfaced” you can check if you have a version of the library in your bin/dexedLibs folder. For google services e.g. it should be something like google-play-services_lib-xxxxxxxxxxxxxxxxxxxxx.jar.

If you have checked the under order and export but the libraries are still not appearing in the dexedLibs folder. Do a project clean they try to build the project again, they will show up in there.

Have people gotten this working for iOS too? Or only Android?

https://developers.google.com/games/services/android/quickstart

No multiplayer for iOS, does someone know is there any beta?

Krunoslav Radem wrote:

> Have people gotten this working for iOS too? Or only Android?
>
https://developers.google.com/games/services/android/quickstart
https://developers.google.com/games/services/ios/quickstart
>
No multiplayer for iOS, does someone know is there any beta?

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