cocos2d-x -- 渠道SDK【棱镜】接入(1)

棱镜SDK简介

    若想让游戏上线,渠道接入步骤是必不可少的,为了避免一对一接入渠道问题,我选择了棱镜SDK,因为棱镜是游戏与渠道SDK的中间层,为CP厂商屏蔽各个渠道SDK之间的差异,整个接入过程,不会改变各个渠道SDK的功能、特性、参数等,对玩家完全透明。

    棱镜平台基本工作原理:http://dev.ljsdk.com/ljdocs/lj_principle.html

    棱镜技术接入文档(cocos2d-x)::http://dev.ljsdk.com/ljdocs/lj_tech_integration_cpp.html

    棱镜SDK下载:http://dev.ljsdk.com/ljdocs/lj_tech_general.html

客户端接入流程

1.将Demo项目中Classes/GameProxy.h 复制到你的C++工程中头文件存放的位置,如Cocos2dx项目放入Classes目录, 将Classes/gameproxy.cpp 放入源码目录,如Cocos2dx的Classes目录:

2.windows平台添加代码如下:

HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__


#include "cocos2d.h"


class HelloWorld : public cocos2d::CCLayer

{

public:

     // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone

    virtual bool init();


    // there's no 'id' in cpp, so we recommend returning the class instance pointer

    static cocos2d::CCScene* scene();


    // a selector callback

    void menuCloseCallback(CCObject* pSender);


    void setUserListener();


    void loginCallback(CCObject* pSender);

 
    void logoutCallback(CCObject* pSender);


    void chargeCallback(CCObject* pSender);


    void payCallback(CCObject* pSender);


    void exitCallback(CCObject* pSender);


    void showInfo(const char* str);


    // implement the "static node()" method manually

    CREATE_FUNC(HelloWorld);


private:

   cocos2d::CCLabelTTF* outputLabel;

};


#endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.cpp

#include "HelloWorldScene.h"

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

#include "GameProxy.h"

#endif


USING_NS_CC;


CCScene* HelloWorld::scene()

{

// 'scene' is an autorelease object

CCScene *scene = CCScene::create();


// 'layer' is an autorelease object

HelloWorld *layer = HelloWorld::create();


// add layer as a child to scene

scene->addChild(layer);


// return the scene

return scene;

}


// on "init" you need to initialize your instance

bool HelloWorld::init()

