原文
6 x' R$ z) K( t$ }! ihttp://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx' i8 Z6 K9 ]$ K& X
. l0 x! j9 Z9 s5 [$ t
: z& m) J7 Q# c; m" O$ A, ~5 k在XNA中显示中文字符或其它UNICODE字符(非GDI+)5 Q. p# s8 u9 K/ D0 q$ b$ i1 p# J
XNA3.0+VS2008SP1下调试通过4 w: L, }6 C- a
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
" ]* V e1 u: w( N) r+ R, h步骤如下:
" \- `6 U5 n% @( n建立字体文件 v$ |* K6 l$ b0 F$ N5 t
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:
+ M8 y7 L( Y+ ~$ h/ F3 o[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
9 E8 S# z n" A( s8 `$ I# R4 G' {# \9 z3 N9 z
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:. x* G0 F# I. |" j. j! E) t
[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;
. U y2 _: ~" X2 r3 qusing Microsoft.Xna.Framework.Content.Pipeline;
! h- U- Q; w% k8 ]! Yusing Microsoft.Xna.Framework.Content.Pipeline.Graphics;0 ?% H2 o* W5 t
using Microsoft.Xna.Framework.Content.Pipeline.Processors;" @9 ?% U) d7 K
( Y# P. W( i( v
y" M6 L$ S; ^7 {namespace FontProcessors
7 v' q8 J8 l& ?( B# h) U( C{0 Q1 k- T4 s( U t5 c
[ContentProcessor]
9 m+ J0 r9 T% i, l# U public class DefaultFontProcessor : FontDescriptionProcessor
( j5 V+ S" ]8 X" {4 i4 A# o {
1 d. @( w: s* k& k5 u: L public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
: Y/ A+ c0 L' x {
+ `' z2 s8 A: k* t2 k! I) J //载入文件6 O( w( c' t, P6 O* b5 v3 |# P
string fullPath = Path.GetFullPath("message.txt");
. g+ |- ]9 d# m0 n. F; A/ } context.AddDependency(fullPath);" F- I' t, R, x
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);- f1 D/ E% g* a
* r. g1 c5 E* S7 |6 _+ W: n3 x: ^$ c$ o1 F4 D' }& Q1 \
//导入字符
, p) r q$ s" I foreach (char c in letters)- f& _- \& z7 {3 L3 w
{4 Q+ X# A' B8 D
input.Characters.Add(c);' O$ l$ w* h: C6 _+ B8 Q8 i$ x
}- J& ~6 a) } b
return base.Process(input, context);9 g1 F) C% N0 R7 V) L! a
}
6 Z8 O6 R5 k4 I1 h5 K( s2 K }& V- j$ a8 n: d0 O8 J5 x o4 f c2 C
}
8 D7 E; `1 m% e7 _ G. u) t) |& i9 {% ^& C" t. ]
| 1 b; v8 I1 M+ h' T$ E/ a, E
+ g5 ?; {. d$ h8 [0 _/ q
添加项目引用' A) q! L9 ^* Z, B) A H
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用* s: @% R9 Z! z3 c9 _4 t X
Game1.cs | using System;, D3 ?. h3 e. b! q# m0 N
using System.Collections.Generic;
% N( m/ a* f: O% D) zusing Microsoft.Xna.Framework;
1 Q# ^, q1 O7 J( [using Microsoft.Xna.Framework.Audio;$ x0 A" S6 M2 c4 a @* l# l
using Microsoft.Xna.Framework.Content;
( l X2 T4 K. ]/ J, fusing Microsoft.Xna.Framework.GamerServices;- z1 o& G5 [+ H4 D
using Microsoft.Xna.Framework.Graphics;
9 R! P% H+ {3 e6 v iusing Microsoft.Xna.Framework.Input;4 s6 [5 U% Z8 q* Y/ g( h3 x1 \
using Microsoft.Xna.Framework.Net;
; h! ?8 n. Y, k7 ?% kusing Microsoft.Xna.Framework.Storage;) ~6 ?4 N$ T& P+ q/ E. ]1 k
/ I2 N% H( g) I: Q- B
2 c# S4 _* {$ z6 i! Unamespace HelloWorld {
2 [4 n' W6 ^1 S- z( \! j% _: ~8 L9 ] public class GameMain : Microsoft.Xna.Framework.Game {. U) V9 m! t% t% b
private GraphicsDeviceManager graphics;
+ X4 b1 \+ Z, d! U' Y- F; f" @* m private SpriteBatch spriteBatch;6 H6 x u- @! c( V, i
private SpriteFont font; " ?+ h7 B5 a. m- \. E+ H9 y; V
- J# D! m8 X: w( {
; ]1 Z6 D# Y1 @ public GameMain() {+ b4 s+ P! O! y# ?- _; K! ?
graphics=new GraphicsDeviceManager(this);
/ A0 Q4 X. K3 l6 ?; ^ Content.RootDirectory="Content";
) L- e8 ]- [- `/ X, z }& c2 {6 p/ y6 Y. e. \1 p2 {
6 O; A5 x. f) ]( e' h
0 F J3 D' t6 c0 J protected override void Initialize() {
% U9 Z% Z$ F6 J' C1 R) x9 h3 B8 i base.Initialize();: j2 ^3 O1 \6 Z1 g
}
0 z) C: J6 g$ P3 o* Y4 I
! U( D5 {+ L7 u8 _7 u$ c1 v
+ D/ u5 T; X* r" \4 a2 p% G& N* W$ _ protected override void LoadContent() {
4 z9 Z( k7 `* g9 Q spriteBatch=new SpriteBatch(GraphicsDevice);* g2 }6 f1 z1 i: e8 o; v2 p
font=Content.Load<SpriteFont>("DefaultFont");* u* T2 u: K) @- Q
}4 U' t' _1 b. Q8 L# i: o
6 r1 x8 b, u6 ]3 i8 U0 L* \" B# S
7 V) W$ t& U- J& O# N* Q protected override void UnloadContent() {
% n- _$ l. O* x4 B. L" Y }; X3 u; l) F+ \5 A
( @7 J* ?0 w$ L) g6 E# X8 W% y; U* {# m% F3 y j
protected override void Update(GameTime gameTime) {
6 |) Y1 t1 ], [8 ~7 L- \$ O7 p; [ if (GamePad.GetState(PlayerIndex.One).Buttons.Back==
% |$ P0 M! D( V ButtonState.Pressed) {
+ k% ~: @8 `8 b1 _/ s Exit();
- j) U2 g0 E/ C/ n- c3 x O }
c: e" g: @7 ^: t& Z2 s$ N+ X& ]! p# m' d+ v
9 M. K. o8 e! r1 t7 p z7 Z7 c
base.Update(gameTime);+ \* L4 Q; ~- ?* G* _! I! l1 V8 {; K
}, F6 R4 \4 T# G; m# }) n( O1 n7 |
& _9 O- m1 G# [/ n- Q3 J" z) G
7 y- s0 c: {4 w1 p9 ^1 H) E( G protected override void Draw(GameTime gameTime) {
' m! \6 \- v8 V1 _$ p R- q/ [ graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
; d+ |2 F q" C3 |
+ @7 k8 n! {* {8 I! g" [
4 p- X3 Z. z# @5 K' W+ i5 z spriteBatch.Begin();$ k- y- |* N$ H) X4 i7 P
DrawString("中文输入测试,日本語テストを入力する",50,50);6 G7 @$ |- p6 D$ j2 g" z
spriteBatch.End();6 P) v" m% U8 d% T- z8 y4 r/ J" K
2 p* @$ E9 d: b3 V$ e0 B' z0 ^/ ?
. d' L- Y" h# O) e4 }5 | base.Draw(gameTime);
3 H3 J7 }; B7 v5 ^+ O }
0 j$ c2 }, j; _0 V9 W9 m% E9 L5 j3 t1 c3 Q) O% n* w, j/ N
' ]4 |7 C2 }6 }" Q9 U R* H
private void DrawString(String str,int x,int y) {" ?& [. @6 @4 @) n' [7 U
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
$ [( H5 h) s3 T7 u P! m2 j }
* F8 \7 ~ s7 p) Z! `* y# M }
( Y' v4 z0 ^9 `5 a) b5 `$ E! _# K1 S}7 Q- A2 |0 D7 @; _% J
, w- U# ^& B5 K
|
|