‹ SdkboxAds Doc Home

SdkboxPlay 集成指南

For the C++ version of cocos2d-x v3.x - (all other versions)

前提条件

Google play

Game Center

集成

在您确保正确安装了 SDKBOX installer 的情况下,运行下面的命令来集成 SDKBOX Youtube 插件。

$ sdkbox import sdkboxplay

JSON 配置

SDKBOX Installer 将会自动在您的 sdkbox_config.json 中插入一份配置样例。请修改这份配置样例,使其能用于您自己的 app 。

这里有一份 SdkboxPlay 配置的例子:

    "sdkboxplay" : {
      "leaderboards" : [
        {
          "id" : "CgkI0sux8sMWEAIQAA",
          "name" : "ldb1"
        }
      ],
      "achievements" : [
        {
          "id" : "CgkI0sux8sMWEAIQAg",
          "name" : "ten-games",
          "incremental" : false
        },
        {
          "id" : "CgkI0sux8sMWEAIQAw",
          "name" : "hunter",
          "incremental" : false
        },
        ...
      ],
      "debug" : true,
      "connect_on_start" : false
    }

如上例所示,Leaderboards 以及 Achievements 都有一个可读性较高的 name, 以及一个机器生成的 id 。这样做的目的是能够通过它们在不同的平台下使用 API 。相比 Google Play 产生的如上所示的随机 ID ,iOS Game Center 产生的 ID 更具可读性。 无论哪个平台,开发者总是通过 name 去使用 Leaderboards 以及 Achievements, 就像下面的示例代码中所看到的那样。

使用

初始化 SdkboxPlay

在您的代码的合适的位置初始化这个插件,我们建议您在 AppDelegate:applicationDidFinishLaunching() 或者 AppController:didFinishLaunchingWithOptions() 中进行初始化。并确保您的代码中包含了正确的头文件。举例如下:

#include "PluginSdkboxPlay/PluginSdkboxPlay.h"
AppDelegate::applicationDidFinishLaunching()
{
     sdkbox::PluginSdkboxPlay::init();
}

使用 SdkboxPlay

介绍

SdkboxPlay 插件 是一个针对 Google Play 以及 Game Center 社交服务的抽象。针对每个平台,在通用的 API 下访问 Leaderboards 以及 Achievements 插件。 为了能适用于两个插件平台,SdkboxPlay 在实现上做了一些权衡,具体细节将在文档的相关部分描述。

Achievements

Achievements 插件在不同的开发者平台上有不同的定义。 以下是在 GooglePlay 以及 GameCenter 下 Achievements 插件一些概念上的不同: Google Play 区分普通成就以及可累积的成就。Google 保持对可累计成就的进度持续追踪。而普通成就只能达成一次。 在 Game Center 下 Achievements 所有的成就都是可累计成就, 但是 Game Center 并不持续跟踪这些成就的进度。这些成就将在游戏过程中被达成。并且这些成就可以被重复解锁多次。 * Google Play 有新解锁成就的概念(第一次解锁),而Game Center则有可周期性解锁的成就。这两个概念是互补的。

为了使以上概念统一, SdkboxPlay API 做了如下设计:

Leaderboards

Leaderboards 插件在不同的开发者平台上有不同的定义。 为了简单,当前的 SdkboxPlay 实现不允许定义组队排行榜。但是对于两个平台您都可以定义任意数量的排行榜。 尽管 GooglePlay 和 GameCenter 都可以采用相同的方式定义排行榜,但是在运行是二者还是有区别的:

这一点不同在下面的回调方法中也将会看到。

Usage

调用 sdkbox::SdkboxPlay::init() 将会配置在 sdkox_config.json 文件中定义的排行榜以及成就系统。

首先,为了连接一个游戏服务平台必须调用下列方法:

sdkbox::PluginSdkboxPlay::signin();

如果连接成功,您将可以通过下列 API 来使用 SdkboxPlay:

