cocos2d-x -- 渠道SDK【稜鏡】接入(1)
阿新 • • 發佈:2019-02-08
稜鏡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);
}
}
真機執行效果圖: