Cocos2d-x游戏移植到WP8之路 -- c++和c#交互

Cocos2d-x是目前最流行的手机游戏引擎之一,开源、轻量、多平台等的诸多特性使得它被很多国内外手游开发者所喜爱。利用Cocos2d-x来开发Windows Phone 8的游戏同样也是非常的方便高效。当然任何跨平台的游戏引擎,最终解决的都只能是游戏层面的问题:包括场景的管理、图形的渲染、真实物理世界的模拟等;要想真正在一个平台上把游戏做好,不可避免会遇到很多和平台相关的问题,需要我们每个游戏程序员对于该平台的技术有个比较深入的了解。在Windows Phone 8这个平台上,我希望通过自己的努力帮助大家解决移植过程中遇到的问题。


从程序架构角度,首先需要向大家说明的是,目前Cocos2d-x 3.2以下的版本生成的Windows Phone工程,主要是针对Windows Phone SilverLight 8.0的Framework;而最新8.1系统的Windows XAML App Framework则是3.3版本之后才会完美支持。目前程序的结构本质上就是带XAML应用的Direct3D的程序模型。工程在SolutionExplore上的截图如下所示:

Cocos2dx-–WP8工程Direct3D and XAML App 工程

可以看出,二者非常类似,均由二个部分组成。第一个部分是C#编码的基于XAML的项目,比如图中的DemoGame,主要负责Windows Phone常规控件和页面逻辑;另一个部分是C++编码的基于Direct3D的Windows Phone Runtime Component,负责所有的游戏逻辑,比如图中DemoGameComponent。这两者通过DrawingSurface或DrawingSurfaceBackgroundGrid控件来渲染Direct3D图像,以非常小的性能代价获取托管代码的优秀特性。在托管的XAML中,可以发现Direct3DInterop类在XAML引擎和Direct3D之间建立起了一个通信桥梁,作为代码之间的代理。更多关于托管的XAML和Direct3D引擎的通信,请查看MSDN文档。

链接地址:http://msdn.microsoft.com/library/windows/apps/jj207012(v=vs.105).aspx

正是由于这种双模块的结构,给大家移植工作带来一些麻烦。主要表现为,大量的第三方SDK,比如腾讯的微信、OpenXLive等都是XAML层的SDK,需要大家在XAML层添加相应功能;而Cocos2d-x的游戏逻辑一般放在C++的WinRT层,这样这二个模块之间的交互工作就必不可少。最简单的需求场景就是Cocos2dx发一个指令,调用XAML层的第三方SDK的某个功能。如何做到这一点呢?我给大家二个方案。

方案一:扩充Cocos2dEvent

前文提到,Direct3Dinterop类在二个模块之间扮演了交互的角色。所以,我们完全可以使用这个方法来实现自己的需求。具体做法如下:

1.WinRT模块:在cocos2d\cocos\platform\winrt\InputEventTypes.h文件中增加新Event的定义(比如WeChat)

1
2
3
4
5
6
7
public enum class Cocos2dEvent
{
ShowKeyboard,
HideKeyboard,
TerminateApp,
WeChat //addnewevent
};

2.WinRT模块:在cocos2d\cocos\platform\wp8\CCGLView.h & cpp中增加新Event向XAML模块抛出消息的函数(比如OnWeChat)

voidGLView::OnWeChat()
if (m_delegate)
{
m_delegate->Invoke(Cocos2dEvent::WeChat);
}
}

3.WinRT模块:在Cocos2dx的代码中根据需要使用上述函数

1
GLView::sharedOpenGLView()->OnWeChat();

4.XAML模块:在mainpage.xaml.cs文件的OnCocos2dEvent函数中,接受新Event,并增加C#的功能代码

7
8
9
10
OnCocos2dEvent(Cocos2dEventtheEvent)
Dispatcher.BeginInvoke(()=>
switch (theEvent)
{
case Cocos2dEvent.WeChat:
WXAPIFactory.CreateWXAPI(AppID).OpenWXApp();
break ;
…}}}

