3

可能不是一个描述性很强的标题,但我正在尽力而为。这是我第一次在 StackOverflow 上发帖,而且我对 C# 编程还比较陌生(大约一年前开始使用 Unity,几天前决定升级到 XNA)。话虽如此,请对我好一点。

我正在计划我正在设计的 2D 游戏的机制,虽然在 XNA 中玩过之后大部分看起来都很简单,但我一直在回想一个问题,我还没有想出一个令人满意的答案为了。该问题涉及将精灵分层为复合/复杂精灵。例如,游戏中的角色可能使用任意数量的武器中的一种或两种。我确实对该主题进行了一些研究,发现有些人建议使用 RenderTarget 类将一系列精灵绘制为一个,而有些人建议在 Draw() 期间简单地将精灵绘制在彼此之上。然而,这些主题主要集中在游戏中具有单个角色的相对简单的案例上。

就我而言,游戏将有许多基于精灵的角色,他们具有完全不同的姿势/动画。现在大约有 10 个,以后可能会在开发中添加更多。同样会有大量的武器(可能开始时大约 20 个)将被合成到角色身上。这让我很舒服。然而,问题在于每个角色都需要在角色动画的每一帧期间将武器精灵绘制在不同的位置并使用不同的旋转。

我已经考虑了几种方法来解决这个问题,但它们都有相当大的缺点。
第一个是简单地为每个角色绘制每个武器的 spritesheet,与相应角色的大小相同。这种方法的好处是只需添加调用即可在基本角色之上绘制额外的精灵,而无需进行任何计算。不利的一面是会产生过多的额外精灵表(10 个字符 x 20 个武器需要 200 个额外的表)。

第二个是创建一个类来处理武器精灵。WeaponSprite 类将附加到每个武器的单个纹理上,然后根据附加到的角色存储有关绘制时要使用的偏移/旋转的信息。这样做的问题是,在每帧的基础上组织偏移/旋转将非常乏味,而且我想不出任何简单的方法来根据所需的帧提取信息。(我的想法是制作一个 AnimationFrame 类来跟踪每个角色的动画名称、朝向和帧数,然后使用武器类中的字典根据当前帧的名称加载适当的数据,但这个想法的某些方面似乎真的很糟糕)。这种方法还有一个缺点是需要相对大量的内存来完成(假设 Vector2 是 8 字节,浮点数是 4,考虑到当前使用的帧数,有 10 个字符和 20 个武器将需要 192KB 的内存,随着更多武器的加入,它只会变得更大)。我有这个想法的一个分支(我从关于同一主题的另一篇文章中偷来的)使用保留的 alpha 值像素来链接每个武器的偏移量和“原点”,在运行时计算位置,然后只需将旋转浮点数存储在上述字典中。随着更多武器的加入,它只会变得更大)。我有这个想法的一个分支(我从关于同一主题的另一篇文章中偷来的)使用保留的 alpha 值像素来链接每个武器的偏移量和“原点”,在运行时计算位置,然后只需将旋转浮点数存储在上述字典中。随着更多武器的加入,它只会变得更大)。我有这个想法的一个分支(我从关于同一主题的另一篇文章中偷来的)使用保留的 alpha 值像素来链接每个武器的偏移量和“原点”,在运行时计算位置,然后只需将旋转浮点数存储在上述字典中。

由于我是 XNA 的新手(并且在 C# 上仍然很年轻),我想我会发布并让专家参与进来。我的方法是否走在正确的轨道上,还是我错过了一些非常简单的东西?非常感谢您的帮助,如果您需要任何其他信息,请告诉我。

4

1 回答 1

2

哇,大问题。我不能真正告诉你如何实现这一点。但我可以给你一些有用的建议:

建议#0:每当出现任何类型的合成问题时,人们都会从木制品中脱颖而出,推荐“渲染目标”作为某种合成灵丹妙药。他们通常是错误的。如果可以,请避免使用渲染目标。只有在对最终的合成图像(混合、模糊等)进行效果处理时才需要它们。否则,只需将您的精灵直接绘制到后台缓冲区。

建议 #1:如果可能,您希望将所有精灵打包到单个精灵表中。如果超出纹理大小限制,则必须巧妙地在工作表之间划分精灵。原因是性能 - 您想限制纹理交换的数量 -有关详细信息,请参阅此答案

您也许可以为 XNA 使用现有的 sprite-packer。如果你能找到合适的,我建议你使用它。一个好的将允许您像在调用时处理纹理一样处理打包的精灵SpriteBatch.Draw

建议 #2:不要担心定位数据在运行时占用多少空间。192kb 几乎没有 - 一个小纹理的大小。

这样做的结果和 #1 是尽可能多地存储在您的定位元数据中,并避免重复的纹理。

您如何存储元数据几乎无关紧要。

建议 3:您可以将存储需求和内容创建故事从n × m问题更改为n + m问题(n 个字符和 m 个武器)。只需存储仅具有“起源”的武器,并存储具有“起源”和“手位置和旋转”的角色。简单地渲染,使武器的起源与角色的手对齐(数学很简单)。

然后你可以添加角色而不用担心存在什么武器,添加武器而不用担心存在什么角色。

这是需要多少空间的示例:10 个字符 × 20 个字节 + 20 个武器 × 8 个字节 = 360 个字节。又好又小!(虽然你可能需要更多的附着点——不同类型的武器、帽子等等。编辑:哎呀我没有包括动画帧——但它仍然是相对少量的数据。)

建议#4:正如您在帖子中暗示的那样,最棘手的部分是内容创建。

正如您所暗示的,理想情况下,您希望能够直接在图像编辑器中编辑附件点。这是一个令人信服的想法。仅当您的精灵没有抗锯齿时,特殊的 alpha 值才适用。从理论上讲,您可以使用图层和不同的颜色来做一些事情。最难的部分是弄清楚如何编码旋转。

您可以使用 XNA 内容管道处理器在构建时从图像中提取数据。然而,这实现起来非常昂贵(特别是如果您以前没有这样做过 - 内容管道的文档严重不足)。除非您的艺术需求确实非常巨大,否则几乎可以肯定不值得花费额外的开发时间来扩展内容管道。完成后,您可能已经多次手动编码定位数据。

因此,我的建议是将额外数据存储在易于编辑的 XML 文件中。我推荐使用 XNA 的 XML Content Importer。一开始掌握格式可能会很棘手,您必须记住包含适当的程序集引用。但是一旦您知道如何使用它,这是将结构化数据快速导入 XNA 的最简单方法。

于 2012-09-26T08:30:20.833 回答