SdkboxPlay 集成指南
For the Javascript version of cocos2d-x v3.x - (all other versions)
前提条件
Google play
- 根据 这篇 google 官方文档 为您的工程打开游戏服务并且创建一个 app 。否则,您的工程将不能连接到 google play 。
- 使用开发者控制台配置 Leaderboards 以及 Achievements 。
Game Center
- 在 XCode 上打开 Game Center 选项。
- 使用开发者平台配置 Leaderboards 以及 Achievements,必须要至少添加一条。
- Game Center需要登录你设置ITunesconnect设置过的测试帐号(不用有些资料说的必需新建帐号)。
集成
在您确保正确安装了 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, 就像下面的示例代码中所看到的那样。
使用
注册 Javascript 函数
您需要在使用之前,在 cocos2d-x 中注册所有的 SdkboxPlay JS 函数。
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
文件,包含下列头文件:
#include "PluginSdkboxPlayJS.hpp"
#include "PluginSdkboxPlayJSHelper.h"
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
文件,添加如下内容:
sc->addRegisterCallback(register_all_PluginSdkboxPlayJS);
sc->addRegisterCallback(register_all_PluginSdkboxPlayJS_helper);
初始化 SdkboxPlay
通过在您的代码合适的位置调用 init()
方法来初始化这个插件。我们建议您在 app.js
中进行初始化。举例如下:
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 做了如下设计:
- 允许您定义非累计式的成就。对于 iOS 平台来说,就是将累计值设为100的累计式的成就,因为这表明这个成就即将被解锁(并只解锁一次)。
- 允许您定义累计式的成就。在 GooglePlay 平台下,累计式插件可以在 app 控制台定义自己的解锁值。
- 为了保持一致,建议您定义 Google Play 下的成就的解锁值为100。这个值也是 Game Center 下的成就解锁值。
Leaderboards
Leaderboards 插件在不同的开发者平台上有不同的定义。 为了简单,当前的 SdkboxPlay 实现不允许定义组队排行榜。但是对于两个平台您都可以定义任意数量的排行榜。 尽管 GooglePlay 和 GameCenter 都可以采用相同的方式定义排行榜,但是在运行是二者还是有区别的:
- Google Play 会为每一个排行榜创建三种时间表的排行:每天,每周以及全时间段的排行。
- Game Center 则只会创建一个时间表的排行。
这一点不同在下面的回调方法中也将会看到。
使用
调用 sdkbox::SdkboxPlay::init()
将会配置在 sdkox_config.json 文件中定义的排行榜以及成就系统。
首先,为了连接一个游戏服务平台必须调用下列方法:
sdkbox::PluginSdkboxPlay::signin();
如果连接成功,您将可以通过下列 API 来使用 SdkboxPlay:
Leaderboards
sdkbox.PluginSdkboxPlay.submitScore( leaderboard_name, score )
这个方法发送一个更新请求给排行榜。排行榜的名字必须是在配置文件中所定义的。 如果该请求发送给一个不存在的排行榜,那么该请求将不起任何作用。 是否存储这个更新请求的值,取决与开发者控制台配置(比如:总是存储最新的分数,或者总是存储最高分)。 这个方法还将触发下面的毁掉方法:
sdkbox.PluginSdkboxPlay.onScoreSubmitted(
leaderboard_name,
score,
maxScoreAllTime,
maxScoreWeek,
maxScoreToday )
对于 iOS 来说,仅有一个时间表排行,所以后面3个参数都是 false 。
sdkbox.PluginSdkboxPlay.showLeaderboard( leaderboard_name );
这个方法请求显示排行榜信息。这将会在不同平台下显示平台特有的 UI 。对于 iOS 来说,显示排行榜与显示成就的 UI 并没有什么区别,所以这个方法在 iOS 下只是会显示排行榜的视图。
Achievements
sdkbox.PluginSdkboxPlay.unlockAchievement( achievement_name );
解锁一个非累计式的成就。这在 iOS 平台上, 将会发送一个请求给 Game Center 使得一个累计式成就直接达到100点从而解锁。 如果这个成就在配置文件中定义的不正确(错误的 ID),或者 SdkboxPlay 认为成就的类型不正确(是在Google Play下的累计式成就),那么这个方法就会静默失败。 如果该方法成功,那么就会触发一个监听事件:onAchievementUnlocked( const std::string& achievement_name, bool newlyUnlocked) 。
sdkbox.PluginSdkboxPlay.incrementAchievement( achievement_name, increment );
增加累计式成就的解锁点数。 如果这个成就在配置文件里定义不正确(错误的或者已经存在的 ID ),或者 SdkboxPlay 认为成就的类型不正确,那么这个方法就会静默失败。 如果这个方法调用成功,它将触发下列两个回调事件:
- 如果这个累计式成就还没有达到解锁的点数,那么就触发
onIncrementalAchievementStep( const std::string& achievement_name, int step )
。 - 如果这个累计式成就达到点数第一次被解锁,那么就触发
onIncrementalAchievementUnlocked( const std::string& achievement_name, bool newlyUnlocked)
。
sdkbox.PluginSdkboxPlay.showAchievements( );
这个方法显示默认的成就视图。这个视图将只显示公开的成就。针对不同的平台显示特定的信息。比如该成就是否解锁,剩余的解锁步骤(仅适用于 Google Play )平台,总共获得的经验值等等。
SdkboxPlay 事件
该插件允许您捕捉事件。
sdkbox.PluginSdkboxPlay.setListener({
/**
* 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.
*/
onConnectionStatusChanged : function( 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.
*/
onScoreSubmitted : function( leaderboard_name, score, is_maxScoreAllTime, is_maxScoreWeek, is_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.
*/
onIncrementalAchievementUnlocked : function( 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.
*/
onIncrementalAchievementStep : function( achievement_name, 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.
*/
onAchievementUnlocked : function( achievement_name, newlyUnlocked ) {}
});
API Reference
Methods
sdkbox.PluginSdkboxPlay.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 }
sdkbox.PluginSdkboxPlay.setListener(listener);
Set SdkboxPlay plugin listener.
sdkbox.PluginSdkboxPlay.removeListener();
Remove the listener. This plugin allows only for one listener which will be disabled after calling this method.
sdkbox.PluginSdkboxPlay.getVersion();
Use this to get the version of the SDK. @return The version of the SDK.
sdkbox.PluginSdkboxPlay.submitScore(leaderboard_name, 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
.
sdkbox.PluginSdkboxPlay.showAllLeaderboards();
Request to show all leaderboards.
sdkbox.PluginSdkboxPlay.showLeaderboard(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.
sdkbox.PluginSdkboxPlay.getMyScore(leaderboard_name, time_span, 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
sdkbox.PluginSdkboxPlay.getPlayerCenteredScores(leaderboard_name,
time_span,
collection_type,
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
sdkbox.PluginSdkboxPlay.loadAchievements(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.
sdkbox.PluginSdkboxPlay.unlockAchievement(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.
sdkbox.PluginSdkboxPlay.incrementAchievement(achievement_name, 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, theincrement
value will be added to the current achievement's value.
sdkbox.PluginSdkboxPlay.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.
sdkbox.PluginSdkboxPlay.reveal(achievement_name);
Reveal a hidden achievement. This method will notify on plugin's listener
onReveal
oronRevelError
methods.
sdkbox.PluginSdkboxPlay.setSteps(achievement_name, 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
oronSetStepsError
methods.
sdkbox.PluginSdkboxPlay.isConnected();
Fast method to know plugin's connection status. @deprecated
sdkbox.PluginSdkboxPlay.isSignedIn();
Same as isConnected (deprecated) but more consistent with naming.
sdkbox.PluginSdkboxPlay.signin(showLoginUI);
Request connection to the platform-specific services backend. This method will invoke plugin's listener
onConnectionStatusChanged
method.
sdkbox.PluginSdkboxPlay.signout();
Request disconnection from the GooglePlay/Game Center backend. This method will invoke plugin's listener
onConnectionStatusChanged
method.
sdkbox.PluginSdkboxPlay.getPlayerId();
Get the currently logged in player's id.
sdkbox.PluginSdkboxPlay.getPlayerAccountField(field);
Get a field from the user account's info obtained after authentication. Current values are: iOS/Android
- display_name
- name
- player_id Android only:
- title
- icon_image_uri
- hires_image_uri
- last_play_timestamp
- retrieved_timestamp
- server_auth_code If a field not valid is queried an empty string will be returned.
sdkbox.PluginSdkboxPlay.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
sdkbox.PluginSdkboxPlay.loadAllData();
DEPRECATED >>>>>> Please use loadAllGameData to replace load all saved user game data in clound will trigger onGameData callback
sdkbox.PluginSdkboxPlay.loadGameData(save_name);
DEPRECATED >>>>>> Please use loadAllGameData to replace load one saved user game data in clound will trigger onGameData callback
sdkbox.PluginSdkboxPlay.saveGameData(save_name, data);
DEPRECATED >>>>>> Please use saveGameDataBinary(name, data, length) to replace save user game data in cloud will trigger onGameData callback
sdkbox.PluginSdkboxPlay.fetchGameDataNames();
fetch game data names will trigger onGameDataNames
sdkbox.PluginSdkboxPlay.loadOneGameData(name);
load game data item will trigger onLoadGameData
sdkbox.PluginSdkboxPlay.loadAllGameData();
load all saved game data will trigger onLoadGameData callback
sdkbox.PluginSdkboxPlay.generateIdentityVerificationSignature();
Generates a signature that allows a third party server to authenticate the local player.
just vaild on iOS
Note: on Android, you can get server_auth_code from getPlayerAccountField
Listeners
onConnectionStatusChanged(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.
onScoreSubmitted(leaderboard_name,
score,
maxScoreAllTime,
maxScoreWeek,
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.
onMyScore(leaderboard_name, time_span, collection_type, score);
Callback method invoked from a call to
getMyScore
method.time_span
andcollection_type
are the supplied values togetMyScore
method call.
onMyScoreError(leaderboard_name,
time_span,
collection_type,
error_code,
error_description);
Callback method invoked from a call to
getMyScore
method and the method was errored.time_span
andcollection_type
are the supplied values togetMyScore
method call.error_code
anderror_description
give extended info about the error.
onPlayerCenteredScores(leaderboard_name,
time_span,
collection_type,
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.
onPlayerCenteredScoresError(leaderboard_name,
time_span,
collection_type,
error_code,
error_description);
Callback method invoked from a call to
getPlayerCenteredScores
method was errored.time_span
andcollection_type
are the values supplied togetPlayerCenteredScores
method.error_code
anderror_description
give extended info about the error.
onIncrementalAchievementUnlocked(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.
onIncrementalAchievementStep(achievement_name, 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.
onIncrementalAchievementStepError(name, steps, error_code, error_description);
onAchievementUnlocked(achievement_name, 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.
onAchievementUnlockError(achievement_name, error_code, error_description);
onAchievementsLoaded(reload_forced, json_achievements_info);
Method invoked after calling plugin's
loadAchievements
method. Thejson_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,
}
onSetSteps(name, steps);
onSetStepsError(name, steps, error_code, error_description);
onReveal(name);
onRevealError(name, error_code, error_description);
onGameData(action, name, data, error);
DEPRECATED >>>>>>
onSaveGameData(success, error);
onLoadGameData(savedData, error);
onGameDataNames(names, error);
手动集成
如果 SDKBOX 安装器 安装插件失败了,那么需要手动集成插件.如果安装器安装插件成功了,那么不需要,也没必要,按文档再手动集成一次.
下面列出的的步骤一般很少用到.如果你按下面的步骤完成了集成,请在完成集成后,再按步骤检查一次.
iOS 平台手动集成
拖拽下列 framework 从 SdkboxPlay
插件包的 plugins/ios 目录到您的 Xcode 工程中,在添加 frameworks 的时候,请勾选 Copy items if needed
。
sdkbox.framework
PluginSdkboxPlay.framework
如果您没有添加下面这些系统库,您有需要添加它们:
GameKit.framework
UIKit.framework
把 plugin/jsbindings
文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes
文件夹中.
把刚刚拷贝的文件拖动到 Xcode 中或使用 File -> Add files to... 来添加.
Android 手动集成
SDKBox 支持三种 Android 工程, command-line, eclipse 和 Android Studio.
- command-line 和 eclipse 类型的项目,
<project_root>
指代proj.android
. - Android Studio 类型的项目,
<project_root>
指代proj.android-studio
.
拷贝文件
从插件安装包中的 plugin/android/libs
目录拷贝下列 jar 文件到您的工程的 proj.android/libs 目录。
PluginSdkboxPlay.jar
sdkbox.jar
-
如果你使用 cocos2d-x 源码,拷贝 jar 文件到:
Android command-line:
cocos2d/cocos/platform/android/java/libs
Android Studio:
cocos2d/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-js 或者 lua ,拷贝 jar 文件到:
Android command-line:
frameworks/cocos2d-x/cocos/platform/android/java/libs
Android Studio:
frameworks/cocos2d-x/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-x 预编译包,拷贝 jar 文件到:
Android command-line:
proj.android/libs
从 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
把 plugin/jsbindings
文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes
文件夹中.
把你刚刚拷贝的 .cpp
文件添加到 Android.mk
文件的的 LOCAL_SRC_FILES 项.比如
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/NewSourceFile.cpp
修改 AppActivity.java
插件版本 >= 2.4.0.3
- 找到 AppActivity.java 文件
find . -name "AppActivity.java"
- 把
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
-
如果您使用 cocos2d-x 源代码,假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/ lib/Cocos2dxActivity.java
-
如果您使用 cocos2dx-x 预编译库, 假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:./src/org/cocos2dx/lib/Cocos2dxActivity.java
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
- 修改
Cocos2dxActivity.java
文件,导入如下包:
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
- 然后,修改
Cocos2dxActivity
类的onCreate(final Bundle savedInstanceState)
函数,添加一个调用语句SDKBox.init(this);
。添加的位置非常重要,必须在调用onLoadNativeLibraries();
之后。如下:
onLoadNativeLibraries();
SDKBox.init(this);
-
最后, 我需要提供合适的 overrides 方法的代码。这里有一些约定如下。
-
如果这个被列出的方法没有在
SDKBox
中定义,那么__定义它__。 -
如果这个被列出的方法已经被定义在
SDKBox
中,那么请调用这个在SDKBox
中的__同名方法__。
-
@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模式下可选)
- 编辑
project.properties
文件, 指定一个Proguard
配置文件。比如:
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 云存储
- 玩家自己的 iCloud 帐号必须是开启状态
- 开发者在对应的工程的必须把 iCloud 打开
用法
加载所有的游戏数据
sdkbox::PluginSdkboxPlay::loadAllData();
加载某一项游戏数据
sdkbox::PluginSdkboxPlay::loadGameData("key2");
保持数据
sdkbox::PluginSdkboxPlay::saveGameData("key1", "{\"game_name\": \"sdkbox go\", \"stage\": 3}");
iOS 存档官方文档
Android 存档官方文档
服务器认证
如果需要用开发者自己的服务器来作认证,可以按下面的步骤
iOS
- 实现
SdkboxPlayListener
中的onGenerateIdentityVerificationSignature
- 调用
sdkbox::PluginSdkboxPlay::generateIdentityVerificationSignature();
Android
- 在
sdkbox_config.json
中添加web_client_id
"sdkboxplay" : {
"web_client_id": "......."
}
web_client_id的生成可以参见这个文档
- 登录
- 调用
sdkbox::PluginSdkboxPlay::getPlayerAccountField("server_auth_code")
以获取 google server auth code