最近做游戏涉及到了使用xml和显示中文,而这两点都涉及到了“内容管道扩展”。关于“内容管道扩展”留在以后说,而我们仅仅只需要有一个简单的概念——我们通过它来处理我们自定义格式的数据的加载,而之前常常用到的Content.load<Texture2D>("XXX") 其实就是说用处理Texture的内容管道来加载名字为XXX的文件数据。
进入正题:
wp7 xna 默认是只有英文的,但是实际上,我们只需告诉它——“我们要用的中文字符有XXXXXXXX”,然后自己重写一个内容加载的处理方法,即可像使用默认的英文一样的方式来使用中文了。
下面是手把手的步骤介绍:
1.创建windows phone Game 项目。
2.添加内容管道扩展库。
右击解决方案->添加->新建项目
选择“内容管道扩展库”(ContentPipelineExtension),这里为了简单,就使用默认的名称了——ContentPipelineExtension1.
完成这个步骤之后可以见到解决方案中多了一个项目:
这个项目中有一个叫做ContentProcessor1.cs的类,它就是我们要重写的处理内容的类。
3.告诉我们的Content我们要用的中文字符有哪些。
新建一个文本文件“text.txt”,输入“使用中文真简单”
,然后文件->另存为,特别注意的是要保存为“Unicode”。如下图:
然后我们将其添加到解决方案的“XXXContent”项目中,并且在text.txt的属性栏中的“生成操作”改为“无”
4.教会ContentProcessor1如何来加载中文汉字:
打开ContentProcessor1.cs文件,会见到自动生成的
public class ContentProcessor1 : ContentProcessor<TInput, TOutput>
我们现将ContentProcessor<TInput, TOutput>改为:FontDescriptionProcessor
然后将自动生成的方法
public override TOutput Process(TInput input, ContentProcessorContext context)
删除掉,并且 override Process:(要让VS自动生成哦,自己手写就有些麻烦了~)
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
再然后就是实现处理的内容:
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
{
string path = Path.GetFullPath(@"../MyGameContent/text.txt");//获得txt文件的完整路径 MyGameContent是XXContent项目
context.AddDependency(path);
string content = File.ReadAllText(path, System.Text.Encoding.UTF8); //用UFT-8来读取文本内容,所以前面txt一定要保存为unicode
foreach (char c in content)
{
input.Characters.Add(c);
}
return base.Process(input, context);
}
此时此刻,其实大部分的任务已经完成了,我们将进入到最需要注意的下一步:
5.项目和项目的关系梳理:
在这个解决方案中有三个项目:
MyGame(主游戏项目)
MyGameContent(内容项目)
ContentPipelineExtension1(内容管道扩展项目)
其中一开始在建立真个解决方案的时候,VS自己将MyGameContent注册给了MyGame,也就是说MyGame是认识Content的,但是因为ContentPipelineExtension1是我们后来加上的,所以他与前两者并不认识。我们要做两件事来让他们相认:
我们先右击MyGameContent项目,选中项目依赖项:
然后将ContentPipelineExtension1注册给MyGame即可:
这样子,主项目就认识内容管道扩展项目了,
然后我们得让Content项目认识内容管道扩展项目:其实就是在Content项目中添加引用:
ok,连Content都已经认识内容管道扩展项目了。
特别注意:在完成了这个步骤后一定要先“重新生成解决方案”一下(此时才是按我们的“项目依赖项”的顺序生成程序的)
6.再做一次特别提醒——在完成了上面的步骤后一定要“重新生成解决方案”一下。
7.最后一步,设置字体的内容处理器为我们自己的。
先正常的在Content项目中添加->新建项->Sprite字体
然后修改spriteFont的内容处理器条目:
(题外话:
细心的孩子早就发现了其实这个名字就是在代码中自动生成的这句话:
[ContentProcessor(DisplayName = "ContentPipelineExtension1.ContentProcessor1")]
public class ContentProcessor1 : FontDescriptionProcessor
)
。
然后我们打开SpriteFont1.spritefont文件,
将其中的
<FontName>Segoe UI Mono</FontName> 修改为 <FontName>微软雅黑</FontName>
<CharacterRegion>
<Start> </Start>
<End>~</End>
</CharacterRegion>
修改为
<CharacterRegion>
<Start> </Start> <!--这里是一个空格-->
<End>~</End>
</CharacterRegion>
7.然后你可以欢呼雀跃了(我已经在欢呼雀跃了!)
接下来和使用英文spritefont的一样:
public class Game1 : Microsoft.Xna.Framework.Game
{
SpriteFont font;
protected override void LoadContent()
{
font = Content.Load<SpriteFont>(@"SpriteFont1");
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.DrawString(font, "使用中文", Vector2.Zero, Color.Black);
spriteBatch.End();
base.Draw(gameTime);
}
}
不过一定要提醒你不要高兴过头,如果在你运行的时候出现了异常,那就应该是你没有把某个使用的汉字放在text.txt中的缘故了。
该代码和项目已经上传,欢迎下载。
OK到此结束~
最后像以往一样吐槽一句。之前看了几篇博客,有种想暴打一顿该博客(不是博主)的冲动。因为他们无一例外地忽略掉了"5.项目和项目的关系梳理"和"重新生成解决方案"
的描述,最后他们happy成功显示了汉字,我却...
平时不太有写博客的习惯,但是为了不再让大家重蹈覆辙,所以写下了这篇博客。
如果读者发现照做有误的话,也有一种”想暴打博客“的冲动的话,欢迎留言,我会及时修改错误!