Leaderboards
void submitScore(   const std::string& leaderboard_name, int score )

这个方法发送一个更新请求给排行榜。排行榜的名字必须是在配置文件中所定义的。 如果该请求发送给一个不存在的排行榜,那么该请求将不起任何作用。 是否存储这个更新请求的值,取决与开发者控制台配置(比如:总是存储最新的分数,或者总是存储最高分)。 这个方法还将触发下面的毁掉方法:

void onScoreSubmitted(
        const std::string& leaderboard_name,
        int score,
        bool maxScoreAllTime,
        bool maxScoreWeek,
        bool maxScoreToday )

对于 iOS 来说,仅有一个时间表排行,所以后面3个参数都是 false 。

void showLeaderboard( const std::string& leaderboard_name );

这个方法请求显示排行榜信息。这将会在不同平台下显示平台特有的 UI 。对于 iOS 来说,显示排行榜与显示成就的 UI 并没有什么区别,所以这个方法在 iOS 下只是会显示排行榜的视图。

Achievements
void unlockAchievement( const std::string& achievement_name );

解锁一个非累计式的成就。这在 iOS 平台上, 将会发送一个请求给 Game Center 使得一个累计式成就直接达到100点从而解锁。 如果这个成就在配置文件中定义的不正确(错误的 ID),或者 SdkboxPlay 认为成就的类型不正确(是在Google Play下的累计式成就),那么这个方法就会静默失败。 如果该方法成功,那么就会触发一个监听事件:onAchievementUnlocked( const std::string& achievement_name, bool newlyUnlocked) 。

void incrementAchievement(
    const std::string& achievement_name,
    int increment );

增加累计式成就的解锁点数。 如果这个成就在配置文件里定义不正确(错误的或者已经存在的 ID ),或者 SdkboxPlay 认为成就的类型不正确,那么这个方法就会静默失败。 如果这个方法调用成功,它将触发下列两个回调事件:

void showAchievements( );

这个方法显示默认的成就视图。这个视图将只显示公开的成就。针对不同的平台显示特定的信息。比如该成就是否解锁,剩余的解锁步骤(仅适用于 Google Play )平台,总共获得的经验值等等。

游戏数据云保存
void loadAllGameData();

加载所有保存在云中的数据(iOS中用iCloud, Android中用Google Drive 来存储).

void saveGameDataBinary(const std::string& name, const void* data, int length);

保存二进制数据. 字符串也是看成二进制数据来存储.

SdkboxPlay 事件

该插件允许您捕捉事件。

#include "PluginSdkboxPlay/PluginSdkboxPlay.h"
class MyClass : public sdkbox::SdkboxPlayListener
{
protected:
    /**
     * Call method invoked when the Plugin connection changes its status.
     * Values are as follows:
     *   + GPS_CONNECTED:       successfully connected.
     *   + GPS_DISCONNECTED:    successfully disconnected.
     *   + GPS_CONNECTION_ERROR:error with google play services connection.
     */
    void onConnectionStatusChanged( int status );

    /**
     * Callback method invoked when an score has been successfully submitted to a leaderboard.
     * It notifies back with the leaderboard_name (not id, see the sdkbox_config.json file) and the
     * subbmited score, as well as whether the score is the daily, weekly, or all time best score.
     * Since Game center can't determine if submitted score is maximum, it will send the max score flags as false.
     */
    void onScoreSubmitted( const std::string& leaderboard_name, int score, bool maxScoreAllTime, bool maxScoreWeek, bool maxScoreToday );

    /**
     * Callback method invoked when the request call to increment an achievement is succeessful and
     * that achievement gets unlocked. This happens when the incremental step count reaches its maximum value.
     * Maximum step count for an incremental achievement is defined in the google play developer console.
     */
    void onIncrementalAchievementUnlocked( const std::string& achievement_name );

