如何扩展Font Description Processor支持附加的字符
本教程介绍如何开发一个自定义内容处理器将附加的字符添加到一个FontDescription对象。
在一个font description (.spritefont)文件中,<CharacterRegions>区域用来添加额外的字符,这让你可以使用SpriteFont绘制额外区域的字符。
对于某些语言,这种方法并不理想。例如,对中文和日文来说,这两者都包含几千个字符。将所有字符都添加到<CharacterRegions>中会极大地增加font素材的大小和生成这个素材所用的时间。更好的办法是当需要特定的字符时才添加它们。你可以创建一个自定义内容处理器实现这个功能。
本例中,一个叫做messages.txt文件包含了游戏中所有要用到的文字。自定义处理器会将这个文件中的所有字符添加到一个FontDescription中,然后使用基类中的 FontDescriptionProcessor处理这个对象,这样messages.txt中的所有字符会实时用在SpriteFont对象中。
源代码CPFontProcessor_Sample.rar下载。
使用Font Description处理器
指定需要处理的字符区域和信息
1.在游戏项目中添加一个新的叫做DefaultFont的Sprite Font对象,在Solution Explorer中右击Content节点,点击Add选择New Item。
2.选择Sprite Font模版后点击Add。
3.设置这个文件使用已存在的字体和你喜欢的字符。详细信息可见Sprite Font XML Schema Reference。
4.在项目中添加一个叫做messages.txt的文件。
5.右击Solution Explorer中的游戏项目节点,然后点击Add选择New Item。
6.选择Text File模版,命名为messages.txt,然后点击Add将这个文本文件添加到游戏中。
7.在这个新文本文件中,键入任何你想显示在Sprite Font文件中的信息。
注意:我们使用了File.ReadAllText方法读取这个文件中的文字。这个方法需要一个在最后一个字符串后添加一个回车("\r")或换行("\n") ,所以,别忘了在文本的最后一行之后添加回车和换行的转义符。
创建一个新的内容处理器项目
内容管道是生成过程的一部分,它与游戏代码是分离的。所以你需要创建一个新的项目,创建这个新项目的第一步是定义一个新的处理器。
注意:首先要有一个游戏项目。本例中游戏项目叫做“FontGame。”
1.要在解决方案中添加一个新处理器项目,需要在右击Solution节点,点击Add并选择New Project。
2.在对话框中,选择Content Pipeline Extension Library (3.1)模版,命名为FontProcessor,然后点击OK。
新项目会自动保护对XNA Framework和Content Pipeline的引用。
扩展字体处理器
1.在using statement中添加以下代码:
using System.IO; using System.ComponentModel;
2.移除ContentProcessor1.cs中靠近顶部的代码,替换为处理器和input类型。
3.使用属性,在类声明的顶部添加一个处理器参数。这个参数存储了文本文件的名称。
[DefaultValue("messages.txt")] [DisplayName("Message File")] [Description("The characters in this file will be automatically added to the font.")] public string MessageFile { get { return messageFile; } set { messageFile = value; } } private string messageFile = "..\\messages.txt";
4.将ContentProcessor1的继承基类从ContentProcessor改为FontDescriptionProcessor。
5.重写Process方法:
public override SpriteFontContent Process(FontDescription input,ContentProcessorContext context)
这个方法替换了模板参数和返回类型。
6.将messages.txt 注册为内容管道的依赖项。这个依赖项告知内容管道如果messages.txt发生改变,那么font也必须重建。
string fullPath = Path.GetFullPath(MessageFile); context.AddDependency(fullPath);
7.读取文件内容,然后依次将每个字母添加到input font中。注意Characters集合会自动处理复制过程。用户无需担心每个字母是否只被添加一次。Characters集合只包含每个字符的一个实例,而不管这个字符被Add调用了几次。
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8); foreach (char c in letters) { input.Characters.Add(c); }
本例中,messages.txt是以Unicode UTF-8编码保存的,这也是为什么调用File.ReadAllText 的原因。这个文本文件的默认文件编码是Western European (Windows) encoding,对应code page 1252。如果你的文本文件使用默认编码,可以这样指定:
string letters = File.ReadAllText( fullPath, System.Text.Encoding.GetEncoding( 1252 ) );
8.调用从FontDescriptionProcessor基类继承的Process方法生成包含新字符的font:
return base.Process(input, context);
将自定义字体处理器与sprite font联系起来
1.编译解决方案生成MyFontProcessor。现在你需要添加自定义字体处理器。
2.从Solution Explorer中右击Content节点,然后点击Add Reference。
3.从Projects选项卡中选择你的内容扩展项目(FontProcessor) 节点,然后点击OK。 要保证处理器项目会自动更新,你需要创建一个项目依赖项。
4.在Solution Explorer中右击游戏项目(FontGame)节点然后点击Project Dependencies。
5.选择FontProcessor旁边的选择框然后点击OK添加一个新的依赖项,让FontGame依赖于FontProcessor。
6.将.spritefont文件的内容处理器从Sprite Font Description - XNA Framework改变为新的处理器。
7.选择.spritefont文件,在Properties窗口中,从ContentProcessor的下来菜单中选择自定义处理器。当生成解决方案时,新的处理器就会将messages.txt 文件中的字符添加到SpriteFont的字符集合中。
技巧:要调试内容管道导入器和处理器,可以再处理器中添加如下代码打开调试器。
System.Diagnostics.Debugger.Launch();
译者注:需要将message.txt文件保存为UTF-8格式,而默认是ANSI格式。
发布时间:2009/6/29 上午10:38:43 阅读次数:7411