《集成 Framework》

重要提示: 服务端开发人员可以直接去->>下一关

支持的游戏类型

AnySDK 支持 Android、iOS、H5 3 种平台,提供C++、Lua(Cocos)、JS(Cocos)、Java、C#(Unity) 5 种框架。

因此,无论是 H5 还是 Android、iOS 原生,无论是使用自研引擎还是开源引擎(比如 Cocos2d-x、Unity3D、Unreal、Ogre、Creator、Egret、LayaBox),都能够很轻松地接入 AnySDK。

示例游戏

本文将以一个 C++(采用 Cocos2d-x 引擎)的游戏为例,演示如何集成 AnySDK Framework,其他语言或引擎开发的游戏接入过程大同小异。

先去 Cocos 官网下载 Cocos 2d-x 3.15 引擎并解压,命令行下进入

cocos2d-x-3.15/tools/cocos2d-console/bin/

然后执行

./cocos new -p com.anysdk.sample -d ../../../../ -l cpp Sample_Cpp

这样,我们就在存放引擎的同级目录得到了一个名为 Sample_Cpp 的基于 Cocos2d-x 的 C++ 的最简单的游戏。Cocos2d-x 是一个跨平台的开源游戏引擎,在我们创建的 Sample_Cpp 中就有我们接下来要用到的 Android、iOS 工程,如图:

即使你对 Cocos2d-x 不熟悉也不要紧,相信你对类似的游戏工程代码并不陌生。 接下来我们看看如何将 AnySDK Framework 集成到游戏工程这个才是重点。

集成 AnySDK Framework

使用 Eclipse 打开 proj.android 工程(或者 Xcode 打开 proj.ios_mac 工程,目前你只需要先以你熟悉的开发环境掌握 Android 或 iOS 其中之一种即可),然后参考:接入指南 -> 客户端(CPP)-> 快速集成指南 -> Android 接入

重要提示:每一篇《快速集成指南》都是针对某一种语言的游戏工程的说明,而不是针对使用了某种引擎的具体游戏工程的手把手教程,因此初次阅读的话可能并不会觉得轻松,推荐的方式是先快速阅读一遍有个大概的印象和理解,然后再动手按照文档一步步进行集成。 如果你一上手就按照《指南》一步一步照搬的话,很可能会遇到一些小挫折。

如果你本次打开的是 Xcode 工程,请跳转至:iOS接入

同理, Lua 原生游戏工程(含Android、iOS),请跳转至:接入指南 -> 客户端(Lua)-> 快速集成指南

JS 原生游戏工程(含Android、iOS,注意不是指 H5 游戏),请跳转至:接入指南 -> 客户端(JS)-> 快速集成指南

Java 原生游戏工程(Android),请跳转至:接入指南 -> 客户端(Java)-> 快速集成指南

Unity 原生游戏工程(Android、iOS),请跳转至:接入指南 -> 客户端(Unity)-> 快速集成指南

H5 游戏工程(比如 Cocos2d-js、Egret、LayaBox等),请跳转至:接入指南 -> 客户端(H5)-> 快速集成指南

具体的集成过程,在对应的《指南》已经讲得非常详细,在此就不再赘述了。回顾一下,按照《指南》文档一共修改了以下这些地方就完成了集成 AnySDK Framework 工作:

  1. 下载 AnySDK Framework 并复制相应的文件到项目中

  2. 修改 Android.mk ,导入 PluginProtocolStatic 静态库

  3. 修改工程属性,导入框架自带的 jar 包并勾选 export 选项

  4. 修改 AndroidManifest.xml ,添加框架需要的权限

  5. 修改 jni/hellocpp/main.cpp ,为 AnySDK framework 设置 JavaVM 引用

  6. 修改 src/org/cocos2dx/cpp/AppActivity.java ,在 JAVA 层初始化 AnySDK Framework

  7. 修改 Classes/AppDelegate.cpp ,在 C++ 层初始化 AnySDK Framework

