原文
+ g% Y2 L {, h; \http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
5 L5 x0 Y% T+ W3 T7 V; R7 C
0 c$ n% `) H1 [4 w, C
% J4 C# D7 u7 E5 \8 Y0 U6 D在XNA中显示中文字符或其它UNICODE字符(非GDI+)
$ t8 Y# t7 J9 }) r+ t- {7 V% gXNA3.0+VS2008SP1下调试通过
4 o3 T- s! B d- v0 ^, c/ ?- t3 b由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
; R; x# J! [" d- A4 {7 w% O步骤如下:
$ M1 p) Y. I5 S3 K0 l建立字体文件6 U6 \& ]( ^7 m4 j- n: @& u" }
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:& u3 e% R" l( t5 w" I
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
% {: a' [# N0 b. O0 v: C* R
# I: W3 h. l- K) D0 U | [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:1 j, X8 z: M% M% x, O0 A4 f
[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;2 W0 `$ H) o4 k# O. y
using Microsoft.Xna.Framework.Content.Pipeline;. V6 { @! `5 ?
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
) X& K4 f; ?3 T2 b* Husing Microsoft.Xna.Framework.Content.Pipeline.Processors;( i1 \& K; {9 c% L& N
. _ M' g: W$ p7 V2 J% ^
( S6 Z3 _" V2 q' O$ @- p4 dnamespace FontProcessors
& {2 o4 l2 d: t! R1 ]! ~* T{6 ~4 O/ N k7 ]( `
[ContentProcessor] i8 i% \% T, H w
public class DefaultFontProcessor : FontDescriptionProcessor
. v, h: x# G9 m% S& i1 _ {2 \5 [' H) A. J- t/ m
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)3 _8 ^7 f" _& f$ \
{
8 n7 a6 _2 {5 X& N. h: { //载入文件& u6 D) y( O1 F, e% O
string fullPath = Path.GetFullPath("message.txt");
3 m# \8 U% _! D' e L4 | context.AddDependency(fullPath);7 M4 I8 E, P0 [& o! h7 `
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);3 z9 [5 [) L, e" F8 [, y: q/ J, Y
# U3 C" q9 w3 F; \6 |' r
0 k* m" X1 m' z2 b% C) C, }3 k //导入字符
% h2 _0 ?# H6 H" {; H$ o foreach (char c in letters)6 k' x" x5 Z9 [* ]$ ]; f
{
4 [2 V5 } d( M6 W; W0 a) H/ ^ input.Characters.Add(c);
. D3 N( b* t6 ]2 I }
& m+ u$ A* f2 O8 ~: H0 X( H8 W9 q+ m return base.Process(input, context);
$ s: A2 Y0 o8 U" B" T, Y }
( P; f4 @$ x' X2 y6 n Y1 b }
- I$ o7 F! V! a" D: a}
4 \4 D( s7 o# Q0 Y
3 s0 I! H) @/ u! r. ]" U4 I | 1 _$ O( v% @! g, v
3 y# c: }" w/ X+ S+ y1 Q7 F
添加项目引用
6 b) C+ ~( U5 L9 G6 T[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
% l+ p: l% B1 l/ w3 V. I8 SGame1.cs | using System;& h: j5 g+ u$ z& j
using System.Collections.Generic;
" p: Q5 X4 p) r( t# ^using Microsoft.Xna.Framework;" O. R$ m* M1 U/ F
using Microsoft.Xna.Framework.Audio;. O+ x# q7 z* A) f! Z' X" w
using Microsoft.Xna.Framework.Content;
* Z# n5 K/ J! A. Cusing Microsoft.Xna.Framework.GamerServices;
4 E3 d- m+ L' I) s# L/ v) J+ [+ R b/ susing Microsoft.Xna.Framework.Graphics;, u2 x( K# \( W s0 v; E8 _
using Microsoft.Xna.Framework.Input;1 a ~3 Y) p( V4 s) N" T
using Microsoft.Xna.Framework.Net;
* s. R1 s, w, v0 Susing Microsoft.Xna.Framework.Storage;
/ i. q3 j" `1 c4 i
" Y0 y; e' c3 K+ h; @$ _; h: x6 B2 c0 B7 r' ]" l
namespace HelloWorld {
- `! I$ w1 n' z8 P1 Q4 y1 a public class GameMain : Microsoft.Xna.Framework.Game {
, m, L( w$ H2 Z5 o3 U private GraphicsDeviceManager graphics; 8 J- c; V7 g/ |+ p& a
private SpriteBatch spriteBatch;6 v1 p" r) l. {+ N( I+ C M, ^4 P! l
private SpriteFont font; ) p/ I0 j3 Q7 R6 S
P$ n, x% F0 M- y) Z, h
, w9 B* c4 j% H ?4 R* d public GameMain() {% _* F. Y" f. i: ?! E
graphics=new GraphicsDeviceManager(this);
7 T6 E1 E( l5 k& D4 J) [$ _! @( X Content.RootDirectory="Content";- z5 I' i% k6 Z# t! U
}/ E; O0 k9 ~1 C* d" w. ]' w" {
, |1 h: x6 G3 q2 s" E2 {2 s7 X" A, S3 ]
, `- m4 i! i1 N- u: i! C& X protected override void Initialize() {* @5 P( a8 _, [/ t8 l- i- f
base.Initialize();7 n: {' L% o) I3 t! Y
}" r& }$ x5 X h Q
8 | D3 s6 O0 n1 Q r+ E2 X
) A$ E$ d1 R( G8 P. b protected override void LoadContent() {
# N! p x% k8 T6 ` spriteBatch=new SpriteBatch(GraphicsDevice);
1 y+ @# f: o5 W N v1 V font=Content.Load<SpriteFont>("DefaultFont");* K0 d6 r6 X" F2 k
}" T9 `7 j% V6 b9 X+ Q
) u2 v8 m5 h3 f! g+ ~1 x
Z- X$ O! h7 j( v6 i protected override void UnloadContent() {8 b6 q& A2 W0 `" n/ `: ~$ n
}, P- y6 O8 Q+ ^$ ~5 N; N% z& ^
; Q, q, N8 @- W- W
0 s; Z3 i. D2 `/ J
protected override void Update(GameTime gameTime) {
) t6 p* f3 ~! C7 x) b& W if (GamePad.GetState(PlayerIndex.One).Buttons.Back==$ [" g, b6 r& r9 _; f9 J( c8 |
ButtonState.Pressed) {
5 w; ~' q2 ~$ F* g% L Exit();" M% Q/ s7 [! u( L. }+ P9 G3 Y5 v* @# V
}9 o$ P2 D9 V# G5 t% x
( x' Q4 X/ m3 W9 G* y( ^
' r( d" P* `2 | base.Update(gameTime);- J, z2 X! _1 N# _7 i/ X/ R! A8 J0 a
}
& q/ l, t& k6 a
, W$ P/ v6 ?/ U: ^- g( K( x" n
3 A. A. c( [, Y& ~) u0 R( A/ d6 f; l protected override void Draw(GameTime gameTime) {: S2 c2 i+ Z4 ]( Y
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
; J6 Z0 o+ L9 A( l- J% Z
9 C# u: n1 e$ ^, S0 k9 t( X- U( D( K& _' f
spriteBatch.Begin();. J" e+ d* T% b( B5 Q: i' l
DrawString("中文输入测试,日本語テストを入力する",50,50);4 I4 H2 \+ _4 y# @: X
spriteBatch.End();
. c. ~( C8 G+ V/ Z `7 q" w( Y, X
$ U6 Y0 E( t4 x) H! g3 S2 g8 @8 a2 Q' p5 [
base.Draw(gameTime);
$ A( O1 W5 h' F }: n9 K. i$ {# \- {7 Q
9 i1 Y3 M/ p, o; g0 n! O
' H& B- B5 c8 V y/ h private void DrawString(String str,int x,int y) {
% }" _; W5 t r" U3 m6 a+ w* [ spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);* n" C8 T5 m2 R6 o1 T* p
}) l6 a- ]5 {" [6 [. T$ W7 x
}. I# o! {) Z% [' i, u' m
}2 j( [7 j6 [& U
" {$ V. {) V& N3 |4 ~) _5 W5 r; }
|
|