天天看點

WP8:在Cocos2d-x中使用OpenXLive

OpenXLive是Windows Phone和Windows 8平台上最大的遊戲社交網絡平台,對Windows Phone遊戲的開發提供了很多非常優秀的輔助功能,比如遊戲基礎功能(積分榜、成就、公告、線上玩家等)、推廣功能(推薦遊戲、推廣牆)、社交功能(分享、動态、任務、交友)以及支付功能(支付寶、點卡支付、禮品卡)等一些列相關功能。除了OpenXLive之外,一批優秀的第三方庫基本都是由C#編寫的,如果需要在Direct3D中使用到這些功能,就需要采用拙者在此前提到的一個解決方案,傳送門:

《WP8:在WinRT元件(C++)中調用C#類庫的解決方案》

以下我們以OpenXLive為例子,介紹如何在Cocos2d-x中進行調用。

一.    Cocos2d-x for Windows Phone

到2013年底,幾大手遊引擎都陸續支援WP8了,特别是Unity3D和Cocos2d-x。有過遊戲開發經驗的朋友們應該對這兩個引擎不陌生,WP8對Native C++的支援,使得其他平台上用C++編寫的遊戲移植到WP8平台上變得非常簡單。Cocos2d-x在2.2.1版本之前在WP8上隻支援純Direct3D工程模式,目前在Github上已提供了支援XAML的混合托管模式,傳送門:https://github.com/MSOpenTech/cocos2d-x/tree/wp8-xaml2

Git下來之後打開cocos2d-wp8.vc2012.sln可以看到工程結構如下:

WP8:在Cocos2d-x中使用OpenXLive
其中HelloCpp-XAML采用一個XAML與Direct3D元件混合的托管模式,是一個标準的WP8工程模闆,編譯并運作可見到:
WP8:在Cocos2d-x中使用OpenXLive

其中的C#項目負責Windows Phone正常控件和頁面邏輯,C++項目是一個基于Direct3D的Windows Phone Runtime Component,負責所有的遊戲邏輯,兩者通過DrawingSurface或DrawingSurfaceBackgroundGrid控件混入Direct3D圖像,以非常小的性能代價擷取托管代碼的優秀特性。DrawingSurface 控件允許使用 Direct3D 來呈現顯示在 XAML 控件後方或與其并列顯示的圖形。

在托管的XAML中,可以發現Direct3DInterop類在XAML引擎和Direct3D之間建立起了一個通信橋梁,作為XAML引擎和Direct3D代碼之間的代理。在Direct3DInterop的實作中,CreateContentProvider方法初始化了一個Direct3DContentProvider類的執行個體,并強制轉化為IDrawingSurfaceContentProvider,這個接口并沒有任何内容,因為它并不是由代碼實作的接口,而是使用WRL(Windows Runtime Library)實作的,将類強制轉化為Windows Phone Runtime Component接口,以便由XAML引擎通路。

更多關于托管的XAML和Direct3D引擎的通信,請檢視MSDN文檔,傳送門:http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207012%28v=vs.105%29.aspx

二.    演練:在Cocos2d-x中調用OpenXLive

1.建立檔案并添加引用

首先在cocos2d-x\samples\Cpp\HelloCpp\Classes檔案目錄下建立一個OpenXLiveHelper目錄,并在該目錄下添加以下三個檔案:ICallback.h、XLiveDelegate.h和XLiveDelegate.cpp,并将他們添加到HelloCppComponent項目中:

WP8:在Cocos2d-x中使用OpenXLive
WP8:在Cocos2d-x中使用OpenXLive

2.定義WinRT接口ICallback

接下來在ICallback.h中定義一個WinRT接口,這個接口将在C#項目中具體實作:

1 // A callback interface for C# code to implement.
2 public interface class ICallback
3 {
4 };      

3.定義C++托管類XLiveDelegate

接下來定義一個C++托管類,所有Direct3D遊戲邏輯通過這個托管類,利用ICallback接口調用具體的C#代碼,這裡采用單例模式管理這個托管類,在XLiveDelegate.h檔案中添加以下代碼:

