原文
$ g/ O. G# g! a4 k. I) Khttp://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
% v8 V1 u! ^" z8 ]9 P" h
' m! s" n( o S' e. V o) O; j. I5 Q # g$ W2 x y6 U& T( M8 G
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
$ m; `8 I5 U' f5 ^% J# _% K9 dXNA3.0+VS2008SP1下调试通过. X" k1 F' d* j1 T& R# n
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
- B0 {6 N( d/ g) t- n4 e步骤如下:
1 d& [8 U" \% Y5 Y" N( _建立字体文件' g3 N- ?. l! d. L7 b
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:( p3 A, }1 Q* a: @ T* \
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
1 [1 P Z# s4 c9 Y& E+ I1 I( {" e; j5 q# h
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:
3 {7 n5 e/ f3 l$ ^) X& W[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;
# ?7 ~. q# k* X* k% O8 I: Qusing Microsoft.Xna.Framework.Content.Pipeline;& U" K: t5 u2 ?& X. E
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
% b8 d- @5 Q3 B; _# K, V/ Xusing Microsoft.Xna.Framework.Content.Pipeline.Processors;+ Y; O4 [ u' ]1 q$ E
1 U# p! R) G- l. u
5 X& f5 G5 @1 R1 _
namespace FontProcessors
4 L7 L9 D1 T4 ?) ]2 k* U4 k! ?{1 t3 _2 q5 w+ l& D; U9 ]* D+ _4 ?
[ContentProcessor]
6 s6 `+ c( k/ V( f, s! K public class DefaultFontProcessor : FontDescriptionProcessor1 O( ` E7 t" n. x- r6 f" A! d6 P
{
+ W( n3 c% Z2 X* x2 X# O$ \! [' L5 ^ public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
0 \9 |, ]& R! S( e5 I {
- C* i% I) K/ I/ C v! M/ ~- _ //载入文件( g. o: u l# L5 ~' j: X
string fullPath = Path.GetFullPath("message.txt");
2 d% K! M/ p) w f" f+ J, y context.AddDependency(fullPath);/ D& Q" ?2 X0 _7 O! i1 n+ d
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
9 ~0 ^( y1 x! L0 d8 `" ]$ r& b" U
" S$ B0 |. j* [, V! i //导入字符
: Q, F6 I1 @3 X" r+ d6 Z9 ]0 a foreach (char c in letters)8 D2 y# E) r% m$ Y
{2 J- ?: @: O3 ]+ B0 x1 s8 E! n
input.Characters.Add(c);
; c7 K: X' C5 U; c7 \ }/ J8 b1 O P9 H- a
return base.Process(input, context);) _3 E0 g" G! U& u# l
}- w. N8 K! r$ i% Z) X
}# M Y1 Q0 A5 \3 U3 g0 Z
}5 Y0 T$ l1 i* G5 p( w7 `+ J
! t* K/ w( [) _2 Q9 a" S
|
$ P \1 {0 a/ W# x" w% s5 @# C: k2 j' Z- s8 ^
添加项目引用
7 D+ Z# B% a' w- e |- }- ~( d' O[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用 a: R4 G/ l' z1 v% `1 H' R
Game1.cs | using System; ?/ `" i6 p S8 I
using System.Collections.Generic;
& b- [& q+ Z( D |( musing Microsoft.Xna.Framework;
' ~* @# G1 B! F0 n3 H1 Q0 X" a$ _using Microsoft.Xna.Framework.Audio;
" W/ L& j: V+ G9 K; i3 Husing Microsoft.Xna.Framework.Content;
( Y5 c6 }* ^5 O- T8 |* l3 \! _using Microsoft.Xna.Framework.GamerServices;
% I, S ^4 r ~using Microsoft.Xna.Framework.Graphics;
' v0 A ]5 T; ]" c" xusing Microsoft.Xna.Framework.Input;
$ k# j+ o8 W9 R& Husing Microsoft.Xna.Framework.Net;
/ I+ a* f8 q. p1 K4 s' d5 C% L7 Rusing Microsoft.Xna.Framework.Storage;
, I% {7 t% R( ^7 `, E/ {$ d4 _' Q+ p- H; {
6 b' ~9 j: P+ A
namespace HelloWorld {
% |! ^% m( i% s: R& x9 _/ _ public class GameMain : Microsoft.Xna.Framework.Game {
( m3 _; O% l& `' K( V9 n( _ \ private GraphicsDeviceManager graphics;
% ^/ p+ `% Q: m) c/ B private SpriteBatch spriteBatch;
& e {5 k+ }7 o private SpriteFont font;
9 K( d( p. p$ ~! W
a9 w' U2 d7 }% [: V
6 i/ z2 J$ T. O# v; C$ V5 s* G public GameMain() {
) L0 w# h2 Z- c9 N9 q- I0 v3 Z% L- x# J- s graphics=new GraphicsDeviceManager(this);
+ e* Q) C2 z& T- Y1 J3 ^ Content.RootDirectory="Content";+ E% j: I' C; y3 i8 l7 i4 K# @" D
}
- b* T$ |+ Y0 E+ h
' l0 M" ~2 q* q8 e/ J
}. L2 Z) h0 T/ }- [" ?) ^% P protected override void Initialize() {
7 b f4 b9 C" b% R2 O9 r: f1 E" W ~ base.Initialize();6 X5 O5 \; X! P$ [" {
}
g2 m% Y8 C7 T
: q% ~5 O6 W( z' O) j% \" l
* C0 K9 p- @8 v# @( N0 b2 W protected override void LoadContent() { U/ {+ c7 T) l
spriteBatch=new SpriteBatch(GraphicsDevice);
$ d2 S% \, T" ^- l p1 ` font=Content.Load<SpriteFont>("DefaultFont");( S# d6 ~* T9 B# r6 a. y
}" i2 f, g2 d* y2 t& H! ?: G; B. R
) [2 m' Y, C: Y f1 a1 S2 W9 ]: l: _/ D2 L7 O+ P2 U
protected override void UnloadContent() {
4 w- z2 p1 Z+ ]' J1 N: K7 I( t }
- U) Q$ w; y0 o
. ~( f/ S$ k8 t1 c8 |3 X
/ b( s& _' {. d protected override void Update(GameTime gameTime) {
) k( [9 p" p! g, J if (GamePad.GetState(PlayerIndex.One).Buttons.Back==" i) I1 w/ Q) B! a. ?
ButtonState.Pressed) {( F; a% S, Q$ u" P6 n. {
Exit();7 v* M- X/ Y4 ?* r
}
4 X, K) X- h. L i+ w: [
9 f) b' X) I u3 T# ] P
; ?5 u1 D/ E6 y/ X q base.Update(gameTime);+ O" C6 R7 Q4 Y7 {! |( J
}
$ q8 m$ |, r1 m/ m$ H: T
7 N& |. ], I9 {. F8 s/ W- W0 l( c n7 i
$ l/ s% H* }5 N5 M" Q8 a" ?3 n protected override void Draw(GameTime gameTime) {. X4 ]" k: [& Q0 x# j. g2 C" R
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
* [# M- ?9 n1 s* m4 C8 X* Q: B- t+ L. A! U$ G
) V( r) G n" b; s3 h spriteBatch.Begin();! D: l4 W1 O2 g0 ~
DrawString("中文输入测试,日本語テストを入力する",50,50);+ ] E6 H7 i: z3 F2 K1 C
spriteBatch.End();
. [/ m( P% ?; P9 A3 T* ~9 v- H" c
}& T; {' D/ @ j7 }0 ^
base.Draw(gameTime);/ A; q+ w# Z1 H$ x# N
}
+ u1 m3 W4 z. L, k8 j/ B
0 ?5 E! v+ L) R# U w; @9 x( T, X
private void DrawString(String str,int x,int y) {! W2 B% R+ i; {+ v7 N
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);, B2 U: G; G% r5 c' a' e
}
0 g* n: X& c x }
" d$ q u. ~' T/ @0 ?- R: |}) l0 ?1 X$ k& t3 ?9 \
! e v% k j0 n$ H/ X, @
|
|