接入SDK

管理提醒: 本帖被 fm2010 设置为精华(2014-11-12)

http://www.cocoachina.com/bbs/read.php?tid-239087.html

本帖属于CocoaChina会员发表,转帖请写明来源和帖子地址

一、Cocos2d-x环境的搭建 
关于Cocos2d-x的环境搭建,网上相关的教程已经有很多了,在此就简单的介绍一下。

1.1 所需工具及软件 
1、JDK(1.7版本)
2、Android SDK(直接在Eclipse里下载所需要的SDK版本) 
3、Android NDK(r9d及以上)
4、Ant
5、Python(2.7版本)
6、Eclipse ADT
7、VS2012(Windows)或XCode(Mac OS) 
8、Cocos2d-x-3.3alpha0(本项目所使用的版本)

1.2 配置环境 
准备好如上软件后,配置好JDK与Python的环境变量,执行Cocos2d-x下的setup.py进行各个环境变量的设置,然后就可以使用cocos命令了。

例子: 
创建工程:cocos new demo -p com.game.demo -l cpp -d d:\cocos 
编译Android:cocos compile -p android -j 4

二、AnySDK环境的搭建 
下载打包客户端及Framework,解压文件夹,安装AnySDK打包客户端。详细使用可查看官方文档

三、实战项目的搭建 
3.1 项目源码下载 
从github上下载游戏项目,由于cocos2d目录是引用Cocos2d-x-3.3alpha0的github,要确保有下载下来。(注意:Cocos2d-x 3.3alpha0中的plugin、bindings-generator、cocos2d-console也是引用)

由于external目录里的库并不完全,所以要运行cocos2d-x的download-deps.py下载external库。

3.2 项目搭建 
1. 将AnySDK的Framework导入项目 
打开之前下载好的AnySDK文件夹,在AnySDK_Framework_C++里有三个文件夹,查看项目工程里的Application.mk(这里应该是proj.android/jni/Application.mk这个文件)里的STL库类型APP_STL := gnustl_static,所以这里要使用的就是protocols_gnustl_static文件夹。

将protocols_gnustl_static文件夹复制到EarthWarrior3D的proj.android目录下,重命名为protocols。然后将其中的res文件夹里的东西放到proj.android的res目录里。

2. 修改Android.mk文件配置Framework编译选项 
1、头文件目录里添加protocols下的android和include目录。

?


 

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \  

           $(LOCAL_PATH)/../protocols/android    \  

           $(LOCAL_PATH)/../protocols/include

2、添加PluginProtocolStatic静态库

?

 

LOCAL_WHOLE_STATIC_LIBRARIES += PluginProtocolStatic

3、引入模块库

?


 

$(call import-module,protocols/android)

3. 添加新路径至ndk module path 
本项目使用build_native编译,所以修改build_native.py文件:

?


 

if platform ==‘win32‘:

    ndk_module_path= ‘NDK_MODULE_PATH=%s;%s;%s/external;%s/cocos‘% ("./",cocos_root, cocos_root, cocos_root)

else:

    ndk_module_path= ‘NDK_MODULE_PATH=%s:%s:%s/external:%s/cocos‘% ("./",cocos_root, cocos_root, cocos_root)

如果使用cocos compile命令编译,则是修改build-cfg.json文件:

?


 

"ndk_module_path":[

        "../cocos2d",

        "../cocos2d/cocos",

        "../cocos2d/external",

        ""

],

4. 导入框架自带的的jar包并勾选export选项 
在Eclipse里导入游戏工程和libcocos2dx工程(cocos/platform/android/java),右键点击工程,选择Properties后选择Java Build Path,在面板上点击 Libraries,通过Add JARs...将libPluginProtocol.jar引进游戏工程。

PS:如果使用cocos compile命令编译,要将libPluginProtocol.jar放到libs目录下,还需要在Application.mk里面添加一句NDK_TOOLCHAIN_VERSION=clang。

5. 配置AndroidManifest.xml添加框架需要的权限

?


 

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

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

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

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

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

四、项目程序编写 
4.1 初始化AnySDK Framework 
1. 初始化JavaVM
 
