原文8 u5 P! u/ _2 K. W
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx/ p: {8 A+ y: K, } c
- o% l8 ^& b# g2 M
# O& T% x. H1 q D2 X
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
$ S" n* [& \9 t" {) mXNA3.0+VS2008SP1下调试通过9 i3 p2 C. m* K
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。2 |1 j2 B* H! V) W! ~* R) n
步骤如下:
3 A; O6 ~4 a. ~9 P建立字体文件5 Y P B2 t) X, A C
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:6 n% }; @+ b6 g) x( k
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
9 y; Z% Y' x2 f+ \! h9 }
) {' H/ f" k D. G | [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:# v: z8 O( O4 O+ m% m2 ^3 b
[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;
! K1 A$ j) \) g" b, { Eusing Microsoft.Xna.Framework.Content.Pipeline;
7 }1 }% z% i/ F; ^5 d, V- uusing Microsoft.Xna.Framework.Content.Pipeline.Graphics;
v% K* R/ Q' busing Microsoft.Xna.Framework.Content.Pipeline.Processors;- ?! h! C* o+ o1 Z
8 E, `0 n! B' r6 L) ~" d0 i {: Q' O
7 Q y/ X/ r V+ Y" b) A* lnamespace FontProcessors
I' J( G' @1 ^4 ]7 ?{: b) m. w! ^- ^. y
[ContentProcessor]2 ^2 A9 F# b- Q& j+ P6 V5 c: I" M0 \9 H$ U
public class DefaultFontProcessor : FontDescriptionProcessor
! i) T; ~0 a4 x1 b! q {. f$ `- Y4 e* a" [. ~
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
; Z/ D+ O* S3 R- i# t {/ U3 z# L$ Y) p: l: F
//载入文件/ J2 u3 R% A4 `- |- S Q( q
string fullPath = Path.GetFullPath("message.txt");
! X8 x5 g& V- w! u3 R& H% ] context.AddDependency(fullPath);0 S" T# _) j) w
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
4 }& u$ c: J, }) V7 M: [! X% C" E, n# y
* C: x* z8 f. l0 _$ G3 Z0 S
//导入字符
% U. f# Y( K2 V" e+ _9 \ foreach (char c in letters)
$ \$ T4 Q$ [' a5 |+ h( ~ {
# c) S" y* i; v' X input.Characters.Add(c);
; ~" ]; H1 m: ~$ f0 \ }
' r# o" w2 ~5 H+ z( ? return base.Process(input, context);
* b3 a9 J4 G A4 T( f: L }
1 l& U2 N# x K( @5 P }
/ u; J1 w% _+ t9 C# F& V2 h" Q}$ }3 o" q. V X3 K4 b0 _5 w
) f! V1 s" }7 A" u
| 5 }% e( _ I2 b& R8 X
+ P0 [8 j! t) ? b9 w3 I+ H" [添加项目引用 b; `8 u6 Z& o! I# |, Y/ t& [
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用! L8 p, [4 g0 O
Game1.cs | using System;7 k2 D; q' c# t
using System.Collections.Generic;3 A+ F& E4 T0 K1 `( ^& A2 _
using Microsoft.Xna.Framework;% O& ^) O9 E& N# ]; r8 O9 y
using Microsoft.Xna.Framework.Audio;; u4 S& @1 m7 X4 l) M g
using Microsoft.Xna.Framework.Content;
3 U/ j( n8 Q0 A9 ?& ~0 U7 a; _4 Xusing Microsoft.Xna.Framework.GamerServices;
' t" t8 B9 d% }, S! J( [, dusing Microsoft.Xna.Framework.Graphics;" `- v* W# ^& x3 t
using Microsoft.Xna.Framework.Input;0 \+ P [& J$ ~( _8 u- \
using Microsoft.Xna.Framework.Net;
P D( K) A% Rusing Microsoft.Xna.Framework.Storage;2 v1 H& B( }. R+ P8 r1 a$ c, {
$ W) a2 U+ d4 [) \1 Z! G \: B- F
# ~" f8 ~# U* u. G) `namespace HelloWorld {, e; D1 r# T+ S/ j6 v C
public class GameMain : Microsoft.Xna.Framework.Game {
5 k1 B c) |' X% J8 y# a' ] private GraphicsDeviceManager graphics; ( f( {; k2 ~* ?2 C' [
private SpriteBatch spriteBatch;
7 Y" i6 y+ [ l private SpriteFont font;
2 e4 E+ i& m$ G: H. J8 v: v+ i9 e8 A2 w# A! l+ h
: G3 Y4 e# Q8 A( {' H! C6 U# F
public GameMain() {
4 S7 ~$ v! k' O2 R: ~# ? graphics=new GraphicsDeviceManager(this);
7 n# g+ N$ p6 z3 ?$ I Content.RootDirectory="Content";
b6 h+ i% Z8 n: P }+ B- ^' b$ E9 w2 n9 F
$ g8 Z g, e0 m; _/ I+ _: G4 v1 k3 M/ L, \ A2 e) c
protected override void Initialize() {( i0 o9 g- j) D, b. x/ i; X
base.Initialize();
) D9 o" g- Z( q- w& ? B }
: ^# m6 l1 D* i/ z, |. p9 M' A1 M3 R( J$ S @; m
8 g: U0 @5 S/ i# O' F% ^) m
protected override void LoadContent() {
0 y4 [( g" z( |% U4 u/ K spriteBatch=new SpriteBatch(GraphicsDevice);) m# g: Z2 O! k8 O( e# O" f7 ~
font=Content.Load<SpriteFont>("DefaultFont");
6 O3 g0 {* g3 f3 @9 z1 P9 S" {1 S }- v2 N' T! {4 R" ~4 o& v
+ ?) @$ L5 C: r- S: o) _% `4 z( g, ]8 [
protected override void UnloadContent() {; a5 M0 c5 v( j- g/ S
}
9 G, s8 p# x2 M, u& M, Y, Y
& H0 X7 l" U5 F0 p) v; ]2 }3 t8 Y4 M! j; M$ Y: ~
protected override void Update(GameTime gameTime) {: x/ [& }5 t/ o+ f% i/ ~
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==; Z7 V- u& B0 [, s
ButtonState.Pressed) {) c/ j9 X/ h( [1 k2 \2 _
Exit();0 K2 K8 i! t/ ~" f
}
& F) h% b6 {; \; l6 v( N% I! ^7 n
9 L, j# ?9 ?; E base.Update(gameTime);+ r, {; W6 t! e4 h
}9 v2 }0 m( g" v
! L, X% s8 g+ z9 u$ g) s
" l v, C( g6 j. f protected override void Draw(GameTime gameTime) {4 l% g* W2 G3 P
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
. e1 x, x& m3 L' A3 `, L6 V1 s. h, @- R3 J
* p& y7 m5 |: k/ @$ u* ^$ [8 \ spriteBatch.Begin();( R; ^ F: q1 `0 s
DrawString("中文输入测试,日本語テストを入力する",50,50);
" e5 D% g: u, G spriteBatch.End();+ |3 K/ S6 T( B0 [8 A+ s
8 S. d. ]: \5 S' ~$ E' \0 k [: b$ e% v# b. T
base.Draw(gameTime);& y0 c+ H0 G7 C) W7 k
}* X+ m# H7 v: M
+ Q( B5 G' Y" I F& s5 [7 G
$ x$ a& ~6 S$ H0 d! J+ m$ D private void DrawString(String str,int x,int y) {7 f* z1 |: [) n
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);3 ?- C, z, S7 d9 m) U
}# R, p! a) R' `) H, q
}
8 e& ]3 A2 t# L; G, Z}
+ ]& L1 Y# _& o3 h T- {! T h* b; G7 c' K! h: d" Q% V( r
|
|