恭喜你!你已经达成了成功的重要一步!

此时,我们运行一下游戏,发现跟没有集成 AnySDK Framework 时并无明显变化。还记得前面的章节《接入必读》中讲到的 AnySDK 的原理吗?原因是 AnySDK Framework 其实是一个抽象出来的“统一接口”——游戏调用 AnySDK Framework 中的接口,AnySDK Framework 中的接口再去实现调用具体的第三方 SDK,从而实现“一次接入,批量生成渠道包”的目的,将我们从繁琐和重复的 SDK 接入工作中解放出来。

那么接下来我们就需要根据实际需要在游戏中适当的位置添加上调用 AnySDK Framework 中的接口的代码了,比如在点击登录时调用登录接口、点击购买道具时调用支付接口。

接口调用要点

在动手之前,建议先粗略地阅读一下《框架接口设计

阅读完我们就会知道,AnySDK Framework 为用户系统、支付系统、广告系统、统计系统、社交系统、分享系统分别提供了插件机制。

通过 AgentManager 这个管理类可以获取到这些插件,比如 AgentManager::getInstance()->getUserPlugin() 获取用户系统插件,然后就可以调用里面的登录、注销、切换账号等方法。。。

方法的执行结果会通过消息回调的方式通知给游戏,我们需要实现抽象方法 Listener,设置监听类,就可以捕获到请求结果信息。

作为一名 C++ 程序员,建议你略花一点小时间大致看一下 protocols/include 下面的 AgentManager.h、ProtocolUser.h、ProtocolIAP.h 这几个头文件,你会对 AnySDK Framework 的实现原理有个更清晰的认识。如果你是一位熟练的开发人员的话,接下来的调用代码示例你可能不用看自己都会了 :-)

调用登录

接口调用

为了测试,我们先在游戏的主场景(HelloWorldScene.cpp)屏幕的右键添加一个“登录”按钮:

    auto button = Button::create();
    button->setTitleText("登录");
    button->setPosition(Vec2(visibleSize.width*0.9 + origin.x, visibleSize.height/2 + origin.y));
    this->addChild(button, 2);

    button->addTouchEventListener(CC_CALLBACK_2(HelloWorld::btnLoginClick,this));

它看起来会是这样:

然后我们在登录按钮的触摸回调函数里调用 AnySDK Framework 的登录接口:

void HelloWorld::btnLoginClick(cocos2d::Ref *pSender, cocos2d::ui::Widget::TouchEventType type)
{
    switch (type)
    {
        case Widget::TouchEventType::BEGAN:
            CCLOG("Touch Down");
            break;

        case Widget::TouchEventType::MOVED:
            CCLOG("Touch Moved");
            break;

        case Widget::TouchEventType::ENDED:
            CCLOG("Touch Ended");
            if(AgentManager::getInstance()->getUserPlugin())
            {
                AgentManager::getInstance()->getUserPlugin()->login();
            }
            break;

        case Widget::TouchEventType::CANCELED:
            CCLOG("Touch Canceled");
            break;

        default:
            break;
    }
}

正如上文所述,调用框架的具体方法一般都是通过 AgentManager 这个管理类获取到对应的插件,然后调用插件里的具体方法。运行一下游戏,点击一下登录按钮,你会看到框架内置的登录界面:

消息回调

好了,接下来你肯定会问游戏怎么得到这个登录的结果呢?我们需要游戏中实现对应的接口(登录为 ProtocolUser 中的 UserActionListener 接口)抽象方法,设置监听类,就可以捕获到请求结果信息。 实现好接口后不了忘了设置一下监听:

将手机在调试模式下连接上你的电脑,运行游戏,通过 Eclipse 的 Logcat (或者命令行adb logcat)来观察一下 log 日志,当我们点击登录按钮并在弹出的登录框里随便输入一个用户名和密码点击登录后,如果一切顺利的话,你应该会看到消息回调函数里 CCLOG("____AnySDK____, onActionResult:%d, msg%s\n",code,msg); 的执行结果:

至此,客户端集成 AnySDK Framework 的工作已经初步成型了。我们只需要在 onPayResult 消息回调函数里根据返回的消息编写具体的业务逻辑代码即可了。那么,更多的用户接口参考 《接入指南》 -> 《客户端(*)》-> 《用户系统》即可。(本文是基于 C++ 游戏进行演示的,所以对应地阅读 用户系统

阶段性测试

截目前为止,虽然我们客户端的登录调用已经完成了,但是还没有真正地与服务端“互动”一把。不要紧,AnySDK 为用户提供了一个测试账号的功能,在还没有正式进行服务端接入之前,我们可以按照《创建测试账号》文档进行操作,之后在你的游戏客户端输入你创建的测试帐号密码进行登录,如果一切正常的话,你应该在后台会看到类似于这样的登录日志:

关于登录的原理

此时,你可能会挺好奇,客户端的登录数据被发送到了哪里?[开发者管理后台]又是怎么捕获到这些日志的?

细心的读者应该还记得在《快速集成指南》里,关于初始化 AnySDK Framework 时所填写的那些参数的说明吧?

http://oauth.anysdk.com/api/OauthLoginDemo/Login.php 就是 AnySDK 提供给母包做登录时框架请求时的测试地址(正式打出渠道包的时候会被替换成相应渠道在 AnySDK 客户端中配置的登录验证地址),这个登录验证地址会将登录请求转发给 AnySDK Server。

详细的登录原理请阅读 《接入指南》->《服务端》-> 《统一登录验证》-> 统一登录验证流程章节,建议仔细阅读和理解这篇文档,并理解什么是“登录验证地址”。

调用支付

接口调用

同样地我们在游戏的主场景(HelloWorldScene.cpp)屏幕的右侧添加一个“充值”按钮,然后我们在充值按钮的触摸回调函数里调用 AnySDK Framework 的支付接口:

消息回调

修改 AppDelegate.h 头文件使其实现 PayResultListener 接口:

设置监听:

阶段性测试

将手机在调试模式下连接上你的电脑,运行游戏,通过 Eclipse 的 Logcat (或者命令行 adb logcat)来观察一下 log 日志,当我们点击充值按钮时,应该会看到这样的支付确认框(支付时,AnySDK Framework 首先会检测用户是否已经登录,如果未登录会先弹出登录框):

点击确认支付,如果一切顺利的话,你应该会看到消息回调函数里 CCLOG("____AnySDK____, onPayResult, %s\n", msg); 的执行结果:

通过 [AnySDK 客户端 -> 打包工具 -> 管理后台] 进入开发者管理后台(或者直接浏览器访问 http://dev.anysdk.com),依次点击 [支付管理 -> 订单列表 -> 查询] ,你应该会看到类似于以下的充值记录:

关于支付的原理

详细的支付原理请阅读 《接入指南》->《客户端(*)》-> 《支付系统

备注

  1. 本文是以基于 C++ 和 Cocos 2d-x 引擎的游戏,且平台为 Android 进行示例的,你也许是其他语言或引擎开发的游戏,在阅读本文时感觉不太适应,但是不要紧,本文演示的只是集成的过程,重点还是找到对应语言的《快速集成指南》进行参考即可。

  2. 本文是一个快速的入门指引,关于登录和支付的调用都是点到为止,更为详细的具体编码可以借鉴一下我们给出的《游戏接入实战》范例。

  3. 为了最简洁地演示调用登录和支付,本文中消息回调是直接写在 AppDelegate.cpp 中的。在实际的游戏项目中,除了登录外,还会有登出、切换账号等,如果将消息回调直接写在游戏场景代码中,甚至会引内存回收的相关不良后果。进行适当模块封装,是一个良好的开发习惯,建议开发者在具体编码的时候可以借鉴《游戏接入实战》范例中 PluginChannel 这个类的实现。

下一步

快点我开启下一关