首先,要在游戏工程加载jni的时候为AnySDK Framework设置JavaVM引用。先找到JNI_OnLoad函数,此函数是jni被加载时会首先被调用的函数。

本项目工程将platform/android目录下的javaactivity.cpp的JNI_OnLoad函数注释掉,然后拷贝JNI_OnLoad函数到main.cpp里。

1、导入头文件并声明命名空间。

?


 

#include "PluginJniHelper.h"

usingnamespace anysdk::framework ;

2、并且添加上javaVM代码。

?


 

PluginJniHelper::setJavaVM(vm);

2. 在JAVA层初始化AnySDK Framework框架 
1、首先找到游戏工程的主Activity,本项目为AppActivity。 
2、然后重写Activity的onCreate()方法,并新增如下代码来初始化AnySDK Framework:

?


 

import com.anysdk.framework.PluginWrapper;

protectedvoid onCreate(Bundle savedState) {

    super.onCreate(savedState);

    PluginWrapper.init(this);

}

3、重写Activity生命周期相关方法,代码如下:

?


 

import android.content.Intent;

@Override

protectedvoid onResume() {

    PluginWrapper.onResume();    

    super.onResume();

}

@Override

public void onPause(){

    PluginWrapper.onPause();

    super.onPause();

}

@Override

protectedvoid onActivityResult(intrequestCode, intresultCode, Intent data){

    PluginWrapper.onActivityResult(requestCode, resultCode, data);

    super.onActivityResult(requestCode, resultCode, data);

}

@Override

protectedvoid onNewIntent(Intent intent) {

    PluginWrapper.onNewIntent(intent);

    super.onNewIntent(intent);

}

3. 创建好需要的JAVA类和C++类 
创建新的C++的文件来编写AnySDK的逻辑代码,本项目创建了个PluginChannel类来实现用户系统和支付系统的功能,PluginChannel类需要继承UserActionListener和PayResultListener,重写其事件回调函数。

JAVA创建一个wrapper类,用来调用C++的函数。在PluginChannel.cpp里定义wrapper的函数(nativeInitPlugins)。

wrapper.java的定义:

?


 

public class wrapper {

    publicstatic nativevoid nativeInitPlugins();

}

PluginChannel.cpp里nativeInitPlugins的定义:

?


 

extern"C"

