2

嘿,我已经四处寻找了一段时间,但我仍然找不到这个问题的直接答案。我有一个 XNA 游戏,其中部分 UI 显示一个图标,该图标会经常更改(多久不相关)。我决定使用一个简单的 spritesheet 制作器来输出 spritesheet 以及一个简单的 XML 文件,其中包含每个单独图标的位置。

我想要做的是从 XML 文件中读取适当图标的精灵表位置和图标大小到Rectangle. 然后我可以将其用作绘图位的源矩形。

但是,我还没有遇到一个简单的解释,说明如何在不编写自己的内容管道的情况下将 XML 文件加载到 XNA 4.0 项目中(如果可能的话,我想避免这样做),并且一旦加载,如何(通常)有效地提取Rectangle变量中的数据。

XML 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with TexturePacker http://texturepacker.com-->
<!-- $TexturePacker:SmartUpdate:748fc56befb00c22540f953093f731a7$ -->
<!--Format:
n  => name of the sprite
x  => sprite x pos in texture
y  => sprite y pos in texture
w  => sprite width (may be trimmed)
h  => sprite height (may be trimmed)
oX => sprite's x-corner offset (only available if trimmed)
oY => sprite's y-corner offset (only available if trimmed)
oW => sprite's original width (only available if trimmed)
oH => sprite's original height (only available if trimmed)
r => 'y' only set if sprite is rotated
-->
<TextureAtlas imagePath="Loadout_Icons.png" width="185" height="86">
    <sprite n="Charge_Down.png" x="0" y="0" w="37" h="43"/>
    <sprite n="Charge_Up.png" x="37" y="0" w="37" h="43"/>
    <sprite n="Damage_Down.png" x="74" y="0" w="37" h="43"/>
    <sprite n="Damage_Up.png" x="111" y="0" w="37" h="43"/>
    <sprite n="FireRate_Down.png" x="148" y="0" w="37" h="43"/>
    <sprite n="FireRate_Up.png" x="0" y="43" w="37" h="43"/>
    <sprite n="Health_Down.png" x="37" y="43" w="37" h="43"/>
    <sprite n="Health_Up.png" x="74" y="43" w="37" h="43"/>
    <sprite n="Speed_Down.png" x="111" y="43" w="37" h="43"/>
    <sprite n="Speed_Up.png" x="148" y="43" w="37" h="43"/>
</TextureAtlas>

我也不确定我是否会因为不制作自己的 XML 文件而自取其辱,那会更容易吗?

我已经阅读了 msdn 提供的大部分内容,但无济于事,但任何指向相关页面或问题的链接将不胜感激。提前致谢。

4

3 回答 3

0

以下应该可以工作,但是,它完全未经测试:

[XmlRoot("TextureAtlas", IsNullable = false)]
public class TextureAtlasXml
{
    public static TextureAtlasXml FromFile(String file)
    {
        using (var stream = File.OpenRead(file))
        {
            return FromStream(stream);
        }
    }

    public static TextureAtlasXml FromStream(Stream stream)
    {
        var serializer = new XmlSerializer(typeof(TextureAtlasXml));
        return (TextureAtlasXml)serializer.Deserialize(stream);
    }


    [XmlAttribute("imagePath")]
    public String ImagePath;

    [XmlAttribute("width")]
    public Int32 Width;

    [XmlAttribute("height")]
    public Int32 Height;

    [XmlElement("sprite")]
    public List<SpriteXml> Sprites;
}

public class SpriteXml
{
    [XmlAttribute("n")]
    public String Name;

    [XmlAttribute("x")]
    public Int32 X;

    [XmlAttribute("y")]
    public Int32 Y;

    [XmlAttribute("w")]
    public Int32 Width;

    [XmlAttribute("h")]
    public Int32 Height;

    public Rectangle Rectangle { get { return new Rectangle(this.X, this.Y, this.Width, this.Height); } }
}

我建议您考虑使用内容管道,因为它提供了一个很好的解决方案,但是,代码应该像您想要的那样工作。

于 2012-11-12T10:29:06.000 回答
0

如果您愿意使用 Sprite Vortex(实际上是特定版本),您可以使用以下类。您必须使用 Sprite Vortex 1.2.2,因为在较新的版本中 XML 格式发生了变化。确保您添加属性的 XML 文件更改为“不编译”。

如果您需要一个工作示例,我可以给您发送一个非常简单的示例。

ps Sprite Vortex 应该做与使用其他程序相同的事情,但是 v 1.2.2 有很多错误,但还不错。

课程在这里: http: //pastebin.com/sNSa7xgQ

于 2012-11-17T05:26:39.570 回答
0

由于仅在评论中提到,我决定说我最终使用 Niko Drašković 的建议,该建议是专门为纹理打包器制作的专用管道扩展,可在http://thirdpartyninjas.com/blog/2012/08/找到02/texturepacker-xna-content-pipeline-extension/。这使得使用纹理打包器生成的 XML 文件变得非常容易。

然而,作为一个旁注和我重新审视这个问题的另一个原因是说我最近一直在使用 XML 做一些工作(试图更好地理解它们)以及我发现的最佳方法处理读取自定义 XML 文件而不为每个文件编写新的管道扩展(就像现在看起来那样优雅)如下。我将 XML 文件添加到内容目录,就像您添加任何其他纹理等一样。在 XML 的属性中,我将构建操作设置为“内容”,然后将复制到输出目录设置为“始终复制”。从这里我有一个单独的类,我在其中传递文件的名称,并在其中处理我需要的来自 XML 的所有内容。这些课程以:

Stream stream = TitleContainer.OpenStream("Content\\" + fileName + ".xml");
XDocument doc = XDocument.Load(stream);

and then go on (using the rest of the System.Xml.Linq library) to read and store the appropriate data, with methods to access data easily. This may not be the best approach to tackling the problem but it has since worked for me and is simple enough to understand and implement quickly. Hope this can help anyone else with a similar issue.

于 2012-12-07T01:01:11.123 回答