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


client接入流程

1.将Demo项目中Classes/GameProxy.h 拷贝到你的C++project中头文件存放的位置,如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() << "
token : " << user.getToken() << "
channelId : " << 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 << "
customParams: " << 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);
	}
}

真机执行效果图:






原文地址:https://www.cnblogs.com/mfrbuaa/p/4024121.html