{

    JNIEXPORTvoid JNICALL Java_org_cocos2dx_cpp_wrapper_nativeInitPlugins(JNIEnv*  env, jobject thiz)

    {

        PluginChannel::getInstance()->loadPlugins();

    

}

4. 在C++层初始化AnySDK Framework框架 
在PluginChannel的loadPlugins函数里编写初始化、加载插件、设置监听等逻辑,然后调用该函数来进行初始化。在onCreate函数里的PluginWrapper.init(this)之后添加如下代码来进行初始化:

?


 

wrapper.nativeInitPlugins();

在PluginChannel的loadPlugins函数里所要做的处理如下: 
1、初始化appKey、appSecret、privateKey、oauthLoginServer参数。

?


 

std::string oauthLoginServer ="http://oauth.anysdk.com/api/OauthLoginDemo/Login.php";

std::string appKey ="BC26F841-DAC5-9244-D025-759F49997A28";

std::string appSecret ="1dff378a8f254ec8ad4b492cae72381b";

std::string privateKey ="696064B29E9A0B7DDBD6FCB88F34A555";

_agent = AgentManager::getInstance();

_agent->init(appKey,appSecret,privateKey,oauthLoginServer);

2、加载所有插件。

?


 

_agent->loadALLPlugin();

3、设置各个插件的Debug模式和监听等。

?


 

_pluginUser = _agent->getUserPlugin();

if(_pluginUser)

{

    _pluginUser->setDebugMode(true);

    _pluginUser->setActionListener(this);

}

_pluginsIAPMap  = _agent->getIAPPlugin();

std::map<std::string , ProtocolIAP*>::iterator iter;

for(iter = _pluginsIAPMap->begin(); iter != _pluginsIAPMap->end(); iter++)

{

    (iter->second)->setDebugMode(true);

    (iter->second)->setResultListener(this);

}

5. 编写PluginChannel类需要的函数 
PluginChannel类里的函数众多,这里就介绍下其中的几个函数。

1、login函数,通过getUserPlugin判断下是否有存在用户插件,存在则调用login函数弹出登陆界面。

?


 

void PluginChannel::login()

{

    if(_pluginUser)

    {

        _pluginUser->login();

    }

}

2、payment函数,因为AnySDK支持多种支付方式,所以通过getIAPPlugin获取所有的支付插件。使用map容器来添加支付所需的各种参数信息,调用支付插件的payForProduct进行支付。如果使用多种支付方式,还需要自己处理相关UI及界面。

?


 

void PluginChannel::payment()

{

    if(_pluginsIAPMap)

    {

        std::map<std::string, std::string> productInfo;

        productInfo["Product_Price"] ="1";

        productInfo["Product_Id"] ="1";

        productInfo["Product_Name"] ="豌豆荚测试a1";

        productInfo["Server_Id"] ="13";

        productInfo["Product_Count"] ="1";

        productInfo["Role_Id"] ="1";

        productInfo["Role_Name"] ="1";

        productInfo["Role_Grade"] ="1";

        productInfo["Role_Balance"] ="1";

        std::map<std::string , ProtocolIAP*>::iterator it = _pluginsIAPMap->begin();

        if(_pluginsIAPMap->size() == 1)

        {

            (it->second)->setDebugMode(true);

            (it->second)->payForProduct(productInfo);

        }

        elseif(_pluginsIAPMap->size() > 1)

        {

            //多支付,游戏开发商自己处理相关UI及界面

        }

    }

}

3、exit函数,通过isFunctionSupported判断下是否有存在exit函数,存在则调用函数来弹出退出界面。退出界面点击确定将回调kExitPage事件。

?


 

void PluginChannel::exit()

{

    if(_pluginUser && _pluginUser->isFunctionSupported("exit"))

    {

        _pluginUser->callFuncWithParam("exit",NULL);

    }

}

4、退出游戏处理,在接收到退出游戏的回调事件后,释放PluginChannel的内存,调用cocos2d-x的Director类的end函数结束游戏。

?


 

void PluginChannel::onActionResult(ProtocolUser* pPlugin, UserActionResultCode code, const char* msg)

{

    switch(code)

    {

        casekExitPage://退出游戏回调

            purge();

            Director::getInstance()->end();

            break;

    }

}

在析构函数里销毁用户系统以及卸载所有插件。

?


 

PluginChannel::~PluginChannel()

{

    destroy();

    unloadPlugins();

}

void PluginChannel::destroy()

{

    if(_pluginUser && _pluginUser->isFunctionSupported("destroy"))

    {

        _pluginUser->callFuncWithParam("destroy",NULL);

    }

}

voidPluginChannel::unloadPlugins()

{

    _agent->unloadALLPlugin();

}

6. 在游戏C++代码中调用PluginChannel类 
为了保证Win32工程可以正常运行,所有涉及AnySDK的代码都采用条件宏判断,在Win32工程下不进行编译。

本项目只修改游戏工程的MainMenuScene类,也就是只在主菜单的场景里添加AnySDK的功能。

1、添加PluginChannel头文件

?


 

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

#include "PluginChannel.h"

#endif

2、修改startgame_callback函数,点击START GAME的时候将会调用login函数来弹出登陆框。

?


 

void MainMenuScene::startgame_callback()

{

    CCLOG("login");

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

    CCLOG("PluginChannel");

    bReady =true;

    PluginChannel::getInstance()->login();//调用渠道登陆

#else

    CCLOG("startgame_callback");

    CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic();

    GameLayer::isDie=false;

    autoscene = (LoadingScene::audioloaded) ? HelloWorld::createScene() :LoadingScene::createScene();

    Director::getInstance()->replaceScene(scene);

    CCLOG("startgame_callback");

#endif

     

}

3、修改update函数,通过isLogined函数判断登陆状态,当状态为登陆则跳转场景开始游戏。

?


 

void MainMenuScene::update(float dt){

    pRate+=0.01;

    plane->setPosition3D(Vec3(visible_size_macro.width/2+50,480-20*sin(1.05*pRate),0));

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

    if(PluginChannel::getInstance()->isLogined()&&bReady)//判断登陆状态

    {

        CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic();

        GameLayer::isDie=false;

        autoscene = (LoadingScene::audioloaded) ? HelloWorld::createScene() :LoadingScene::createScene();

        Director::getInstance()->replaceScene(scene);

    }

#endif

}

4、修改recharge_callback函数,调用payment函数来显示支付界面。

?


 

void MainMenuScene::recharge_callback()

{

    CCLOG("recharge");

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

    CCLOG("PluginChannel");

    PluginChannel::getInstance()->payment();//调用渠道支付

#else

#endif

}

5、重写onKeyReleased函数来监听按键事件,在Android按返回键的时候调用退出界面。 
在init函数里调用如下代码开启按键监听:

?


 

setKeyboardEnabled(true);

重写onKeyReleased函数:

?


 

void MainMenuScene::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)