以上步骤是在Cocos2dx代码中直接打开微信的示例。使用这种方法的优点是借用原来的程序结构,开发比较方便,代码改动比较小;缺点是不够灵活,不支持参数。只能通过增加Event 定义的方法来支持有限的参数。

方案二:使用WinRT 组件中调用 C# 类库的标准解决方案

具体步骤如下所示:

1.WinRT模块:在Cocos2dx的代码的头文件里(比如HelloWorldScene.h),定义WindowsPhone RunTime的接口ICallback(注意下面的namespace)

namespacePhoneDirect3DXamlAppComponent
[Windows::Foundation::Metadata::WebHostHidden]
public interface ICallback
{
};
2.WinRT模块:定义C++托管类XliveDelegate(仍然放在上述的namespace里)

10
11
[Windows::Foundation::Metadata::WebHostHidden]
ref XLiveDelegatesealed
{
:
static XLiveDelegate^GetInstance();
SetCallback(ICallback^callback);
propertyICallback^GlobalCallback;
private :
XLiveDelegate();
XLiveDelegate^m_Instance;
3.WinRT模块:在Cocos2dx的代码的cpp文件里(比如HelloWorldScene.cpp),实现上述托管类,传递ICallback对象保存在托管类中

11
12
13
14
15
16
17
18
19
XLiveDelegate::XLiveDelegate()
}
XLiveDelegate^XLiveDelegate::GetInstance()
{
(m_Instance==nullptr)
{
m_Instance=ref new XLiveDelegate();
}
return m_Instance;
}
XLiveDelegate::SetCallback(ICallback^callback)
{
GlobalCallback=callback;
}
XLiveDelegate^XLiveDelegate::m_Instance=nullptr;
4.XAML模块:在C#文件里(比如mainpage.xaml.cs)定义WinRT接口ICallback的C#实现(XLiveCallback)

6
sealed XLiveCallback:ICallback
}
5.XAML模块:创建XLiveCallback对象传递回上述C++的托管类

XLiveDelegate.GetInstance().SetCallback(XLiveCallback());

6.WinRT模块:扩充ICallback接口(增加了ShowGameCenter函数)

8
virtual ShowGameCenter();
};
7.XAML模块:在XLiveCallback中实现扩充部分(ShowGameCenter的具体实现)

ShowGameCenter()
OpenXLive.Silverlight.XLiveUIManager.ShowGameCenter();
}
}
8.WinRT模块:在Cocos2dx代码中通过接口调用C#实现的功能

XLiveDelegate::GetInstance()->GlobalCallback->ShowGameCenter();

9.XAML模块:使用如下方法,避免产生UI线程和后台工作线程之间的数据交互冲突

Deployment.Current.Dispatcher.BeginInvoke(()=>


以上步骤是在Cocos2d-x代码中直接打开OpenXLive的GameCenter,供大家参考。使用这种方法的优点是采用标准化的解决方案,可以灵活支持各类带参数接口;缺点是需要一定的知识门槛,代码改动相对比较多,调试不太方便。

关于这边博文,我借鉴了如下网站的内容。

链接地址:

http://www.cnblogs.com/zhxilin/archive/2013/03/20/2971331.html

http://wiki.openxlive.net/Applying-OpenXLive-to-Cocos2d-x-Game-for-WP8.ashx

最后,我默认各位读者对于Cocos2d-x已是非常的熟悉。如果大家对于Cocos2d-x引擎本身或如何在WP8上建立Cocos2d-x开发环境不清楚的话,推荐大家去观看我在微软虚拟在线课堂上的免费课程。

链接地址:http://www.microsoftvirtualacademy.com/training-courses/854


感谢微软(中国)有限公司开发体验和合作事业部--开发技术顾问 --梅颖广老师(yimei@microsoft.com)所提供的教程。

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...