{

//////////////////////////////

// 1. super init first

if ( !CCLayer::init() )

{

return false;

}


CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();


CCLabelTTF* pLabel = CCLabelTTF::create("CoCos2d-x SDKTest", "Arial", 30);


// position the label on the center of the screen

pLabel->setPosition(ccp(origin.x + visibleSize.width/2,

origin.y + visibleSize.height - pLabel->getContentSize().height));

// add the label as a child to this layer

this->addChild(pLabel, 1);



this->outputLabel = CCLabelTTF::create("Output Here", "Arial", 20);

this->outputLabel->setHorizontalAlignment(kCCTextAlignmentLeft);

// position the label on the center of the screen

this->outputLabel->setAnchorPoint(ccp(0, 0));

this->outputLabel->setPosition(ccp(origin.x + visibleSize.width/2, origin.y));

this->addChild(this->outputLabel, 1);



// add "HelloWorld" splash screen"

CCSprite* pSprite = CCSprite::create("icon.png");


// position the sprite on the center of the screen

pSprite->setPosition(ccp(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2));


// add the sprite as a child to this layer

this->addChild(pSprite, 0);



CCMenuItemFont *loginItem = CCMenuItemFont::create(

"login",

this,

menu_selector(HelloWorld::loginCallback));

CCMenuItemFont *logoutItem = CCMenuItemFont::create(

"logout",

this,

menu_selector(HelloWorld::logoutCallback));


CCMenuItemFont *chargeItem = CCMenuItemFont::create(

"charge",

this,

menu_selector(HelloWorld::chargeCallback));


CCMenuItemFont *payItem = CCMenuItemFont::create(

"pay",

this,

menu_selector(HelloWorld::payCallback));


CCMenuItemFont *exitItem = CCMenuItemFont::create(

"exit",

this,

menu_selector(HelloWorld::exitCallback));



float borderWidth = 0;

float currentYBorder = origin.y + visibleSize.height;


float offset = borderWidth + loginItem->getContentSize().height/2;


loginItem->setPosition(ccp(origin.x + loginItem->getContentSize().width/2 + borderWidth,

currentYBorder - offset));




currentYBorder -= 2 * offset;

offset = borderWidth + logoutItem->getContentSize().height/2;

logoutItem->setPosition(ccp(origin.x + logoutItem->getContentSize().width/2 + borderWidth ,

currentYBorder - offset));


currentYBorder -= 2 * offset;

offset = borderWidth + chargeItem->getContentSize().height/2;

chargeItem->setPosition(ccp(origin.x + chargeItem->getContentSize().width/2 + borderWidth ,

currentYBorder - offset));


currentYBorder -= 2 * offset;

offset = borderWidth + payItem->getContentSize().height/2;

payItem->setPosition(ccp(origin.x + payItem->getContentSize().width/2 + borderWidth ,

currentYBorder - offset));



currentYBorder -= 2 * offset;

offset = borderWidth + exitItem->getContentSize().height/2;

exitItem->setPosition(ccp(origin.x + exitItem->getContentSize().width/2 + borderWidth ,

currentYBorder - offset));


CCMenu* pMenu = CCMenu::create(loginItem,logoutItem,chargeItem,payItem,exitItem,NULL);

pMenu->setPosition(CCPointZero);

this->addChild(pMenu,1,2);


#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

this->showInfo(GameProxy::GetAndroidManifestMeta("XMGAME_PRODUCT_CODE"));

#endif



return true;

}





void HelloWorld::showInfo(const char *info){


this->outputLabel->setString(info);

CCLOG("showinfo %s", info);

}



#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

class XMUserListenerImpl: public XMUserListener {

private:

HelloWorld * parent;

public:

XMUserListenerImpl(HelloWorld* parent) {

this->parent = parent;

}

virtual void onLoginSuccess(XMUser user, const char *customParams) {


// 游戏的登陆逻辑需要写在这里


// 当游戏调用 GameProxy::Login(params) 时,该函数会被调用

// 其中user对象为渠道登陆系统返回的用户相关参数,包含uid token 渠道号等

// 其中params为调用GameProxy::Login( params)时,传入的params

// 确保该函数被调用后,用户可以正确地进入游戏


CCLOG("login success");


stringstream is;

is << "uid : " << user.getUserId() << "\ntoken : " << user.getToken() << "\nchannelId : " << user.getChannelId();

parent->showInfo(is.str().c_str());

GameProxy::SetXMRoleData("1", "hi", "10", "1", "1");

};


virtual void onLoginFailed(const char *reason,

const char *customParams) {

stringstream is;

is << "login failed reason: " << reason << "\ncustomParams: " << customParams;

parent->showInfo(is.str().c_str());


};

virtual void onLogout(const char *customParams) {

// 游戏相关的用户登出注销逻辑需要写在这里


// 当渠道的用户中心界面中点击注销,该函数会被调用

// 当游戏调用 GameProxy::Logout(params) 时,该函数也会被调用

// 其中params为用户调用 GameProxy::Logout(params) 时传入的params

// params可以用来传递一些游戏中的上下文,可以是任意字符串

// 确保游戏中任何时候,该函数被调用后,游戏可以正确登出


parent->showInfo("logout");

};

};



class PayCallBackImpl:public PayCallBack{

private:

HelloWorld* parent;

public:

PayCallBackImpl(HelloWorld* parent) {

this->parent = parent;

}

virtual void onPaySuccess(char *successinfo){

stringstream is;

is << "sucess: " <<successinfo;

parent->showInfo(is.str().c_str());

};

virtual void onPayFail(char *failinfo){

stringstream is;

is << "payfailed: " << failinfo;

parent->showInfo(is.str().c_str());

};

};


