原文
6 _: D9 K! H+ X8 {9 jhttp://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx/ |; I# y( L. I3 p3 Z6 |; C
0 v& x* N2 H! G3 l! x% H( F
5 z6 E, k& p' J1 {& Y4 d9 _% c n I
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
A0 M7 W4 O! t7 xXNA3.0+VS2008SP1下调试通过5 I" s* u4 `. R/ o! n) e
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。# E% G4 E1 Y; {4 ~" p G
步骤如下:0 L" k& L1 B' m$ F
建立字体文件9 ?4 B. H% ?" A! i& j% r/ y. ?
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:
B' P2 o8 ~; ?) C# i[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する3 D' h6 N" [/ w
9 T3 k, C/ H. U+ n% ^
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:
$ D8 _( |' N+ k* [# l[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;
1 b' m& Z+ L% E# M' gusing Microsoft.Xna.Framework.Content.Pipeline;( {& F1 T1 I8 u% f; N! _0 {* e
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
( y- v+ `8 `0 t* H; W. Fusing Microsoft.Xna.Framework.Content.Pipeline.Processors; h2 \' |: s& y* s' I
- u& k1 E5 ^/ O
6 _0 x0 u$ I) G- I; `
namespace FontProcessors$ ?0 t! T9 c* w: Z$ A& V; ~
{
\& ~* P6 V: T/ l( U [ContentProcessor]
, w" W% X- ]4 _6 K0 j R: j: z1 S public class DefaultFontProcessor : FontDescriptionProcessor+ i* y- s$ e+ z$ ]4 z% K ~8 l5 B
{
% P+ j% {. B A1 u3 d. K public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)! x7 ^# A# H( Z4 c6 X* w' \7 G
{' }: i4 t1 c" G- X4 Q1 c/ f
//载入文件 Z( o a8 u' } j
string fullPath = Path.GetFullPath("message.txt");+ w8 ^" C- V' E7 ^" S" o+ l
context.AddDependency(fullPath);
9 \* ] p! N) q9 z" L string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
8 d& ~, p5 D& G0 x) i: `7 F3 q3 L. V: c s
6 X" S5 z# U' y# x
//导入字符
2 @. @% \# A, ~1 Y& D! T% W, P1 u foreach (char c in letters)$ D; _4 m6 V `" ~/ v5 j. `2 ?% ~
{' E% y3 A3 m, U# A
input.Characters.Add(c);& C5 @+ s& ], s& J* o0 A! }
}
( s& U! M; z* i; S$ h7 X1 d, } return base.Process(input, context);4 |6 k: O* K8 O7 G2 x
}- t( k/ ]9 A) X6 |' a
}( E8 r3 k) |+ \4 t
}9 Y; z: B( B4 r3 t" n/ C0 W1 k* O
* H* O4 W& @+ i( g$ I9 Y
|
; \! _/ j- V5 n8 u; W
( o# {9 A2 f* J" Y) s- \添加项目引用
3 g5 M: E- }2 S `1 ?5 r6 }8 C1 M$ K[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用6 T! U/ }5 X. G' I. @0 v2 `* z
Game1.cs | using System;" S! i! {' [' w
using System.Collections.Generic;
' q% Y7 q4 g& T( n7 o& `! {. n7 Busing Microsoft.Xna.Framework;# k" b( s. S3 a; k; ?0 f
using Microsoft.Xna.Framework.Audio;4 ^8 Y5 Y+ k m9 V
using Microsoft.Xna.Framework.Content;
+ }8 z3 Z. Z- Gusing Microsoft.Xna.Framework.GamerServices;: W0 z9 e" E# G$ _1 Y" X
using Microsoft.Xna.Framework.Graphics;& B: X$ i1 w" S3 @3 @
using Microsoft.Xna.Framework.Input;( e( u. \% C) l, T, A/ r
using Microsoft.Xna.Framework.Net;; r' W4 @7 Y7 z: D5 i, M# D
using Microsoft.Xna.Framework.Storage;
+ X$ C$ L" m. R/ p3 J ]3 q& q7 j' U4 M4 w; r5 ?/ O
# W+ K- d# B( a6 @namespace HelloWorld {
7 t4 j z- C6 z: M5 o8 M$ E0 @ public class GameMain : Microsoft.Xna.Framework.Game {( v; L% ~5 v9 \' n
private GraphicsDeviceManager graphics; 1 ?' m, y/ r5 D
private SpriteBatch spriteBatch; I2 C5 O. r8 B+ v0 |! V
private SpriteFont font; + l( G0 e3 V7 T+ {5 N
' } ]6 a. F6 d+ Q1 ]( g# ]
. @3 g/ c" \; o9 W" G7 s& w0 b public GameMain() {9 y' ~$ |1 F- e5 j; S- ?
graphics=new GraphicsDeviceManager(this);) g, ~ O! a, {6 _# p
Content.RootDirectory="Content";
- q1 ?- y( {8 ^' ~- }" s }
5 b& V* L9 i/ P: D
9 V" E5 A, y4 W7 _
J6 w) Z6 r. U( t, q protected override void Initialize() {" N3 G) F7 n g$ x0 ]7 i8 c
base.Initialize();
) G3 b2 j! c+ G& }7 m }
- L I7 K+ c- a0 D$ v
" D1 Y) M* ?8 x& ?) \; x: q) F+ ?; S. K6 [, ]5 a. J6 e4 _
protected override void LoadContent() {9 ^9 {! r( F1 Y' d) }
spriteBatch=new SpriteBatch(GraphicsDevice);( R S4 p% Y2 }' }
font=Content.Load<SpriteFont>("DefaultFont");6 {9 J6 ~: G+ x: h4 `/ @5 A# K
}
8 s) m: k+ G' x; G9 [- Y# g
( {, k9 q T. a2 e) y; p. X! N2 ^( R4 f
protected override void UnloadContent() {
& T n' A- {2 `& Q }
9 ?0 g; p; |6 q
- R5 j7 ^7 d: i Y: ~
0 O0 ^( U0 N* r+ t9 d$ v# k protected override void Update(GameTime gameTime) {
* Y# k; A, d% m$ r+ j7 A if (GamePad.GetState(PlayerIndex.One).Buttons.Back==
2 r |- i9 x: h5 b ButtonState.Pressed) {! B `7 [ o3 D2 g5 U
Exit();
7 s* D$ J$ [3 r& K: R H( x }6 c! t1 @. w8 I( V# p
% N3 H7 R; Q0 V: n: D5 `9 Y; e% `: |0 j5 J9 _; P8 `( C9 V' t0 Q/ M
base.Update(gameTime);
3 M- W4 q* Z0 z1 `& |7 h }
2 N) u+ e! h5 u% K0 {9 l
. v5 w* e* I& K# {3 L5 M6 l! H% U; T; C$ j
protected override void Draw(GameTime gameTime) {
6 r7 l1 w2 u( U; @ graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
6 O- c3 Q+ |; v* Z1 t, a
( C' Z' ~, v/ I
, a3 v& u t F O6 ] spriteBatch.Begin();! I Q+ N6 }' _4 C" n* Y
DrawString("中文输入测试,日本語テストを入力する",50,50);
! z6 ?9 ?) B; b0 W9 u spriteBatch.End();3 k, c$ h+ ?2 g! `9 |7 H' T7 @
; B; p5 _7 N8 ^* [. |
4 o! }& `. D, l& G! q. j base.Draw(gameTime);
/ c& F$ v* j$ |( T: Q' u }
2 J. O, `, E- T4 d3 L- l G
- b* ^: x, m9 W7 T8 j, R/ D7 D2 G6 g }1 m# q
private void DrawString(String str,int x,int y) {4 ^8 u0 d- u4 o U2 ?
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);: e# j @, W2 m: I- r
}: a$ W9 ` V& x+ N' d p8 E3 Q6 r6 L
}8 D7 s. K( o# H( M
}# P1 P5 @1 g- A( p! Q8 @& d
: v- E* {7 k' U" J/ o
|
|