如何在monogame中用spritefont画出每一个角色

How to draw every characters with spritefont in monogame

我是 monogame 的新手,我正在尝试制作一个 .spritefont 文件,以便使用我选择的字体绘制字符串。

英文字符的字符串在屏幕上可以很好地显示,但我想绘制多国语言的字符串,例如日文和中文。

所以,我尝试加载多语言字体“Microsoft JhengHei”中的所有字符。

字体的第一个字符是!(U+0021),最后一个字符是○(U+FFEE)

但是当我尝试编译程序时,编译器给我一个错误:

.../Content/MyFont.spritefont : error : Importer 'FontDescriptionImporter' had unexpected failure!

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: CharacterRegion.End must be greater than CharacterRegion.Start

at Microsoft.Xna.Framework.Content.Pipeline.Graphics.FontDescription.set_CharacterRegions(CharacterRegion[] value)

当我将 ○ 更改为 忮 时,MSBuild 卡住并需要很长时间才能继续内容。

下面MyFont.spritefont中的代码:

<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="Graphics:FontDescription">
    <FontName>Microsoft JhengHei</FontName>
    <Size>14</Size>
    <Spacing>0</Spacing>
    <UseKerning>true</UseKerning>
    <Style>Regular</Style>
    <CharacterRegions>
      <CharacterRegion>
        <Start>&#x0021;</Start>
        <End>&#xFFEE;</End>
      </CharacterRegion>
    </CharacterRegions>
  </Asset>
</XnaContent>

我搜索了几天的解决方案,但没有找到任何帮助。

因为处理所有 65000 个字符需要太多时间。我们应该只处理我们正在使用的字符。

所以最简单的方法是制作一个 MonoGame Custom Content Pipeline 并加载一些 .resx 文件使用的字符。

我花了很多时间寻找这个解决方案。所以我就post我是怎么成功的,希望对以后遇到同样问题的人有所帮助

分步教程

  1. 创建一个 Class 库。

  2. 使用 NuGet 引用 MonoGame.Framework.Content.Pipeline.Portable 包。 (确保您选中了 Include Prerelease 复选框)

  3. 下载 LocalizationSample here 并解压缩文件。

  4. LocalizationPipeline\下复制LocalizedFontDescription.csLocalizedFontProcessor.cs到class库

  5. 构建 class 库,使其输出 LocalizationPipeline.dll 文件。

  6. 打开 Myfont.spritefont 并将其资产类型更改为 LocalizationPipeline.LocalizedFontDescription

  7. 然后添加资源<ResourceFiles><Resx>..\strings.resx</Resx></ResourceFiles>(这些文件应该包含我们要绘制的字符串)

  8. 打开Content.mgcb并参考LocalizationPipeline.dll

  9. MyFont.spritefont 的处理器设置为 LocalizedFontProcessor

  10. 重建项目。

MyFont.spritefont

<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="LocalizationPipeline.LocalizedFontDescription">
    <FontName>Microsoft JhengHei</FontName>
    <Size>14</Size>
    <Spacing>0</Spacing>
    <UseKerning>true</UseKerning>
    <Style>Regular</Style>
    <CharacterRegions>
      <CharacterRegion>
        <Start>&#32;</Start>
        <End>&#126;</End>
      </CharacterRegion>
    </CharacterRegions>
    <ResourceFiles>
      <Resx>..\strings.resx</Resx>
    </ResourceFiles>
  </Asset>
</XnaContent>

Content.mgcb

...
#-------------------------------- References --------------------------------#

/reference:..\LocalizationPipeline.dll

#---------------------------------- Content ---------------------------------#
...
#begin MyFont.spritefont
/importer:FontDescriptionImporter
/processor:LocalizedFontProcessor
/build:MyFont.spritefont
...

来源

  1. 第 1 部分 Creating custom content importers for the MonoGame Pipeline

  2. How to: Create a Localized Game

  3. LocalizationSample(感谢@Groo 给我这个link。)

我无法在 Monogame 3.7.1 中重现 J3soon 接受的答案的步骤。

但是在 Monogame 3.7.1 中,不再需要使用自定义内容管道,因为管道工具现在原生包含 LocalizedFontProcessor。

我的步骤是:

  1. 在管道工具中将 .spritefont Processor 设置为 LocalizedFontProcessor
  2. 在 .spritefont 中,包含 resx 文件的路径。
  3. 在 .spritefont 中,将 Asset Type="Graphics:FontDescription" 替换为 Asset Type="Graphics:LocalizedFontDescription"
  4. 重建内容

我原以为第 1 步会在幕后完成第 3 步,但对我来说,有必要在管道工具和 .spritefont 文件中执行此操作。

精灵字体文件

<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="Graphics:LocalizedFontDescription">
    <FontName>Arial</FontName>
    <Size>16</Size>
    <Spacing>2</Spacing>
    <UseKerning>true</UseKerning>
    <Style>Regular</Style>
    <CharacterRegions>
      <CharacterRegion>
        <Start>&#32;</Start>
        <End>&#126;</End>
      </CharacterRegion>
    </CharacterRegions>
    <ResourceFiles>
      <Resx>..\Strings.fr.resx</Resx>
    </ResourceFiles>
  </Asset>
</XnaContent>

内容文件

#begin MyFont.spritefont
/importer:FontDescriptionImporter
/processor:LocalizedFontProcessor
/processorParam:PremultiplyAlpha=True
/processorParam:TextureFormat=Compressed
/build:MyFont.spritefont