Tutorial: How to use Google Play Services with Cocos2d-X for android

Consider viewing this post on my new blog:http://adrian-dawid.me/gulp/c++/2014/08/18/google-play-cocos2d-x-tutorial.html, I will post any updated information only there.

This is a short tutorial how to use Google Play Games Services with cocos2d-x. It describes how you add the library to your project. Google Play Games is a really handy tool for mobile game development, but there is almost no documentation how to use it with engines like Cocos2d-X, that are using the NDK and are designed to be cross platform compatible. I am using the JNI Bridge between C++ and Java here to use all the java functionality. There is also a c++ sdk, but it is also not easy to integrate into cocos2d-x too and has not the full feature-set of the java sdk.

1.Add the Google Play Games Services library and the BaseGameUtils to your project.

To use google play services you need to install the Google Play Services Library.

You can do that over the Android SDK Manager:

Bildschirmfoto 2014-08-17 um 17.32.16

After you have installed the library you must copy it into the libs folder of your cocos2d-x android project. To do that copy the .jar, that is located in the your-sdk/extras/google/google_play_services/libproject/google-play-services_lib/libs/ folder into your project. For convenience you should also copy the file your-sdk/extras/google/google_play_services/libproject/google-play-services_lib/res/values/version.xml into you res/values folder, if you don’t do that you will have have to set the version number by yourself. You also need to copy the android-support-v4.jar file into your libs folder.

To use the Google Play Games Services in your app you also need the BaseGameUtils. The source is available on github:

https://github.com/playgameservices/android-basic-samples/tree/master/BasicSamples/libraries

Download the source as zip file or clone it onto your pc, then copy the .java files and the res folder into your project.

The BaseGameUtils are not made to be used with cocos2d-x or other native   engines, therefore we must change some things:

1.

Change the package of the BaseGameUtils files to org.cocos2dx.cpp 

IMPORTANT NOTICE:

You need to copy the files into the correct folder:

org/cocos2dx/cpp/*.java

2.

Change the base class of BaseGameActivity to Cocos2dxActvity. In order to do that you must add this line of code at the top of the file:

import org.cocos2dx.lib.Cocos2dxActivity;

This is necessary because the BaseGameActivity uses an std. Android Activity as it’s base class, but we want to see the results of the C++ based Cocos2dX renderer and therefore we must change the base class to Cocos2dxActivity. Cocos2dxActivity is the native activity that is used as the base class of the java AppActvity by default.

3.

Change the base class of your AppActivity class to BaseGameActivity and add an onCreate function.

Your class should look like this now:

         package org.cocos2dx.cpp;

         import org.cocos2dx.lib.Cocos2dxActivity;

          import your.app.id.*;

         import android.os.Bundle;

          public class AppActivity extends BaseGameActivity {

    

                    @Override

                      public void onSignInSucceeded(){

        

                    }

    

                      @Override

                       public void onSignInFailed(){

        

                      }

    

                       @Override

                       protected void onCreate(Bundle savedInstanceState) {

                              super.onCreate(savedInstanceState);

                      }

    

           }

4.

Add an import for your app id to all files. This is necessary because we need to access the android R class, and it is always in the std. package of our app, which is your app id  (you can find it in your android mainfest if you don’t know it anymore).

If you have done these steps you have added the Google Play Games Services Library and the BaseGameUtils to your project successfully. Now you should be able to compile your project, but it will most likely crash at startup, for the Google Play Games Services can not find an google play games app id.

2. Set your game up

To use Google Play Games Services  you need to set up your game in the cloud. You need to do that over the Google Play Console, please take a look at the documentation, if you want to find out how:

https://developers.google.com/games/services/console/enabling

Once you have created your game in the console, add these lines to your android manifest under the application tag:

                 <meta-data

                  android:name=”com.google.android.gms.games.APP_ID”

                  android:value=”@string/app_id” />

                  

                  <meta-data

                  android:name=”com.google.android.gms.appstate.APP_ID”

                  android:value=”@string/app_id”/>

                  

                 <meta-data android:name=”com.google.android.gms.version” android:value=”@integer/google_play_services_version” />

After you added this to the file you must add the @string/app_id resource to your project, in order to do that add a new file to the res/values folder and call it ids.xml. Use this template:

                  <resources>

                              <string name=”app_id”>your app id from the google play console</string>

                  </resources>

Now you can compile your app and you should see the Google Play Games Services Sign-In window at startup.

3 .Next Steps

Once you have set up your game you need to create java methods for the google play games functionality and c++ wrappers for them. Keep in mind, that it improves your performance if you transfer less data between C++ and Java.

I have created a C++ Wrapper and some Java files you can use, they are available at Github:

https://github.com/dwd31415/GameSharing

41 thoughts on “Tutorial: How to use Google Play Services with Cocos2d-X for android

  1. sohail says:

    excellent work, i follow your tutorial and i have only issue with jni calls, when i call jni methods then my game is crash. i use your c++ wrapper. plz tell me the solutions.

    Like

    • Any android app has a package id, your.app.id.* means that you should instert yours and add .* at the end. If you don’t know what your id is you can look it up in the Manifest file, the tag is called manifest package.

      Like

  2. Fabio says:

    Hi,

    I’ getting a Fatal Exception from main:
    09-18 01:54:02.737: E/AndroidRuntime(8130): java.lang.RuntimeException: Unable to resume activity {org.fabio.corundum/org.fabio.corundum.HelloCpp}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=9001, result=10004, data=null} to activity {org.fabio.corundum/org.fabio.corundum.HelloCpp}: java.lang.NullPointerException
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2737)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2765)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2221)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3683)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.access$700(ActivityThread.java:149)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1311)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.os.Handler.dispatchMessage(Handler.java:99)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.os.Looper.loop(Looper.java:153)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.main(ActivityThread.java:5000)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at java.lang.reflect.Method.invokeNative(Native Method)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at java.lang.reflect.Method.invoke(Method.java:511)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at dalvik.system.NativeStart.main(Native Method)
    09-18 01:54:02.737: E/AndroidRuntime(8130): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=9001, result=10004, data=null} to activity {org.fabio.corundum/org.fabio.corundum.HelloCpp}: java.lang.NullPointerException
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.deliverResults(ActivityThread.java:3308)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2720)
    09-18 01:54:02.737: E/AndroidRuntime(8130): … 13 more
    09-18 01:54:02.737: E/AndroidRuntime(8130): Caused by: java.lang.NullPointerException
    09-18 01:54:02.737: E/AndroidRuntime(8130): at org.fabio.corundum.GameHelper.onActivityResult(GameHelper.java:619)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at org.fabio.corundum.BaseGameActivity.onActivityResult(BaseGameActivity.java:133)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.Activity.dispatchActivityResult(Activity.java:5204)
    09-18 01:54:02.737: E/AndroidRuntime(8130): at android.app.ActivityThread.deliverResults(ActivityThread.java:3304)
    09-18 01:54:02.737: E/AndroidRuntime(8130): … 14 more

    It seems it’s cause by : mHelper.onActivityResult()

    Do you have any clue about this?

    Regards

    Like

      • I am not able to reproduce the bug. Are you using the newest code from github?
        But it looks like the problem would be the BasicGameUtils from Google. Make sure you use the most recent code release from Google too.

        Like

  3. mike says:

    Hello, I have an error when running my game, when I want to display the table of liderboard tells me google play stopped working, I hope to help as m passing game points, please help

    Like

  4. Muniraj says:

    hi I managed to add the code to my android project with game sharing. The first time i start the app the game play service logins and works fine. But next time i start the game the keyboard pop’s up. Can you please help me to fix the issue.

    Like

  5. After setup project, build and login. This popup will show up all the time. Can’t you have me fix it
    “Failed to sign in. Please check your network connection and try again”

    Like

    • You issue sounds strange, I don’t know what is it’s reason, if it is not the lack of network connection. Maybe you have not configured your app right in the Google Play Console or you didn’t add a network access premission to your app.

      Like

  6. sharjeel says:

    brother i am totally new with this google play service thing. i am following your tutorial but i cant integrate GPGS into mine project. kindly give me some tips of how to integrate them.

    Like

  7. sharjeel says:

    like what to do in import your.app.id.*; ??
    secondly how to Change the package of the BaseGameUtils files to org.cocos2dx.cpp ?
    when i import basegameutils it imports main library

    Like

    • you must replace your.app.id with the android package ID of your application, you can find it in your AndroidManifest.xml. To change the package of java source file, you must just change the id that comes after “package” in one of the first lines of the file, with org.cocos2dx.cpp.
      I don’t know what you means by “when i import basegameutils it imports main library”, could you specify that?

      Like

  8. terec says:

    So, before I put your GameSharing class and additional java files, the google play service managed to pop up at the start up of the application. Then, right when I followed the steps displayed on your git hub, the google play services simply disappear off from the start up.

    I went ahead and tried to logcat the ovverided function “onSignInFailed” in the AppActivity class, and it seems like the activity directly call the function “onSignInFailed” without even popping up the “Sign In button”.

    Could you perhaps help me on this one? Thanks

    Like

  9. hi
    I am currently developing a real-time multiplayer application , I managed to implement (submitScore, unlockAchievement, incrementAchievement …) but i couldn’t implement thz phase of real-time multiplayer,
    I followed the official docs, but i could not even to create a multiplayer room

    Like

  10. ericrb1986 says:

    Thanks again. Just a final question. Is there an important reason to check if google play is available at MainActivity? because Ive tested with just 1 class and if I don’t have google play games installed it just asks me to install it. Other than that is there other important reason? (perhaps it crashes in older android versions?)

    Like

  11. nick says:

    hello. thanks for the tutorial.
    I have done everything in the tutorial and it worked.
    My game can sign in the google play game services but when I call the function in GameSharing.h.
    they don’t work. Could you tell me what went wrong? thank you

    here is the debug log
    25181-25202/testing.play.game E/JniHelper: Failed to find static method id of isGPGSupported

    Like

  12. cho says:

    Hi adrian! thank you very much for your ‘gamesharing’

    I successfully done with GPGS.
    but, I have some trouble.
    I don’t know how can I use UnlockAchievement(int ID);

    first : add ‘achievement ID’ in ids.xml

    C2093sdlkfjj;

    Casdffsdffdf;

    Caldkfjsldfs;

    second : make event for UnlockAchievement() in My Game code
    like this,
    void MetaUiLayer::pressAchievement(Ref* pSender, Widget::TouchEventType enType)
    {
    GameSharing::UnlockAchivement(1);
    }

    and than I excuted the game, nothing happened. T.,T
    can you give me some advise?

    thanks again for your ‘GameSharing’

    Like

    • cho says:

      I solved that put a code of ‘idx.xml’ directly to ‘unlock( )’ in ‘AppActivity.java’.
      now, I faced on another problem.

      AppActivity.java should have a ‘currentScore’.(See ‘static public int collectScore(){}’ function)
      But there is no ‘currentScore’.
      even though in ‘BaseGameActivity.java’.

      Could I put some code of mine?
      Will there any problem?

      thank you for your kindness.

      Like

  13. Fredric says:

    I using Cocos2d-x v3.8.1 and Android Studio 2.1.2.
    I integrated in-app billing with Sdkbox.
    So android studio project has Google Play Services(‘:gps’).
    I wanna integrated leaderboard to that so I imported BaseGameUtils with your tutorial.
    But project has gradle error.

    Here is error.

    FAILURE: Build failed with an exception.

    * What went wrong:
    Execution failed for task ‘:ProjectName:processDebugResources’.
    > Error: more than one library with package name ‘com.google.android.gms’

    * Try:
    Run with –stacktrace option to get the stack trace. Run with –info or –debug option to get more log output.

    How can I fix this?

    Like

Leave a comment