【问题标题】:How to draw every characters with spritefont in monogame如何在monogame中用spritefont绘制每个字符
【发布时间】:2020-05-16 02:57:48
【问题描述】:

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

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

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

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

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

.../Content/MyFont.spritefont : 错误 : Importer 'FontDescriptionImporter' 出现意外失败!

System.Reflection.TargetInvocationException:调用的目标已抛出异常。 ---> System.ArgumentException: CharacterRegion.End 必须大于 CharacterRegion.Start

在 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>

我搜索了几天的解决方案,但徒劳无功,感谢任何帮助。

【问题讨论】:

  • 这没有意义,因为CharacterRegion.End.Start 都是char 类型,而(char)0xFFEE 大于(char)0x0021。你确定问题不简单,比如看错文件之类的吗?如果将 End 更改为 &lt;End&gt;&amp;#x0022;&lt;/End&gt; 会发生什么?
  • 是的,它可以编译。我在想可能&lt;End&gt;&amp;#xFFEE;&lt;/End&gt;太大了,因为网上的文章说内容管道会将字符区域中的所有字符解析为图像文件。
  • @Groo 但是错误信息让我很困惑,我不知道该怎么办。
  • 我尝试使用这个 spritefont 文件,它没有抛出错误,但 msbuild 仍在构建内容。我认为生成的纹理太大而无法正常工作。你看到这篇文章了吗:Common Kanji char. ranges for XNA?您还可以查看 XNA 4 Localization sample project,它实现了一个自定义导入器,它只添加在 .resx 文件中找到的字符范围。
  • @Groo 非常感谢。我找到了这个link,它成功了。

标签: c# fonts xna monogame spritefont


【解决方案1】:

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

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

我的步骤是:

  1. 在管道工具中将 .spritefont 处理器设置为 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

【讨论】:

  • 我已经有一段时间没有使用 MonoGame 了。很高兴知道这个功能终于原生包含在 MonoGame 库中!如果我以后要使用 MonoGame 的自定义字体,我会尝试你的步骤。谢谢!
【解决方案2】:

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

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

我花了很多时间寻找这个解决方案。所以我会发布我是如何成功的,希望它可以帮助将来有同样问题的人。

分步教程

  1. 创建类库。

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

  3. 下载LocalizationSamplehere并解压文件。

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

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

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

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

  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. Creating custom content importers for the MonoGame Pipeline 第 1 部分

  2. How to: Create a Localized Game

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    相关资源
    最近更新 更多