{

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

    switch(keyCode)

    {

        caseEventKeyboard::KeyCode::KEY_BACK:

            PluginChannel::getInstance()->exit();

            break;

    }

#endif

}

五、编译运行游戏 
最后进行编译,在编译完工程后,就可以在手机或模拟器上安装apk运行游戏了,可使用测试账号(用户名:csdn,密码:csdn)进行登陆,游戏效果如下:

时间: 2024-09-19 08:02:01

接入SDK的相关文章

高效率完成一次接入80个手游渠道SDK——游戏接入SDK服务端篇

1 概要    通常,游戏开发商并不会只在一个渠道上线他们的游戏,接入越多的渠道,代表着可能获取越多的用户,但同时也代表着越多的接入SDK工作量.工期和费用.一款游戏要有足够的用户,甚至需要接入30家以上的各种渠道,以保障自己的市场覆盖率. 单个SDK接入流程在一位有经验的全职客户端程序.一位全职服务端程序员.一位全职QA处理的情况下,需要3天时间才能完成.因此当一款产品面对30个甚至更多不同需求的渠道SDK时,人员成本和时间成本就会急剧增加.所以我们需要一个通用接口,来处理各种渠道的需求,这就

教你快速高效接入SDK——渠道SDK的接入(就是实现抽象层的接口而已)

题记:很多做游戏开发的人,估计都或多或少地接过渠道SDK,什么UC,当乐,91,小米,360......据统计国内市场当前不下于100家渠道,还包括一些没有SDK的小渠道.每个渠道SDK接入的方法呢,多是大同小异.但是,正是这些小异,又让SDK的接入,产生了无穷无尽的变数.所以,接入SDK之前,如果你没有经验,或者没有被SDK坑过,那么当你看到这系列文章的时候,你很幸运,你可以避免这一切了.如果你之前被坑过,而且还在继续被坑着,那么现在,就是你解脱的时刻. 先将之前的每一篇做个索引,方便亲们查阅

教你快速高效接入SDK——SDK接入抽象层的设计

题记:很多做游戏开发的人,估计都或多或少地接过渠道SDK,什么UC,当乐,91,小米,360......据统计国内市场当前不下于100家渠道,还包括一些没有SDK的小渠道.每个渠道SDK接入的方法呢,多是大同小异.但是,正是这些小异,又让SDK的接入,产生了无穷无尽的变数.所以,接入SDK之前,如果你没有经验,或者没有被SDK坑过,那么当你看到这系列文章的时候,你很幸运,你可以避免这一切了.如果你之前被坑过,而且还在继续被坑着,那么现在,就是你解脱的时刻. 上一篇文章,我们总体地分析并设计了一套

教你快速高效接入SDK——游戏接入SDK(只接入抽象框架)

题记:很多做游戏开发的人,估计都或多或少地接过渠道SDK,什么UC,当乐,91,小米,360......据统计国内市场当前不下于100家渠道,还包括一些没有SDK的小渠道.每个渠道SDK接入的方法呢,多是大同小异.但是,正是这些小异,又让SDK的接入,产生了无穷无尽的变数.所以,接入SDK之前,如果你没有经验,或者没有被SDK坑过,那么当你看到这系列文章的时候,你很幸运,你可以避免这一切了.如果你之前被坑过,而且还在继续被坑着,那么现在,就是你解脱的时刻. 上一篇文章我们说了整个U8 SDK抽象

