反序列化从 BMFont 工具导出的 XML 时出错

Error deserializing XML exported from BMFont tool

我正在尝试使用以下示例:http://www.faqwhosebug.com/answered/using-a-bmp-image-as-font-in-monogame

这个概念似乎很合理。我正在使用由建议的工具生成的 .fnt。根据 classes 中使用的 [Serialization],它看起来格式正确并且有意义。

但是,每次我 运行 代码都会收到此错误:“System.Xml.dll

中发生了 'System.InvalidOperationException' 类型的未处理异常

附加信息:XML 文档 (1, 1) 中存在错误。"

我狂热地查看了 StackExchange 和 google,并在来这里发布我的问题之前尝试了很多东西。我在下面的 FontLoader class 内发表的评论中仍有许多这些尝试的混乱遗留问题,我正在修改以尝试解决该问题。无论如何切片,它都会给出相同的错误,甚至更糟。

    public class FontLoader
{
    public static FontFile Load(String filename)
    {
           /* XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
            TextReader textReader = new StreamReader(Encoding.UTF8.GetBytes(filename).ToString());
            FontFile file = (FontFile)deserializer.Deserialize(textReader);
            textReader.Close();
            return file;*/


byte[] bytes = Encoding.UTF8.GetBytes(System.IO.File.ReadAllText(filename));
FontFile myInstance = null;
using (MemoryStream memStream = new MemoryStream(bytes))
{
XmlSerializer tokenSerializer = new XmlSerializer(typeof(FontFile));
myInstance = (FontFile)tokenSerializer.Deserialize(memStream);
Console.WriteLine(myInstance);
return myInstance;
}

/*
        XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
        TextReader textReader = new StreamReader(filename);
        FontFile file = (FontFile)deserializer.Deserialize(textReader);
        textReader.Close();
        return file;*/

/*         var xml = System.IO.File.ReadAllText(filename);
        using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(FontFile));
            FontFile file = (FontFile)serializer.Deserialize(stream);
            return file;
        }*/

     /*   var writer = new StringWriter();
        var serializer = new XmlSerializer((filename.GetType()));
        serializer.Serialize(writer, filename);
        string xml = writer.ToString();
        return xml;*/

    }
}

我使用的字体是Arial,作为测试,应该可以使用。它以这些行开头:

info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32   x=155   y=75    width=3     height=1     xoffset=-1    yoffset=31    xadvance=8     page=0  chnl=15

然后是具有相同结构的许多 "char" 行的 contineus,其次是字距调整行,然后是 "kerning" 行的 bunce,如下所示,具有相同的结构:

kernings count=91
kerning first=32  second=65  amount=-2  

如果序列化最终出现问题,我为发布而道歉,但我没有看到它。如果有人有解决方案,请告诉我。谢谢。

自从您提到的那个答案写下来后,有一些事情发生了变化。您可以使用 MonoGame.Extended library to do exactly what you're trying to do. I wrote a detailed blog post 前一段时间的相关内容,而不是自己编写。

您需要做的第一件事是 install the MonoGame.Extended NuGet package。 运行 在程序包管理器控制台中执行以下命令。

Install-Package MonoGame.Extended -Pre

一旦安装完成,您的包文件夹中就会有几个 DLL。其中之一将需要由 MonoGame 管道工具引用。最简单的方法是在文本编辑器中手动编辑 Content.mgcb 文件。像这样添加参考行,但一定要匹配当前版本。

#-------------------------------- References --------------------------------#

/reference:..\..\packages\MonoGame.Extended.0.3.44-alpha\lib\MonoGame.Extended.Content.Pipeline.dll

最后,您可以将字体文件和纹理添加到 MonoGame 管道工具并像加载任何其他内容一样加载。

_bitmapFont = Content.Load<BitmapFont>("my-font");

然后使用精灵批处理绘制它

_spriteBatch.Begin();
_spriteBatch.DrawString(_bitmapFont, "Hello World", new Vector2(100, 200), Color.Red);
_spriteBatch.End();

如果您确实想自己编写它,您可以查看 implementation from MonoGame.Extended,因为它是开源的。

从你原来的问题来看,这个问题其实很明显,但和你一样,我一开始忽略了这个问题。

在您向我发送 .fnt 文件后,我几乎立即发现了这个问题,因为我将它与我之前导出的文件进行了比较。问题是您以错误的格式导出文件。正如您在问题中所说,您的文件如下所示:

info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32   x=155   y=75    width=3     height=1     xoffset=-1    yoffset=31    xadvance=8     page=0  chnl=15

但它应该看起来更像这样:

<?xml version="1.0"?>
<font>
  <info face="Arial" size="32" bold="1" italic="0" charset="" unicode="1" stretchH="100" smooth="1" aa="1" padding="0,0,0,0" spacing="1,1" outline="1"/>
  <common lineHeight="32" base="26" scaleW="256" scaleH="256" pages="1" packed="0" alphaChnl="1" redChnl="0" greenChnl="0" blueChnl="0"/>
  <pages>
    <page id="0" file="arial_0.png" />
  </pages>
  <chars count="191">

将它们并排比较后,差异就很明显了。第一个文件是纯文本,第二个文件是 XML。它发生在我们最好的人身上:)

无论如何,要修复它,您只需在 BMFont 工具中将文件格式设置为 XML。

  1. 单击选项
  2. 单击导出选项
  3. 单击对话框底部附近的 XML 单选按钮

然后再次导出文件。