65.9K
CodeProject 正在变化。 阅读更多。
Home

MonoGame 实现可移植

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2013年2月19日

CPOL

7分钟阅读

viewsIcon

8952

MonoGame 实现可移植

当我为了达到惊艳效果而整理 MonoGame 解决方案时,你确实会感觉像是在为多个平台构建游戏,这其中有相当多的来回折腾,需要将项目的各个部分整合在一起,还有我最不喜欢的移植实践之一——复制项目(COPY project)。

是的,在多个项目上重复使用完全相同的代码文件听起来很棒,直到其中一个项目需要一个不同的 using 指令,或者要求你以不同的方式使用相同的参数,甚至天知道,要求某些函数需要额外的参数。

可移植库(Portable libraries)是解决这种实践的救星之一,它通过构建一个可以被多种不同项目类型或平台使用的项目,并采用单一代码库。主要区别在于,这是一个以单一方式使用的代码库,可移植框架不允许你超越这些界限,并让你保持在规范内。如果有什么是特定于平台的,那就把它保留在那个平台上,不要让它弄乱你的应用或游戏的核心部分。

MonoGame 的主要问题在于,之前无法做到这一点,但现在可以了……

首先,一个警告!!

请注意,这是我自己的工作,虽然它基于原始的 MonoGame 开发分支,并且(据我所知)仍然与 MonoGame 的核心完全兼容,但在 MonoGame 团队推出此方案或另一个经批准的解决方案之前,您只应将其用作实际项目中的概念验证(Proof of concept)。

这不是我理想中的可移植解决方案,因为 MonoGame 目前并非为可移植性而编写,其核心重点是保持一个熟悉且灵活的代码库,该代码库基于老化的 XNA 框架,以便能够在多个平台上重用您的项目(请注意,我说的是重用,因为仍然需要付出努力)。

MonoGame 是一项了不起的成就,如果你和我一样对这类事物充满热情(并且会编码,这会有帮助),那么就参与进来,看看你能为这个平台带来什么好处吧!

为何要追求可移植性?

俗话说,没坏就别修。

嗯,目前 MonoGame 的代码库(以及你使用 MonoGame 构建的任何解决方案)对于几乎所有平台来说都非常单一,它们紧密地交织在一起,组件被替换、更改或仅仅是扩展,以试图提供灵活性来适应不断变化的需求目录。

这种做法本身并没有什么特别错的,但是随着时间的推移,你的代码会变得非常复杂,试图修复一个平台上的问题可能会在不知不觉中严重影响另一个平台(除非你在每次提交后在所有平台上测试所有构建),基本上,在一个锅里放太多口味的派,很快就很难区分哪个是哪个了。

可移植库通过将项目的“核心”放在一个地方,以一种方式工作,并将平台扩展保留在各自的平台上,从而帮助解决这个问题。如果你足够明智,核心部分甚至永远不会知道这些事情的发生。

当然,你可能会用多个较小的项目创建出同样的东西,然后不断地进行替换,但问题是,如果你添加了某个平台不喜欢的东西,直到在该平台上测试之前你都不会知道。可移植库可以防止这种情况,因为它们只允许在所有配置的平台上都能工作的函数,从而保护你免受自己的影响。

想了解更多吗?可以试试这些资源:

不过要注意,一个可移植库能让你开发一个非常简单和集中的共享项目,但如果没有至少一个平台来运行它,你实际上是无法运行你的项目的。可移植特性只是让在其他平台上启用项目变得轻而易举。

我们使用可移植类库的目标是实现类似这样的效果:

image

言归正传

那么这到底有什么不同呢?让我们阐明它对 MonoGame 项目带来的两个主要区别。

1. 项目构成

第一个主要影响是你如何布局或管理你的多项目解决方案(上面的 MVVM cross 演示文稿对此有更好的解释,但这里还是简单说一下)。

项目组合

按照目前的做法,你很可能会有类似这样的东西:

image

取决于你是链接项目的核心文件还是直接复制它们,每个平台你都会有多个解决方案,并且在考虑每个平台时需要管理/集成更多的代码。在最坏的情况下(只是复制项目),对核心代码的一个 bug 修复必须在所有平台上重复进行,如果这个链条中存在平台特定的差异,事情就会变得越来越困难。

可移植库以其中心化的特性在一定程度上缓解了这个问题。

可移植组合

image

可移植库允许一个项目与许多其他项目相关联,只要你在可移植库中加载了项目目标(有关更多信息,请阅读关于可移植库的资料!)。

2. 唯一的真相来源

可移植库解决了多平台解决方案中最大的难题之一,因为一个简单的事实:它们都是不同的。每个平台都有自己的一套做事方式,通常与其他平台不兼容。

现在我必须坦白,单靠可移植库并不能解决所有问题,但它们能做的是让工作变得容易得多,并准确地显示出在你所有支持的平台之间哪些是兼容的,更重要的是,哪些是不兼容的。如果你试图引入与所有平台都不兼容的东西或引用一个不兼容的库,你只会得到编译错误。

这确保你将特定于平台的代码放在平台内部,而将核心的东西放在一个地方。

image

如果你阅读有关可移植类库的资料,会发现一个“购买者须知”的警告:你添加的平台越多,真正可移植的范围通常会越小,所以要小心。

就像我说的,它不会解决你所有的问题,所以多看一些上面的视频,阅读关于抽象的资料,并为可扩展的解决方案打好基础。尽可能地集中化,但要保持简单!

纯粹而简单的闪电

所以在清理了所有东西,并现在使用可移植库来处理之前演示的核心代码后,我剩下的是以下这些:

image

目前,我保留了原始的绘图代码,因为我最初的可移植实验只是为了启用基本功能,但我似乎在相当短的时间内成功地在一个可移植库中启用了框架的大部分功能。因此,在这一点上,我几乎可以将所有演示代码移到可移植库中,这样我只需要在每个平台项目中保留一个垫片(shim)来运行它(外加我想要利用的任何附加平台功能,比如分享/NFC/等等)。

该系列文章的源代码可以在 CodePlex 上的这里找到,以及这个阶段的代码

打破常规

好了,我现在要暂时告别 MonoGame 一小会儿,回到 SunBurn。你可能会问为什么,对此,显而易见的答案应该是:

“那边有非常有趣的东西值得一看。”

稍后我会回来报告,并向你展示 SunBurn 有多“带电”(天哪,这听起来像是《超能少年》里糟糕的一集 困惑的微笑)。

附言:花了一周时间将 MonoGame 可移植化后,我累坏了,哈哈。

© . All rights reserved.