教你快速高效接入SDK——总体思路和架构

题记:很多做游戏开发的人,估计都或多或少地接过渠道SDK,什么UC,当乐,91,小米,360......据统计国内市场当前不下于100家渠道,还包括一些没有SDK的小渠道.每个渠道SDK接入的方法呢,多是大同小异.但是,正是这些小异,又让SDK的接入,产生了无穷无尽的变数.所以,接入SDK之前,如果你没有经验,或者没有被SDK坑过,那么当你看到这系列文章的时候,你很幸运,你可以避免这一切了.如果你之前被坑过,而且还在继续被坑着,那么现在,就是你解脱的时刻. 完成一个SDK的接入并没有多少技术含量

高效率完成一次接入80个手游渠道SDK——游戏接入SDK客户端篇

一.引言 通常,游戏开发商并不会只在一个渠道上线他们的游戏,接入越多的渠道,代表着可能获取越多的用户,但同时也代表着越多的接入SDK工作量.工期和费用.一款游戏要有足够的用户,甚至需要接入30家以上的各种渠道,以保障自己的市场覆盖率.单个SDK接入流程在一位有经验的全职客户端程序.一位全职服务端程序员.一位全职QA处理的情况下,需要3天时间才能完成.因此当一款产品面对30个甚至更多不同需求的渠道SDK时,人员成本和时间成本就会急剧增加. 所以我们需要一个通用接口,来处理各种渠道的需求,这就是统一

Android教程-从零开始一步一步接入SDK

从零开始一步一步接入SDK 本篇博客想总结一下笔者在接入手游渠道SDK的一些经验方法,为想接入手游渠道或者想学习如何接入SDK的童鞋们提供一个参考.本篇博客基于Android平台,关于IOS接入SDK的方法,笔者以后有机会也会整理. 首先来给大家说明一下SDK,何为SDK?它的全称是,SoftWare Develop Kit,意思是软件开发工具包,它是可以辅助我们去开发某类软件的相关文档,范例和工具的集合.关于SDK,这里推荐一个服务商店,名叫Devstore(http://www.devsto

教你快速高效接入SDK——U8Server的初步分析

在U8SDK整套框架总体架构那篇文章,我们就给出了服务器端的解决方案,为此,我们加入了一个U8Server,来作为U8SDK整套框架的服务器端的统一用户认证中心和支付中心.那么,为了方便,我们这里再来引用一下登陆认证的流程图: 回顾下我们之前的分析,U8Server作为统一的登陆认证中心,针对的是多款游戏,那么每款游戏在接入SDK之前,就需要向U8Server申请一个AppID以及AppKey.这样,申请的过程,也就是在U8 Server中加入一条该游戏的数据记录.接下来,游戏需要配置每一个第三

U8SDK——游戏接入SDK(只接入抽象框架)

上一篇文章我们说了整个U8 SDK抽象成的设计,那这篇文章,我们就来验证一下,他是否如我们期待的那样,简单灵活. 正如之前所说,对于每个游戏,只需要接入抽象层,而每个渠道SDK的接入,就是该抽象层的一个实现而已.最后通过一键打包工具来完成最后的产出.那么,我们先来看看,游戏怎么来调用这个抽象层. 我们假设我们已经开发了一款游戏,面临上线,需要接入SDK,需要接入UC,当乐,91,360,小米等渠道.因为采用U8 SDK统一接入框架的思想,游戏工程本身不耦合具体的每个渠道SDK,而只是调用U8 S

Google Play笔记之接入SDK

更新:好消息:Unity5.3添加了google play.Mac .AppStore.windows store的IPA接口,我们做内购日后方便多啦!关于国内渠道的接入,推荐通用SDK平台,比如anySDK,棱镜SDK(需要付费) Unity IPA: http://unity3d.com/cn/learn/tutorials/topics/analytics/integrating-unity-iap-your-game-beta http://unity3d.com/cn/services