设为首页 收藏本站
查看: 1570|回复: 0

马宁的Windows Phone 7开发教程(4)——XNA显示中文字体

[复制链接]

尚未签到

发表于 2015-5-8 11:55:18 | 显示全部楼层 |阅读模式
  我最近勤快地连自己都有些不可思议。昨天有朋友在上一篇文章里留言,批评Windows Phone 7暂时没有支持中文版的问题。凡事都有个过程,在中文版出来前,咱们想自己想点办法吧。Silverlight for Windows Phone那边就不管了,肯定会有人想出办法来的。如何让Windows Phone 7游戏显示中文?把说“贴图”的那个人拖出去打死!因为XNA 4.0中支持中文的办法倒是现成的,这与XNA字体支持的方式有很大关系。
  示例代码下载地址:
  http://files.iyunv.com/aawolf/XNA_aawolf_SIP_Chinese.rar
  绘制字体
  我们先来看一下XNA中如何绘制字体,MSDN上的描述很好:
  http://msdn.microsoft.com/en-us/library/bb447673.aspx
  关于字体授权的问题咱们就不纠结了,提醒一句,使用某种字体前首先确认是否能够使用、再分发。绘制字体的第一步是,创建Sprite Font字体。XNA中使用的字体文件叫做Sprite Font,文件扩展名为.spritefont,XNA支持从.ttf将字体转换为.spritefont。
  首先,我们在VS 2010的Solution Explorer中找到WindowsPhoneGame1Content项目,右键菜单点击“Add”-“New Folder”,将新文件夹命名为Font,然后在Font上右键点击,选择“Add”-“New Item”,然后在对话框中选择创建“Sprite Font”,将字体文件命名为StartFont。
DSC0000.png
  在Solution Explorer中双击StartFont.spritefont文件,我们会打开一个XML文件,我们省去XML注释部分:



Kootenay
30
0
true
Regular


 
~




  按照XML的注释,我们可以很容易的了解每一项的功能,只看高亮部分:FontName,字体的名称;Size,字体的大小;Style,指定字体是否为粗体、斜体等;CharacterRegion,字体区间,目前的设置为只显示ASCII字体。这一点也是非常适合游戏开发的,游戏没有必要提供完整的字符集支持。
  接下来就是绘制代码了,首先在类中增加SpriteFont的变量:

    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”之后,会显示下面的界面:
DSC0001.jpg
  大家注意到,我将第二个绘制“中国”的DrawString注释掉了,如果不注释掉会怎么样呢?产生一个Exception,因为我们Sprite Font的CharacterRegion只包含了ASCII字符,所以,中文字体显然超过了字符范围。
DSC0002.png

添加中文支持
  MSDN上的另一篇文章描述了这个问题:
  http://msdn.microsoft.com/en-us/library/bb447751.aspx
  我们可以Font Description Processor来添加对于指定字符的支持,而不需要扩大CharacterRegions,让很多无用的字符也被增加到字体文件中来。
  首先,我们在Solution Explorer中找到游戏的Project,在本例中,就是WindowsPhoneGame1,右键菜单“Add”-“New Item”,选择“Text File”,命名为messages.txt。双击打开messages.txt,在里边添加游戏中要支持的所有中文字符。因为要使用File.ReadAllText,所以确保文本文件是以’\r’或’\n’结尾。
  接下来要创建一个新的Content Processor Project,在Solution Explorer中选择Solution,右键点击”Add”-“New Project”,选择”Content Pipeline Extension Library(4.0)”,命名为FontProcessor。下面是ContentProcessor1.cs中修改后的所有代码:

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”。
DSC0003.png
  最后,在游戏中增加雅黑字体,将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);
}
  最后的效果就是:(向毛主席保证,这不是贴图!)
DSC0004.jpg

相关资源
  马宁的Windows Phone 7开发教程(1)——Windows Phone开发工具初体验
  马宁的Windows Phone 7开发教程(2)——Windows Phone XNA 4.0 3D游戏开发
  马宁的Windows Phone 7开发教程(3)——XNA下使用MessageBox和软键盘

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-64964-1-1.html 上篇帖子: Windows Phone 7 问答 下篇帖子: 马宁的Windows Phone 7开发教程(3)——XNA下使用MessageBox和软键盘
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表