    /**
     * Callback method invoked when the request call to increment an achievement is successful.
     * If possible (Google play only) it notifies back with the current achievement step count.
     */
    void onIncrementalAchievementStep( const std::string& achievement_name, int step );

    /**
     * Call method invoked when the request call to unlock a non-incremental achievement is successful.
     * If this is the first time the achievement is unlocked, newUnlocked will be true.
     */
    void onAchievementUnlocked( const std::string& achievement_name, bool newlyUnlocked );
};
sdkbox::PluginSdkboxPlay::setListener( new MyClass() );

API Reference

Methods

static bool init ( ) ;

Initialize the plugin instance. The plugin initializes from the sdkbox_config.json file, and reads a configuration of the form: { "leaderboards" : LeaderboardObject[], "achievements" : AchievementObject[], "connect_on_start" : boolean, "debug" : boolean, "enabled" : boolean }

debug:
   is a common value to all plugins which enables debug info to be sent to the console. Useful when developing.
enabled:
   is a common value to all plugins, which enables or disables the plugin. If enabled is false, the plugin methods will do nothing.
connect_on_start:
   tells the plugin to make an automatic connection to Google Play Services on application startup.
leaderboards:
   a collection of objects of the form:
   {
       "id"   : // google play's assigned leaderboard id
       "name" : // human readable leaderboard name. You'll request leaderboard actions with this name.
   }
achievements:
   a collection of objects of the form:
   {
       "id"          : // google play's assigned achievement id.
       "name"        : // human readable achievement name. You'll request achievement actions with this name.
       "incremental" : // boolean
   }
static void setListener ( SdkboxPlayListener * listener ) ;

Set SdkboxPlay plugin listener.

static SdkboxPlayListener * getListener ( ) ;

Get the plugin's listener.

static void removeListener ( ) ;

Remove the listener. This plugin allows only for one listener which will be disabled after calling this method.

static std::string getVersion ( ) ;

Use this to get the version of the SDK. @return The version of the SDK.

static void submitScore ( const std::string & leaderboard_name , long score ) ;

Request submission of an score value to a leaderboard name defined in sdkbox_config.json file. If the leaderboard name does not exists, or the id associated is not defined in the Developer Console for the application, the call will silently fail. If everything's right, it will notify the method onScoreSubmitted.

static void showAllLeaderboards ( ) ;

Request to show all leaderboards.

static void showLeaderboard ( const std::string & leaderboard_name = "" ) ;

Request to show the default Leaderboard view. In this view you'll be able to interactively select between daily, weekly or all-time leaderboard time frames and the scope to global or you google play's friends results.

Android only:
 if empty string or __ALL__ is used as leaderboard_name, sdkbox play will invoke an activity
 with all game-defined leader boards.
static void getMyScore ( const std::string & leaderboard_name ,
                         int time_span ,
                         int collection_type ) ;

Get The signed-in user score for an specified leaderboard. This method notifies its result in a call to SdkboxPlay's listener onMyScore method. time_span offers the abbility to filter leaderboard for one of the three time spans each leaderboard offers. Values are: + 0 : daily time span + 1 : weekly time span + any other value : all time time span. collection_type is to filter the leaderboard between social or global scopes. Values are: + 1 : social collection type + any other value : global collection type

static void getPlayerCenteredScores ( const std::string & leaderboard_name ,
                                      int time_span ,
                                      int collection_type ,
                                      int number_of_entries ) ;

Get leaderboard information. This method notifies its result in a call to SdkboxPlay's listener onPlayerCenteredScores method. The information supplied is a json array encoded string. Each json element contains the following information:

  {
     "display_rank"          : string,
     "display_score"         : string,
     "rank"                  : number,   // long
     "score"                 : number,   // long,
     "holder_display_name"   : string,
     "hires_imageuri"        : string,    // content:// protocol
     "lowres_imageuri"       : string,
     "tag"                   : string,
     "timestamp_millis"      : long
   }

