原文' L( @1 r0 J9 D- a
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx( t1 `. `7 A. C' f m
" ]: _* e7 ]6 I0 Z" P
E& T/ o) k: N5 U7 l+ X在XNA中显示中文字符或其它UNICODE字符(非GDI+)" n+ b6 n. A3 i/ a; v2 @
XNA3.0+VS2008SP1下调试通过) Q r7 r7 g( T# u: `
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。3 ~- i; P. B( Y% m% Y* m' U; o
步骤如下:/ o" r) | D) V/ j4 C3 H5 i
建立字体文件0 X8 B k+ ?4 o3 M) T% |
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件: b# L% W, Y8 ?6 A2 b
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
0 J' h6 R' w: J4 D: R0 ?& m* s. n: f/ d
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:
/ y% @7 I* o/ M[li]在解决方案浏览器中右键点击解决方案 [/li][li]添加新的项目,在项目类型对话框中选择"Windows Game Library(3.0)",起名"FontProcess" [/li][li]在项目中增加引用,选择“Microsoft.Xna.Content.Pipeline” [/li][li]将这个项目中的默认类"Class1.cs"改名为"DefaultFontProcessor.cs",修改为如下代码: [/li][li]重新编译这个项目 [/li] DefaultFontProcessor.cs | using System.IO;
' Y7 U; h- S C* v2 h! Vusing Microsoft.Xna.Framework.Content.Pipeline;' E; d( X3 n2 g( @
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;/ d6 n$ n% ]8 n+ H2 V% v2 q
using Microsoft.Xna.Framework.Content.Pipeline.Processors;9 }; z! W3 ]: K" J1 |
5 E6 D8 M6 ^' @ }
* n p5 ]: |' r7 tnamespace FontProcessors3 }) S0 A T% U5 D0 d5 e* ~8 ~
{
1 N) f" j4 V/ ]9 D [ContentProcessor]
1 d* }) U7 g3 _% I- R- t% q$ m public class DefaultFontProcessor : FontDescriptionProcessor9 I" X2 r6 F% O: F$ U
{5 E& c2 }5 H5 q, y6 b' g# i; g7 B
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)1 Z; f- i: y u7 z2 D7 X
{5 }& G4 v0 _- ~- [( o- J/ r! k( }& l
//载入文件
/ t% L% q6 T* ^ string fullPath = Path.GetFullPath("message.txt");" ^, X* ~! `8 D) ], }. s7 s9 J/ d7 S
context.AddDependency(fullPath);5 O8 m* F9 v2 Y' z
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);3 Z9 A) m' P; }4 O* q3 ^/ {
9 J- T& q T* b, v8 h c# R( c1 A. B+ U8 s3 r
//导入字符
+ t+ w+ y, p! i: W4 i1 `& ~ k3 { foreach (char c in letters)7 E, U. W" u8 l% j* _6 H- a
{) \) M& M; c8 h8 U
input.Characters.Add(c);
' ~9 X9 u& H. J }
7 d& |; u; x8 f( a; u$ B) Y4 b return base.Process(input, context);
, G5 X4 s2 G( k4 ~, q# z& _ }
9 |! W; W/ F, l2 n! T( c# T& t3 `: k1 w+ a }
( l9 Z' I& @& l" y. R}
; y; G, ^* W+ r& e. ]1 X' R7 J* ^
7 A: s0 p" w/ w' @ |
2 J: ^6 ?# [! J( t' D2 K0 C: r) a/ K
添加项目引用, W4 a" O2 i9 o+ Q2 w0 K+ f, P
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
& U) u4 Q; D+ W/ ~4 @% U+ yGame1.cs | using System;8 b; z( F; _; Z7 C( L2 O5 ~
using System.Collections.Generic;; }' o2 x2 ?, {0 a( N: y
using Microsoft.Xna.Framework;7 W# k) u+ n& c& \- a A
using Microsoft.Xna.Framework.Audio;8 U/ y3 ~0 r6 R$ H2 y
using Microsoft.Xna.Framework.Content;
" v( m4 R0 `# ^/ I; h0 Xusing Microsoft.Xna.Framework.GamerServices;
/ T( w3 |( ~% J1 N1 qusing Microsoft.Xna.Framework.Graphics;
* S5 M, K# d5 e+ t8 ]using Microsoft.Xna.Framework.Input;5 g1 T9 W3 _1 ~8 O T* n
using Microsoft.Xna.Framework.Net;
( ~/ ?& w/ w) e$ G2 pusing Microsoft.Xna.Framework.Storage;
2 D: ]( d. g! ]8 |" y+ B G
) G9 |- _0 w3 s. L/ z1 {3 p* e9 f* Q* _5 V
namespace HelloWorld {
- P6 U& F8 _4 }* Q+ @ public class GameMain : Microsoft.Xna.Framework.Game {
* v8 C7 r, f+ _5 t. u( T5 F private GraphicsDeviceManager graphics; 4 V; l. c+ _( U$ O+ Z; d1 v) K
private SpriteBatch spriteBatch;
- g" |0 n4 b4 Q/ X/ h; w6 r private SpriteFont font; ' v4 z% I- I+ {2 Z" K0 {
1 _# p9 h" t7 s5 {7 k6 Z1 y
0 n5 O9 C$ Y0 X* S
public GameMain() {- V' f) s) L) t4 F9 [
graphics=new GraphicsDeviceManager(this);
5 N7 Z7 y! C5 M# A6 u Content.RootDirectory="Content";
' ^- s2 |1 x: A2 e/ C }* g& J* ?4 P* x& t o
/ D& u; g+ w* n n1 A; @
: } k& _. Y& E5 j
protected override void Initialize() {4 M# h7 q- z E
base.Initialize();
" {: y" |0 P; E }
' h7 W$ @: `2 N( J9 ]8 a) T. o( Z$ d$ ?6 k" M5 t8 r
0 D$ _3 ]+ g. V3 N2 h" h5 {" ]1 E protected override void LoadContent() {- Y8 {2 S" j/ Z4 W
spriteBatch=new SpriteBatch(GraphicsDevice); f1 |4 C3 C2 Z* b% \/ Y. D
font=Content.Load<SpriteFont>("DefaultFont");
/ R) B; S5 o2 _6 N }" T5 X; b- d7 k& k
; y3 O F7 k8 g' D
5 q- [$ K! m' |/ ], X protected override void UnloadContent() {3 b( X. \. I# M
}; Q& ]7 ^* R: a9 s& ?
5 g- H3 q5 Q# x& y8 c) ` H7 i/ c9 n: G; }- a$ N' {4 q+ C
protected override void Update(GameTime gameTime) {
! C" }% z0 N- I! i if (GamePad.GetState(PlayerIndex.One).Buttons.Back==+ X4 e* ?& r5 @, o& M% O! m
ButtonState.Pressed) {( z: q: h4 i* x9 S3 A' e+ l: q
Exit();
4 N3 W$ @; [, s" m }4 Z t3 O' b. h0 w7 ^# L- m
7 v' E9 O; D! \: Q8 E( s
' c1 B% i* ?9 R0 w2 _& y4 w base.Update(gameTime);
) g* c6 B+ u$ C2 I }# O7 K3 f$ [2 S: i/ _) g, X
& U+ d4 G+ ^7 T+ B) Z* [% q% e H/ w; V* G
protected override void Draw(GameTime gameTime) {
: `2 g% L$ E t7 w graphics.GraphicsDevice.Clear(Color.CornflowerBlue);& W7 {& @+ h$ H* A" [
8 S2 ?! D5 A# A* l' g
9 N) {# U( _: Z. W
spriteBatch.Begin();
" ]. D- i6 Y; R8 h DrawString("中文输入测试,日本語テストを入力する",50,50);- X! T- I- b. \
spriteBatch.End();
2 l. p8 [4 t9 K3 D
5 m( c D2 O( e6 o5 U9 `
/ ?1 W# p8 R" {3 L) B& l base.Draw(gameTime);
& p$ C8 U P" ~6 {: b+ Y# ]& C9 l }: S7 \* k8 T! u/ @5 t$ E
; Q9 |% g, A1 ^3 v% R) [: ?% p
" y0 j: e5 G: b2 x5 O' P' X$ F5 } private void DrawString(String str,int x,int y) {
6 P: F% F. E: I" d6 C spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
3 S. e9 ~# T9 h+ Z% \ }
- I" g1 i! }1 x }. s. t4 H( B1 N, W6 o; u6 i! e# r
}
2 x7 D! O+ f H( M% L1 z. u8 ?+ `2 |7 T! Z/ w! Q
|
|