原文
) [& t6 O1 [6 b& Y" d, p: R4 whttp://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
* V0 m& [* a% }
' t3 Z! N# L3 f m( i6 B& t0 j
7 X4 C7 s( y* _* x& a在XNA中显示中文字符或其它UNICODE字符(非GDI+)
+ `. [- v5 y# ? k# G$ G- E" O/ r" zXNA3.0+VS2008SP1下调试通过% Y: `% P6 A. d0 O# H- B- I% ?5 o
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。 A" ^) _: C2 Q! Y
步骤如下:# I2 v. V. k1 K ^
建立字体文件
7 U q( h \* E5 A[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:9 F( W: z# G, c( ~4 E6 r# }
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
3 m! i! r, {8 I& \6 p( d" _* q' ^$ m& V! U' x
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:) J, \& n( z5 E4 S$ }9 b1 k0 ^
[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;
5 d5 O& c- z7 ?4 V& V, ausing Microsoft.Xna.Framework.Content.Pipeline;
+ ~( b7 y, e7 Husing Microsoft.Xna.Framework.Content.Pipeline.Graphics;# X( `6 Y$ O/ G/ J
using Microsoft.Xna.Framework.Content.Pipeline.Processors;, C1 Z) `* X$ f" k! o
& ` N4 ]) T) q0 J/ Q2 u2 s7 {; l' Y+ i, \" L
namespace FontProcessors
9 I& _. e' ?6 m* o2 G{4 d! x6 [; X1 l
[ContentProcessor]" U1 W" g% x2 Y w1 i! @- D
public class DefaultFontProcessor : FontDescriptionProcessor
2 `+ G5 A; _. G# k. ^ {! Z! Z/ Y3 q; t8 P W: t
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)* \' L6 D3 I2 ^' X; v* E( ^
{' k& b5 ~: k+ y2 {- q
//载入文件
$ D' f% s5 b- G) b! b1 Q. N! R; D4 ^& q9 [ string fullPath = Path.GetFullPath("message.txt");
y6 d( s) p1 f1 s+ K( a. h context.AddDependency(fullPath);" {) y* H3 K4 H x" W: P
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
1 s6 X6 p2 a b% \' @- o
, E- g& Q* h7 p% @: M8 Q) P
! V4 a" r" B- V1 {' x2 h& E //导入字符9 V- o' U0 f0 @
foreach (char c in letters)
& L/ T( g1 G+ k8 u6 s n {- b1 {; ] {' S* W
input.Characters.Add(c);
- x4 [# Y: {! k2 Q& t }" ^* e+ B" e. G8 b4 z7 }8 q
return base.Process(input, context);
( ]" c6 J, B2 g5 |/ r1 } }
( Y. S: E: V, S: y5 U- o/ G }
. R0 }, F" C. Q/ T6 R+ T. _}- ?: u1 `5 e9 V
1 t+ V, m/ v G8 \8 ]" I
|
2 h) r% b y9 Q3 h7 Y9 w- c3 N1 H" s8 C& }7 ]' M
添加项目引用7 V" j) {/ |7 O% S2 q
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
" h! h2 |7 Z! I( b' zGame1.cs | using System;
5 W. x0 w9 z( o2 E9 f6 B0 w% iusing System.Collections.Generic;2 G9 _ @; F2 N: _
using Microsoft.Xna.Framework;
; O6 C) g; l3 r) s w6 b) Gusing Microsoft.Xna.Framework.Audio;
" E& D/ S, }2 yusing Microsoft.Xna.Framework.Content;# N6 Z9 d, s q
using Microsoft.Xna.Framework.GamerServices;
) L; U: m* d' K2 ^' Fusing Microsoft.Xna.Framework.Graphics;
! ^, [" p3 Q6 Y2 ?1 Zusing Microsoft.Xna.Framework.Input;
; R* i& E+ a4 s \) s3 x; Cusing Microsoft.Xna.Framework.Net;6 I* W$ J1 {7 ~6 `
using Microsoft.Xna.Framework.Storage; `0 V9 j) S$ D) g( b
( @( ]! A3 a! \, D
! X" I) ^% j' d# Y: q4 D( i
namespace HelloWorld {6 U) l7 I$ w5 `* K( C
public class GameMain : Microsoft.Xna.Framework.Game {& M/ J4 _% N. Z# h& h: T
private GraphicsDeviceManager graphics;
# [2 J% t. }. X/ C, I- U private SpriteBatch spriteBatch;0 S& C0 R' l$ z. C' d K# p
private SpriteFont font; " x6 g# K e* {
6 ^% H, m7 s9 ^0 \; Q& K" n6 M
% D, a0 b' K( X$ i5 I public GameMain() {3 n4 k9 j6 Q! A( v5 w6 F
graphics=new GraphicsDeviceManager(this);) Y o/ T" a' U
Content.RootDirectory="Content";9 w2 i/ _. ?, W1 J1 s' X
}. z6 }' }. g$ X/ n! H
' k6 c+ W( W6 _7 D- N9 A
$ z1 A+ t1 r" W+ h5 g9 a protected override void Initialize() {
7 u5 \& L- j# m( l- [# e base.Initialize();
& b0 K4 \7 T2 _4 T# U }8 o2 D' o. ?8 ?8 Y) I
; e; e2 T3 W, b( t8 X7 ]
3 K# m; I$ ~, F* @% c: p5 ~
protected override void LoadContent() {, [7 T+ D3 w( v( b$ r
spriteBatch=new SpriteBatch(GraphicsDevice);
! S8 r! o8 k0 P7 | font=Content.Load<SpriteFont>("DefaultFont");
0 J+ g: i2 y: W }- t0 e( W1 [ ~
# m: r9 w6 g1 F* e4 e6 b
6 F5 V5 G t: Q& ~5 x7 W protected override void UnloadContent() {2 P6 c( G- h7 N4 k" e
}
* z. P& [7 Q: i+ u( B9 @1 k. S8 c' m9 n2 @) v: z/ O' L! ?
* ^& f: H$ y! D/ t1 G protected override void Update(GameTime gameTime) {
5 q r: N) s+ N+ h+ H7 X9 l if (GamePad.GetState(PlayerIndex.One).Buttons.Back==& x2 ^( ^4 ~. ~) d0 q: Z
ButtonState.Pressed) {) f1 y+ ~8 @1 o3 `: Q3 v$ e1 i
Exit();/ U: Y7 V' \# i, Z, d, A
}6 u$ ^. w; p, R3 |! H
& w& E! [% |. y; W6 c* ^' u0 C- \4 r" }
base.Update(gameTime);- {% u" r' m7 X" S
}
& H) {( t. Y1 G( R! t8 u% g& @7 f
9 V2 O9 K: ]# o& v1 P! R; ?+ D) c* ]! y
protected override void Draw(GameTime gameTime) {; O, I2 v& H; S1 D0 g* Q1 `, N
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
- o( b' z' ~/ t) D% j; T. Z1 F' W* u
$ i1 q7 s; J$ x. w
spriteBatch.Begin();
. I- F/ r9 @# U) z0 T DrawString("中文输入测试,日本語テストを入力する",50,50);* D; v6 C' x; h1 h1 {- d$ i/ X. s1 u; K
spriteBatch.End();
! M H( C2 L: b$ R0 h7 D7 X' M
4 g% ^3 `# o) S
! ?/ J2 r' T: Y5 S2 e* q: p2 n- [ base.Draw(gameTime);
( m, [' B* L+ d4 ^, _2 `1 U5 V }% ]( t& d( Q t: p
% T' |- _; V5 S; L6 `* [
& ^2 N6 ?- _0 y# ]* E# ?- ] X( a( w private void DrawString(String str,int x,int y) {! M3 ?- o& ?5 @% z9 C; \
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);4 |. @4 @4 y7 N! D5 ]7 y6 U
}/ h/ N. i) \. W6 K d R- f9 Z+ P0 Y
}
( m+ f+ Q2 B+ K. ]- i}6 K7 g9 u. [' t5 ^5 J+ U6 v
$ O* i8 g( a* S+ [4 N; j9 r5 m+ s |
|