time_span offers the abbility to filter leaderboard for one of the three time spans each leaderboard offers. Values are: + 0 : daily time span + 1 : weekly time span + any other value : all time time span. collection_type is to filter the leaderboard between social or global scopes. Values are: + 1 : social collection type + any other value : global collection type

static void loadAchievements ( bool force_reload ) ;

Load achievements metadata. A forece reload will force a cloud-side requery of the achievements information. See onAchievementsLoaded for a description on the returned information.

static void unlockAchievement ( const std::string & achievement_name ) ;

Request to unlock an achievement defined by its name. This method assumes the achievement is non incremental. If the achievement type is incorrectly defined in the configuration file, or the play services determines it is of the wrong type, this method will fail silently. Otherwise, if everything is right, the method onAchievementUnlocked will be invoked on the plugin listener.

static void incrementAchievement ( const std::string & achievement_name ,
                                   double increment ) ;

Request to increment the step count of an incremental achievement by the specified number of steps. This method assumes the achievement is incremental. If the achievement type is incorrectly defined in the configuration file, or the play services determines it is of the wrong type, this method will fail silently. If the call is successful, this method may invoke two different methods: + onIncrementalAchievementStep if the achievement is not unlocked. + onIncrementalAchievementUnlocked the first time it's been newly unlocked. On Android, the achievement is set to a fixed number of incremental steps. On iOS, the achievment is set as a percentage value (0..100). In either case, the increment value will be added to the current achievement's value.

static void showAchievements ( ) ;

Request to show the default Achievements view. In this view, you'll only see public achievements. It will show wether or not achievements are unlocked, and the steps towards unlocking it for incremental achievements. Total experience count is measured as well.

static void reveal ( const std::string & achievement_name ) ;

Reveal a hidden achievement. This method will notify on plugin's listener onReveal or onRevelError methods.

static void setSteps ( const std::string & achievement_name , double steps ) ;

Set an incremental achievement to the given amount of steps. If achievement's current steps are already equal or bigger the specified steps, nothing will happen. This method will notify on plugin's listener onSetSteps or onSetStepsError methods.

static bool isConnected ( ) ;

Fast method to know plugin's connection status. @deprecated

static bool isSignedIn ( ) ;

Same as isConnected (deprecated) but more consistent with naming.

static void signin ( bool showLoginUI = true ) ;

Request connection to the platform-specific services backend. This method will invoke plugin's listener onConnectionStatusChanged method.

static void signout ( ) ;

Request disconnection from the GooglePlay/Game Center backend. This method will invoke plugin's listener onConnectionStatusChanged method.

static std::string getPlayerId ( ) ;

Get the currently logged in player's id.

static std::string getPlayerAccountField ( const std::string & field ) ;

Get a field from the user account's info obtained after authentication. Current values are: iOS/Android



static void resetAchievements ( ) ;

Calling this class method deletes all progress towards achievements previously reported for the local player. Hidden achievements that were previously visible are now hidden again.

iOS Only
static void loadAllData ( ) ;

DEPRECATED >>>>>> Please use loadAllGameData to replace load all saved user game data in clound will trigger onGameData callback

static void loadGameData ( const std::string & save_name ) ;

DEPRECATED >>>>>> Please use loadAllGameData to replace load one saved user game data in clound will trigger onGameData callback

static void saveGameData ( const std::string & save_name ,
                           const std::string & data ) ;

DEPRECATED >>>>>> Please use saveGameDataBinary(name, data, length) to replace save user game data in cloud will trigger onGameData callback

static void fetchGameDataNames ( ) ;

fetch game data names will trigger onGameDataNames

static void loadOneGameData ( const std::string & name ) ;

load game data item will trigger onLoadGameData

static void loadAllGameData ( ) ;

load all saved game data will trigger onLoadGameData callback

static void saveGameDataBinary ( const std::string & name ,
                                 const void * data ,
                                 int length ) ;