1 #include "ICallback.h"
 2 
 3 namespace PhoneDirect3DXamlAppComponent
 4 {
 5     namespace OpenXLiveHelper
 6     {
 7         // A native class to pass and store an ICallback instance, calling C# code via the ICallback object.
 8         [Windows::Foundation::Metadata::WebHostHidden]
 9         public ref class XLiveDelegate sealed    
10         {
11         public:
12             // Gets the single XLiveDelegate instance.
13             static XLiveDelegate^ GetInstance();
14             // Set callback into the XLiveDelegate instance.
15             void SetCallback(ICallback^ callback);
16             // Gets or sets the callback.
17             property ICallback^ GlobalCallback;
18 
19         private:
20             XLiveDelegate();
21             static XLiveDelegate^ m_Instance;
22         };
23     }
24 }      

4.實作C++托管類XLiveDelegate

接下來實作XLiveDelegate這個C++托管類,在XLiveDelegate.cpp檔案中添加以下代碼:

1 #include "pch.h"
 2 #include "XLiveDelegate.h"
 3 
 4 namespace PhoneDirect3DXamlAppComponent
 5 {
 6     namespace OpenXLiveHelper
 7     {
 8         XLiveDelegate::XLiveDelegate()
 9         {
10         }
11 
12         XLiveDelegate^ XLiveDelegate::GetInstance()
13         {
14             if (m_Instance == nullptr)
15             {
16                 m_Instance = ref new XLiveDelegate();
17             }
18             return m_Instance;
19         }
20 
21         void XLiveDelegate::SetCallback(ICallback^ callback)
22         {
23             GlobalCallback = callback;
24         }
25 
26         XLiveDelegate^ XLiveDelegate::m_Instance;
27     }
28 }      

5.定義實作ICallback接口的C#類XLiveCallback

在C#項目HelloCpp中,在OpenXLive\OpenXLiveHelper中添加XLiveCallback.cs檔案,并添加以下代碼:

WP8:在Cocos2d-x中使用OpenXLive
1 using PhoneDirect3DXamlAppComponent.OpenXLiveHelper;
2 
3 namespace PhoneDirect3DXamlAppInterop
4 {
5     public sealed class XLiveCallback : ICallback
6     {
7     }
8 }      

6.根據需求補充ICallback的接口方法,并在XLiveCallback中實作

例如需要在Direct3D遊戲邏輯中擷取一個成就,則在ICallback.h中定義一個接口方法:

1 // Award an achievement completed event.
2 event Windows::Foundation::EventHandler<CompletedEventArgs^>^ OnAwardComplted;
3 void Achievement_Award(Platform::String^ achievementKey);      

在XLiveCallback.cs中實作:

1 public void Achievement_Award(string achievementKey)
 2 {
 3     Achievement ac = new Achievement(XLiveGameManager.CurrentSession, achievementKey);
 4     ac.AwardCompleted += ac_AwardCompleted;
 5     ac.Award();
 6 }
 7 
 8 void ac_AwardCompleted(object sender, AsyncEventArgs e)
 9 {
10     if (OnAwardComplted != null)
11     {
12         OnAwardComplted(sender, new CompletedEventArgs(e.Result.ReturnValue, e.Result.ErrorCode, e.Result.ErrorMessage));
13     }
14 }
15           

觀察上述邏輯,可以發現這實作過程其實是一個擴充卡模式的實作:

WP8:在Cocos2d-x中使用OpenXLive

其中的ICallback為目标接口(Target),Achievement為需要适配的類(Adaptee),XLiveCallback則為擴充卡(Adapter),将原有接口轉換為目标接口,而XLiveDelegate則為用戶端(Client),負責管理和調用目标接口,而不必關心具體的适配接口。

至于其餘的OpenXLive接口,拙者認為需要從遊戲邏輯中向外POST并且擷取傳回通知的接口才需要進行封裝,而UI跳轉或其他GET類型的接口隻需要在托管XAML示例中調用即可,附上拙者封裝的一些接口。

 ICallback.h源碼下載下傳