版本
- cocos2dx: 2.1.3
- 91SDK: 3.2.6.1(Android)
适用范围
这里仅仅讨论的是Android的版本
正题
不得不说,91的SDK没有动态库,反而编译起来坑不会那么多,不过既然是Android的整合,坑自然也不会少你的呀,啊哈哈。文档和流程很清楚,可以到91对应的论坛上参考
接入91SDK
加载Lib库
直接的Eclipse中,把91SDK_LibProject_complete这个项目加进来,然后在你的项目的properties中的Android一栏中增加一个项目依赖,如图,直接Add一个即可
注意Lib项目中的两个jar:alipay_msp.jar android-support-v4.jar,这两个可能会和现有项目中的依赖冲突,安全起见还是用lib包中的好了,如果你本地有,则删除,反正加了项目依赖后这几个文件都会打包到apk中去的。如图。
初始化SDK
以下的代码大部分是抄Demo的,莫见怪
// ///////////////////////////////////////////////////////////////////////////// // 这里开始定义91市场的接入 // 变量定义,初始化等 /* 初始化完成监听端口 */ private OnInitCompleteListener m_onInitCompleteListener = null; /* 91的toolbar */ private NdToolBar m_NDToolBar = null; /** * 初始化91SDK,在 onCreate 中调用 */ private void initSDK91() { // if(AppPreferences.isDebugMode(this)){ NdCommplatform.getInstance().ndSetDebugMode(0);// 设置调试模式 // } NdCommplatform.getInstance().ndSetScreenOrientation( NdCommplatform.SCREEN_ORIENTATION_AUTO); m_onInitCompleteListener = new OnInitCompleteListener() { @Override protected void onComplete(int ndFlag) { switch (ndFlag) { case OnInitCompleteListener.FLAG_NORMAL: // initActivity(); // 初始化自己的游戏 int orient = NdCommplatform.SCREEN_ORIENTATION_LANDSCAPE; // 横屏 NdCommplatform.getInstance().ndSetScreenOrientation(orient); break; case OnInitCompleteListener.FLAG_FORCE_CLOSE: default: // 如果还有别的Activity或资源要关闭的在这里处理 break; } } }; NdAppInfo appInfo = new NdAppInfo(); appInfo.setCtx(this); appInfo.setAppId(Constants.SDK_91_APPID);// 应用ID appInfo.setAppKey(Constants.SDK_91_APPKEY);// 应用Key /* * NdVersionCheckLevelNormal 版本检查失败可以继续进行游戏 NdVersionCheckLevelStrict * 版本检查失败则不能进入游戏 默认取值为NdVersionCheckLevelStrict */ appInfo.setNdVersionCheckStatus(NdAppInfo.ND_VERSION_CHECK_LEVEL_STRICT); // 初始化91SDK NdCommplatform.getInstance().ndInit(this, appInfo, m_onInitCompleteListener); // 创建Toolbar if (m_NDToolBar == null) { m_NDToolBar = NdToolBar.create(this, NdToolBarPlace.NdToolBarRightMid); } m_NDToolBar.show(); } /** * 清理91数据 */ private void cleanSDK91() { // 移除监听 if (m_onInitCompleteListener != null) m_onInitCompleteListener.destroy(); // 清理工具条 if (m_NDToolBar != null) m_NDToolBar.recycle(); }
这里特别要注意,91的Toolbar一定要在初始化后调用,否则会报资源加载出错的Exception,然后程序就崩了,切记
这两个函数,分别在onCreate和onDestroy中调用即可。一个是初始化的,一个是销毁清理用的。
登录接入
登录这里其实有个坑,呃,我还没跨过去,只是有解决思路,但是后来我把cpp中的代码稍微改了下,就暂时绕过去了,后面会讲到。
// 登录监听 private OnLoginProcessListener m_onLoginProcessListener = null; /** * 91帐号登录 * */ private void SDKND91AccountLogin() { Activity act = this; m_onLoginProcessListener = new OnLoginProcessListener() { @Override public void finishLoginProcess(int code) { String tip = ""; // hideLoading(); JSONObject prms = new JSONObject(); // 得到用户昵称 try { // 设置请求业务类型为登录请求 prms.put("requestType", Constants.REQ_LOGIN); prms.put("retcode", "-1"); // 登录的返回码检查 if (code == NdErrorCode.ND_COM_PLATFORM_SUCCESS) { // 得到用户信息,返回到cocos2dx中 tip = "登录成功"; // actInstance.runOnUiThread(new Runnable() { // public void run() { prms.put("retcode", "0"); prms.put("nickname", NdCommplatform.getInstance() .getLoginNickName()); prms.put("account", "91_" + NdCommplatform.getInstance().getLoginUin()); // } // }); // 账号登录成功,测试可用初始化玩家游戏数据 // 有购买漏单的此时可向玩家补发相关的道具 } else if (code == NdErrorCode.ND_COM_PLATFORM_ERROR_CANCEL) { tip = "取消登录"; } else { tip = "登录失败,错误代码:" + code; } // 把数据返回给客户端 AndroidNDKHelper.SendMessageWithParameters( Constants.SDKBussinessCallback, prms); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } Toast.makeText(actInstance, tip, Toast.LENGTH_SHORT).show(); } }; // showLoading(); NdCommplatform.getInstance().ndLogin(this, m_onLoginProcessListener); }
这里的登录函数需要有个监听用来响应登录状态回调,我就不展开了。关于AndroidNDKHelper,这个挺好用的,可以在cpp中直接调用和底层NDK的交互,并且支持Android和iOS两个版本,不用直接写那个JNI的调用还是很爽的,虽然有JNIHelper,但是写起来还是比较晦涩冗长,关键是可以在cpp中统一代码调用两个平台的NDK。推荐大家用下,Github上也有源代码。
这里是登录的代码,如果要在cocos2dx中调用的话,只需要登录的时候调用JNI,然后JNI去调用这个函数即可,后面的就是SDK的事情了,登录完成后会在Listener中回调的,只要回调回cocos2dx中通知下即可。不过注意,这里有个小坑,就是貌似回调到cpp中后,可能不是主线程(虽然我JAVA的debug中看到的线程号是主线程),所以如果像这样做的话,cpp中的响应不能有UI的操作,否则直接崩你没商量。我这里偷了个懒,把cpp中的UI操作全都注释了,就修改了个变量的状态,然后主线程定时器扫到这个变量状态变化后,会调用对应应用登录的操作,这里就切换过去了。在360接入的时候,貌似没有这种线程问题,可能360的SDK登录是同步的,而91这个是登录状态起线程异步回调的,没研究过,如果有谁知道知会一声,不胜感激。不知道把91这个模块封装到一个独立的Activity中,然后通过Intent传递数据是否能解决cpp中UI线程的问题,因为即使我用this.runOnUiThread来包一层也还是有问题。
接入支付
支付的话,91提供的种类还是相当繁多的!我这里使用的代币充值,就是先充成91币,然后再和应用结算。需要在支付的时候填入对应的coins,当然需要在91的后台配置下和软妹币的兑换比例,然后填入你需要充值的游戏内的东西即可(也可以是对应的商品价格)。服务器端的回调通知不在本篇的讨论范围。
太简单了,代码就不贴了,给个对应的详细介绍地址好了,接91的应该都知道吧,给没注意的小白看下:请猛击我