save user game data will trigger onSaveGameData callback

Note: if you want to save string, please translate to void>
static void generateIdentityVerificationSignature();

Generates a signature that allows a third party server to authenticate the local player.

just vaild on iOS

iOS Ref Document

Note: on Android, you can get server_auth_code from getPlayerAccountField

Listeners

void onConnectionStatusChanged ( int status );

Call method invoked when the Plugin connection changes its status. Values are as follows: + GPS_CONNECTED: successfully connected. + GPS_DISCONNECTED: successfully disconnected. + GPS_CONNECTION_ERROR:error with google play services connection.

void onScoreSubmitted ( const std::string & leaderboard_name ,
                        long score ,
                        bool maxScoreAllTime ,
                        bool maxScoreWeek ,
                        bool maxScoreToday );

Callback method invoked when an score has been successfully submitted to a leaderboard. It notifies back with the leaderboard_name (not id, see the sdkbox_config.json file) and the subbmited score, as well as whether the score is the daily, weekly, or all time best score. Since Game center can't determine if submitted score is maximum, it will send the max score flags as false.

void onMyScore ( const std::string & leaderboard_name ,
                 int time_span ,
                 int collection_type ,
                 long score ) 

Callback method invoked from a call to getMyScore method. time_span and collection_type are the supplied values to getMyScore method call.

void onMyScoreError ( const std::string & leaderboard_name ,
                      int time_span ,
                      int collection_type ,
                      int error_code ,
                      const std::string & error_description ) 

Callback method invoked from a call to getMyScore method and the method was errored. time_span and collection_type are the supplied values to getMyScore method call. error_code and error_description give extended info about the error.

void onPlayerCenteredScores ( const std::string & leaderboard_name ,
                              int time_span ,
                              int collection_type ,
                              const std::string & json_with_score_entries ) 

Callback method invoked from a call to getPlayerCenteredScores method. json_with_score_entries is an json array enconded string, each of which elements is of the form: Each json element contains the following information:

  {
     "display_rank"          : string,
     "display_score"         : string,
     "rank"                  : number,   // long
     "score"                 : number,   // long,
     "holder_display_name"   : string,
     "hires_imageuri"        : string,    // content:// protocol
     "lowres_imageuri"       : string,
     "tag"                   : string,
     "timestamp_millis"      : long
   }

time_span and collection_type are the values supplied to getPlayerCenteredScores method.

void onPlayerCenteredScoresError ( const std::string & leaderboard_name ,
                                   int time_span ,
                                   int collection_type ,
                                   int error_code ,
                                   const std::string & error_description ) 

Callback method invoked from a call to getPlayerCenteredScores method was errored. time_span and collection_type are the values supplied to getPlayerCenteredScores method. error_code and error_description give extended info about the error.

void onIncrementalAchievementUnlocked ( const std::string & achievement_name );

Callback method invoked when the request call to increment an achievement is succeessful and that achievement gets unlocked. This happens when the incremental step count reaches its maximum value. Maximum step count for an incremental achievement is defined in the google play developer console.

void onIncrementalAchievementStep ( const std::string & achievement_name ,
                                    double step );

Callback method invoked when the request call to increment an achievement is successful. If possible (Google play only) it notifies back with the current achievement step count.

void onIncrementalAchievementStepError ( const std::string & name ,
                                         double steps ,
                                         int error_code ,
                                         const std::string & error_description ) 
void onAchievementUnlocked ( const std::string & achievement_name ,
                             bool newlyUnlocked );

Call method invoked when the request call to unlock a non-incremental achievement is successful. If this is the first time the achievement is unlocked, newUnlocked will be true.

void onAchievementUnlockError ( const std::string & achievement_name ,
                                int error_code ,
                                const std::string & error_description ) 
void onAchievementsLoaded ( bool reload_forced ,
                            const std::string & json_achievements_info ) 

