public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont StartFont;
SpriteFont YaheiFont;
static string Text = "";
我们还增加了一个Text,可以用这个变量从SIP软键盘中获取用户输入的字符串。然后是LoadContent函数:
///
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
StartFont = Content.Load(@"Font\StartFont");
YaheiFont = Content.Load(@"Font\Yahei");
}
请大家注意字体文件的路径:将Content资源放到另外一个DLL里可以方便游戏替换资源,而路径方面,只需要将Folder指定对就可以了。这里顺便把中文微软雅黑字体也加了上了。因为要获取SIP的输入,所以还要修改 Update方法:
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
if (Text == "" && !Guide.IsVisible)
Guide.BeginShowKeyboardInput(PlayerIndex.One,
"Here's your Keyboard", "Type something...",
"",
new AsyncCallback(GetTypedChars),
null);
base.Update(gameTime);
}
private static void GetTypedChars(IAsyncResult asynchronousResult)
{
Text = Guide.EndShowKeyboardInput(asynchronousResult);
Debug.WriteLine(Text);
}
我们修改了update方法,只有Text为空时,SIP才会弹出,SIP部分的代码上次已经说过了。最后一部分就是绘制Draw函数了:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.DrawString(StartFont, Text, new Vector2(10, 10), Color.Black);
//spriteBatch.DrawString(StartFont, "中国", new Vector2(10, 50), Color.Black);
spriteBatch.End();
base.Draw(gameTime);
}
运行程序,会首先实现一个输入法对话框,输入”Hello,xna”之后,会显示下面的界面:
大家注意到,我将第二个绘制“中国”的DrawString注释掉了,如果不注释掉会怎么样呢?产生一个Exception,因为我们Sprite Font的CharacterRegion只包含了ASCII字符,所以,中文字体显然超过了字符范围。
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using System.IO;
using System.ComponentModel;
namespace FontProcessor
{
///
/// This class will be instantiated by the XNA Framework Content Pipeline
/// to apply custom processing to content data, converting an object of
/// type TInput to TOutput. The input and output types may be the same if
/// the processor wishes to alter data without changing its type.
///
/// This should be part of a Content Pipeline Extension Library project.
///
/// TODO: change the ContentProcessor attribute to specify the correct
/// display name for this processor.
///
[ContentProcessor(DisplayName = "FontProcessor.ContentProcessor1")]
public class ContentProcessor1 : FontDescriptionProcessor
{
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
{
string fullPath = Path.GetFullPath(MessageFile);
context.AddDependency(fullPath);
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
foreach (char c in letters)
{
input.Characters.Add(c);
}
return base.Process(input, context);
}
[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 = @"..\WindowsPhoneGame1\messages.txt";
}
}
首先,增加两个引用,用于读取文件:
using System.IO;
using System.ComponentModel;
然后增加MessageFile的属性:
[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 = @"..\WindowsPhoneGame1\messages.txt";
请注意其中的文件路径,因为文件包含在WindowsPhoneGame1的目录中,而本工程位于FontProcessor目录中,所以我们要修改其路径,否则会出现文件无法找到的编译错误。因为FontProcessor是在编译时使用的,所以Excepiton都是以编译错误展现出来的。
我们还需要将ContentProcessor1的基类ContentProcessor替换为FontDescriptionProcessor。为messages.txt注册Content Pipeline,增加依赖关系,告诉Content Pipeline,如果messages.txt变化,则字体需要重新编译。最后是读取这个文件,为其中的每一个字符增加字体的支持。另外,确保你的messages.txt文件,采用了UTF-8的编码方式。
完成这些之后,我们要首先编译一下FontProcessor,然后在Solution Explorer中,右键点击WindowsPhoneGame1Content的References目录,选择“Add references”,在Project Tab页中,选择FontProcessor。接下来,在Solution Explorer中,右键点击Project Dependencies,将FontProcessor前的CheckBox选中。
然后,创建一个新的Sprite Font字体,叫做YaheiFont,字体名称为“Microsoft Yahei”,选中yahei.spritefont,在属性页中的Content Processor项中,将“Sprite Font Description - XNA Framework”切换为“FontProcessor.ContentProcessor1”。
最后,在游戏中增加雅黑字体,将Game中的绘制函数改为:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.DrawString(StartFont, Text, new Vector2(10, 10), Color.Black);
spriteBatch.DrawString(YaheiFont, "中国", new Vector2(10, 50), Color.Black);
spriteBatch.End();
base.Draw(gameTime);
}
最后的效果就是:(向毛主席保证,这不是贴图!)