具有预定偏移/旋转的分层精灵

时间:2012-09-26 07:14:18

标签: c# xna sprite xna-4.0

可能不是一个非常具有描述性的标题,但我正在尽我所能。这是我第一次在StackOverflow上发帖,而且我对C#编程相对较新(大约一年前首次使用Unity开始,并在几天前决定升级到XNA)。话虽如此,请善待我。

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

在我的情况下,游戏将有许多基于精灵的角色,他们拥有完全不同的姿势/动画。现在大约有10个,并且可能会在开发后期添加更多。同样会有大量的武器(可能大约20个开始)将被合成到角色上。我觉得很舒服。然而,问题在于每个角色都需要在角色动画的每一帧中在不同的位置绘制武器精灵并进行不同的旋转。

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

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

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

1 个答案:

答案 0 :(得分:2)

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

建议#0:每当出现任何类型的合成问题时,人们都会从木工中走出来,推荐“渲染目标”作为某种合成灵丹妙药。他们通常是错的。如果可以,请避免使用渲染目标。如果你对最终的合成图像(混合,模糊等)进行效果,你只需要它们。否则,只需将精灵直接画在彼此的顶部,然后再连接到后缓冲器。

建议#1:如果可能,您希望将精灵 所有 打包到单个精灵表中。如果超出纹理大小限制,则必须巧妙地了解如何在片材上划分精灵。原因是性能 - 您希望限制纹理交换的数量 - see this answer for details

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

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

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

存储元数据的方式几乎无关紧要。

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

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

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

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

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

您可以使用XNA内容管道处理器在构建时从映像中提取数据。 然而这实现起来非常昂贵(特别是如果你之前没有这样做 - 内容管道严重不足)。除非您的艺术要求真的很大,否则几乎肯定不值得进行内容管道扩展所需的额外开发时间。当你完成时,你可以多次手动编码定位数据。

我的建议是将额外数据存储在易于编辑的XML文件中。我建议使用XNA的XML Content Importer。一开始就抓住formatting可能很棘手,你必须记住包含适当的assembly referencing。但是一旦你知道如何使用它,它就是将结构化数据快速输入XNA的最简单方法。