Method invoked after calling plugin's loadAchievements method. The json_achievements_info parameter is a json array encoded string.

Android fields:

each array element is of the form:

  {
     "id"                        : string,
     "name"                      : string,
     "xp_value"                  : string,   // experience value
     "last_updated_timestamp"    : number,
     "description"               : string,
     "type"                      : number,   // 0 = standard, 1 = incremental
     "state"                     : number,   // 0 = unlocked, 1 = revealed,   2 = hidden
     "unlocked_image_uri"        : string,   // content:// protocol
     "revealed_image_uri"        : string,   // content:// protocol
  }

If the achievement is incremental, these fileds will also be available:

  {
     "formatted_current_steps"   : string,
     "formatted_total_steps"     : string,
     current_steps"              : number,
     "total_steps"               : number
  }

IOS fields:

  {
     "id"                        : string,
     "name"                      : string,
     "xp_value"                  : number, int
     "last_updated_timestamp"    : number,
     "description"               : string,   // maybe empty if no achievemnt submission happened before.
     "state"                     : number,   // 0 = unlocked, 1 = revealed,   2 = hidden
     "type"                      : 1,        // on ios all achievemtns are incremental.
     "current_steps"             : number,   // double value. percentage 0.0 .. 100.0
     "total_steps"               : number,   // 100.0
  }
 ```
 iOS only fields:
```json
  {
     "replayable"                : boolean,
  }
void onSetSteps ( const std::string & name , double steps ) 
void onSetStepsError ( const std::string & name ,
                       double steps ,
                       int error_code ,
                       const std::string & error_description ) 
void onReveal ( const std::string & name ) 
void onRevealError ( const std::string & name ,
                     int error_code ,
                     const std::string & error_description ) 
void onGameData ( const std::string & action ,
                  const std::string & name ,
                  const std::string & data ,
                  const std::string & error ) 

DEPRECATED >>>>>>

void onSaveGameData ( bool success , const std::string & error ) 
void onLoadGameData ( const SavedGameData * savedData ,
                      const std::string & error ) 
void onGameDataNames ( const std::vector <std::string> & names ,
                       const std::string & error ) 

手动集成

如果 SDKBOX 安装器 安装插件失败了,那么需要手动集成插件.如果安装器安装插件成功了,那么不需要,也没必要,按文档再手动集成一次.

下面列出的的步骤一般很少用到.如果你按下面的步骤完成了集成,请在完成集成后,再按步骤检查一次.

iOS 平台手动集成

拖拽下列 framework 从 SdkboxPlay 插件包的 plugins/ios 目录到您的 Xcode 工程中,在添加 frameworks 的时候,请勾选 Copy items if needed

sdkbox.framework

PluginSdkboxPlay.framework

如果您没有添加下面这些系统库,您有需要添加它们:

GameKit.framework

UIKit.framework

Android 手动集成

SDKBox 支持三种 Android 工程, command-line, eclipseAndroid Studio.

拷贝文件

从插件安装包中的 plugin/android/libs 目录拷贝下列 jar 文件到您的工程的 proj.android/libs 目录。

PluginSdkboxPlay.jar

sdkbox.jar

plugin/android/libs 目录下拷贝 sdkboxads_lib 目录到您的 proj.android/libs/ 目录下。

拷贝 jni 库

plugin/android/jni/ 拷贝并覆盖 <your_project_root>/jni/ 目录.

编辑 AndroidManifest.xml

在标签 application tag 上添加下列权限:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

设置 application tag 下的 hardware acceleration 为真。这一选项在新版本的 sdk 上可以生效,但不适用于 2.3.3的 cocos2d-x 版本。

<android:hardwareAccelerated="true" />

编辑 Android.mk

Edit proj.android/jni/Android.mk to:

LOCAL_WHOLE_STATIC_LIBRARIES 添加额外的库:

LOCAL_WHOLE_STATIC_LIBRARIES += android_native_app_glue
LOCAL_LDLIBS += -landroid
LOCAL_LDLIBS += -llog
LOCAL_WHOLE_STATIC_LIBRARIES += PluginSdkboxPlay
LOCAL_WHOLE_STATIC_LIBRARIES += sdkbox

在所有 import-module 语句之前添加一条 call 语句:

$(call import-add-path,$(LOCAL_PATH))

在最后添加额外的 import-module 语句:

$(call import-module, ./sdkbox)
$(call import-module, ./pluginsdkboxplay)

Add additional import-module statements at the end:

$(call import-add-path,$(LOCAL_PATH))
$(call import-module, ./sdkbox)
$(call import-module, ./pluginsdkboxplay)

编辑 Application.mk

编辑 proj.android/jni/Application.mk

APP_PATFORM 添加版本:

APP_PLATFORM := android-10

修改 AppActivity.java

插件版本 >= 2.4.0.3

  1. 找到 AppActivity.java 文件
find . -name "AppActivity.java"
  1. extends Cocos2dxActivity 替换为 extends com.sdkbox.plugin.SDKBoxActivity

以下是 AppActivity.java 不同版本的引擎所在的目录:

cpp
  - proj.android/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android-studio/app/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android/app/src/org/cocos2dx/cpp/AppActivity.java ( from cocos2d-x 3.17)

lua
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android-studio/app/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/lua/AppActivity.java (from cocos2d-x 3.17)

js
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/javascript/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/javascript/AppActivity.java ( from cocos2d-x 3.17)

插件版本 < 2.4.0.3

Note: 当你使用 cocos2d-x 源代码时,不同的版本中 Cocos2dxActivity.java 文件的位置也不同。一个确定该文件位置的方法是查看 proj.android/project.properties 。比如:

android.library.reference.1=../../cocos2d-x/cocos/platform/android/java

在这个例子中, Cocos2dxActivity.java 文件应该在如下位置:

../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
onLoadNativeLibraries();
SDKBox.init(this);
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if(!SDKBox.onActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
          }
    }
    @Override
    protected void onStart() {
          super.onStart();
          SDKBox.onStart();
    }
    @Override
    protected void onStop() {
          super.onStop();
          SDKBox.onStop();
    }
    @Override
    protected void onResume() {
          super.onResume();
          SDKBox.onResume();
    }
    @Override
    protected void onPause() {
          super.onPause();
          SDKBox.onPause();
    }
    @Override
    public void onBackPressed() {
          if(!SDKBox.onBackPressed()) {
            super.onBackPressed();
          }
    }

使用 Proguard (release模式下可选)

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

只要有需要,您可以使用任何 Google Play 的混淆配置文件。 默认的混淆配置如下:

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

Note: Proguard 只能工作在 Release 模式下 (比如: cocos run -m release) debug 模式下不会触发 Proguard 。

游戏存档

SDKBoxPlay 支持 iOS/Google的游戏云存档功能. 开发者可以使用此接口存储用户的游戏数据.

iOS 云存储

用法

加载所有的游戏数据

sdkbox::PluginSdkboxPlay::loadAllData();

加载某一项游戏数据

sdkbox::PluginSdkboxPlay::loadGameData("key2");

保持数据

sdkbox::PluginSdkboxPlay::saveGameData("key1", "{\"game_name\": \"sdkbox go\", \"stage\": 3}");

iOS 存档官方文档

Android 存档官方文档

服务器认证

如果需要用开发者自己的服务器来作认证,可以按下面的步骤

iOS

  1. 实现 SdkboxPlayListener 中的 onGenerateIdentityVerificationSignature
  2. 调用 sdkbox::PluginSdkboxPlay::generateIdentityVerificationSignature();

Android

    "sdkboxplay" : {
        "web_client_id": "......."
    }

web_client_id的生成可以参见这个文档