class ExitCallBackImpl:public ExitCallBack{

public:

virtual void onGameExit(){

CCDirector::sharedDirector()->end();

};

virtual void onNo3rd(){


CCDirector::sharedDirector()->end();

};

};


#endif



void HelloWorld::setUserListener(){

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

GameProxy::SetUserListener(new XMUserListenerImpl(this));

#endif

}



void HelloWorld::loginCallback(CCObject* pSender)

{

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

this->showInfo("logining");

HelloWorld::setUserListener();

const char *customParams = "login";

GameProxy::Login(customParams);

#endif

}


void HelloWorld::logoutCallback(CCObject* pSender){

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

const char *customParams = "logout";

GameProxy::Logout(customParams);

#endif

}



void HelloWorld::chargeCallback(CCObject* pSender){

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

const char *itemName = "元宝";

int unitPrice = 10;

int defalutNum = 500;

const char *callBackInfo = "this is callback info...";

const char *callbackUrl = "http://test";

GameProxy::Charge(itemName, unitPrice, defalutNum, callBackInfo, callbackUrl,new PayCallBackImpl(this));

#endif

}





void HelloWorld::payCallback(CCObject* pSender){

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

int amount = 10;

const char *unitName = "天币";

int count = 118;

const char *callBackInfo = "this is callback info";

const char *callbackUrl = "http://test";


GameProxy::Pay(amount, unitName, count, callBackInfo, callbackUrl, new PayCallBackImpl(this));

#endif

}



void HelloWorld::exitCallback(CCObject* pSender){

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

GameProxy::Exit(new ExitCallBackImpl());

#endif

}


void HelloWorld::menuCloseCallback(CCObject* pSender)

{

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)

CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");

#else

CCDirector::sharedDirector()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

exit(0);

#endif

#endif

}


3.android平台:

环境搭建:

将Demo项目中libs目录下jar包复制到游戏项目的libs目录下
将Demo项目中assets目录下的文件复制到游戏项目的assets目录下

Android.mk:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.InsetSDK.org"

android:versionCode="1"

android:versionName="1.0">


<uses-sdk android:minSdkVersion="8"/>

<uses-feature android:glEsVersion="0x00020000" />


<application

android:name="com.xinmei365.game.proxy.XMApplication"

android:label="@string/app_name"

android:icon="@drawable/icon">


<activity android:name=".InsetSDK"

android:label="@string/app_name"

android:screenOrientation="landscape"

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

android:configChanges="orientation">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<meta-data android:name="XMGAME_CHANNEL_CODE" android:value="9f10f46c37214442ba473b5409a05ebf" />

<meta-data android:name="XMGAME_PRODUCT_CODE" android:value="lsjs" />


</application>

<supports-screens android:largeScreens="true"

android:smallScreens="true"

android:anyDensity="true"

android:normalScreens="true"/>


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

</manifest>

Activity的Java代码:

public class InsetSDK extends Cocos2dxActivity{


protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);


GameProxyNativeStub.init(this, GameProxy.getInstance(), new XMGLThreadRunner() {


@Override

public void runOnGLThread(Runnable pRunnable) {

InsetSDK.this.runOnGLThread(pRunnable);


}});

GameProxy.getInstance().applicationInit(this);

GameProxy.getInstance().onCreate(this);


}


public Cocos2dxGLSurfaceView onCreateView() {

Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);

// InsetSDK should create stencil buffer

glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);


return glSurfaceView;

}


static {

System.loadLibrary("cocos2dcpp");

}


public void onStop() {

super.onStop();

GameProxy.getInstance().onStop(this);

}


public void onDestroy() {

super.onDestroy();

GameProxy.getInstance().onDestroy(this);

}


public void onResume() {

super.onResume();

GameProxy.getInstance().onResume(this);

}

public void onPause() {

super.onPause();

GameProxy.getInstance().onPause(this);

}

public void onRestart() {

super.onRestart();

GameProxy.getInstance().onRestart(this);

}


protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

GameProxy.getInstance().onActivityResult(this, requestCode, resultCode, data);

}

}


真机运行效果图:

猜你喜欢

转载自blog.csdn.net/u012278016/article/details/82048082