• 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);
    	}
    }

    真机执行效果图:






  • 相关阅读:
    IOS 获取时间的问题
    JQ 点赞
    截取字符串第一个空格前的字符
    JQ 的一些方法
    匿名函数var a =function(){}和function a(){}的区别
    完美支持中文编程的 Emacs 配置文件 .emacs
    linux find 命令忽略某个或多个子目录的方法
    Linux下如何用date设置时间
    nagios的监控代码!
    shell脚本监控apache进程数和oracle连接数
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4024121.html
Copyright © 2020-2023  润新知