原文
) r" J6 q! H2 T K: Y/ J w: Uhttp://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx% T* ]+ H% e0 o! z# i
. c9 B- F: e8 I; k
% g4 n( T0 F# G) N在XNA中显示中文字符或其它UNICODE字符(非GDI+)
- l' C8 z5 I+ fXNA3.0+VS2008SP1下调试通过
6 h) {/ ?/ A$ s) x/ q9 _由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
7 W9 C" m% J! I1 M1 E步骤如下:- [9 Y8 `7 _" j
建立字体文件7 ^. ~0 {* L; M0 m" e" ~% q# |
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:
& v$ O8 \% [- ?6 W1 f[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
/ }7 Z \: H' }- I' u& z# S$ c* d4 a( U
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:
4 `" y4 _! q6 n0 v' ]. H[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;6 a2 h- I H6 H# a: a
using Microsoft.Xna.Framework.Content.Pipeline;
f/ a5 j4 X, y( ^" X( k( Wusing Microsoft.Xna.Framework.Content.Pipeline.Graphics;
( R9 F! }& X4 ?& [8 P% Zusing Microsoft.Xna.Framework.Content.Pipeline.Processors;( c* K6 t- x2 U6 ^' z0 M
+ S5 b B# p; c
( S N8 V; ?/ }7 k- W( K( B
namespace FontProcessors
, d! p4 Y- B# j8 J9 y{
7 t; M6 G$ T* d" w/ O7 t$ y [ContentProcessor]
8 D8 ?8 c1 D0 u0 d1 f$ z public class DefaultFontProcessor : FontDescriptionProcessor
5 I6 w) @5 P' O1 x+ C* m$ v {6 i, @: x& e% h* r) f* d# _
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)( t2 |9 H$ \0 Z4 L7 C3 V5 O
{
: {/ W: X# h6 L0 h/ z //载入文件
7 H5 a4 W4 g) N5 ]- v string fullPath = Path.GetFullPath("message.txt");9 F, w6 X0 A4 t0 v8 V
context.AddDependency(fullPath);6 S% A4 Z9 B* G' b
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);8 Q0 f* X$ A: @6 I: G
$ V9 B. f* w- t4 _9 ^: i' T5 C1 g5 B! s0 G% N8 j/ m# W4 X8 A# H8 `
//导入字符' o+ M$ a/ V$ e, U# }7 }
foreach (char c in letters)5 `. Y( G/ S2 G
{
; }) _: O' x$ B! ~, }+ ~ input.Characters.Add(c);0 N' ~+ t. T1 a' L8 ?1 }
}* h! I' m) u, ?! x1 z N2 k
return base.Process(input, context);& n7 I! L" X! t) ?0 v/ A w
}
& f; e; j+ ^ G }* _! ~5 ?1 t' y" O- u
}$ C' N8 c2 _: n3 J5 h6 y3 g5 Q
2 }2 ?# I7 ]( U) u3 e, Q | 3 Q" x. R) H: r- R
% l: K3 D) N: ]# U
添加项目引用, E1 W$ g: x6 O+ }' R6 T# _ c9 A
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
K! L) C/ A CGame1.cs | using System;
8 n: D9 _9 u0 a+ e0 s) J$ o2 zusing System.Collections.Generic;5 ]. K& v% [8 D P! `
using Microsoft.Xna.Framework;' z9 G& N8 W8 r3 O; K
using Microsoft.Xna.Framework.Audio;: M4 Y6 W! o& G* b0 ]
using Microsoft.Xna.Framework.Content;8 Z/ M+ q# V) c7 h; U) \" }+ [$ C; L
using Microsoft.Xna.Framework.GamerServices;+ p: g' H5 j- I+ l
using Microsoft.Xna.Framework.Graphics;4 z5 x- a0 m+ r& f
using Microsoft.Xna.Framework.Input;
2 X/ ~! U. l7 Zusing Microsoft.Xna.Framework.Net;' A |( t5 r! o, {4 _6 m
using Microsoft.Xna.Framework.Storage;7 m1 R5 r- y4 J7 H$ q
5 V# s" s( _& {
" D' M* h' c+ rnamespace HelloWorld { Z8 `3 e. K9 ]/ f% r; | V/ K# r
public class GameMain : Microsoft.Xna.Framework.Game {: d; W# _: Y7 o0 b
private GraphicsDeviceManager graphics; % k! P5 a1 w5 z' J1 }
private SpriteBatch spriteBatch;9 V& l, Y) K M8 A6 U
private SpriteFont font;
$ s6 s3 s P0 Y% O9 ~
8 b8 {* O: h/ ?; A
( q! u& Q" {6 j0 ?1 ]6 } public GameMain() {3 B1 N! t" H% h( [( P" m
graphics=new GraphicsDeviceManager(this); \/ T8 I- @' ~. _7 T: F
Content.RootDirectory="Content";! o' _! e" n$ F( N" D9 J
}& V; D- F4 W# M, m2 e
1 `* C- m o0 m( K$ a; w/ j
1 `5 M: s5 \* @6 e5 V( E protected override void Initialize() {
; ^$ f3 H5 o+ F base.Initialize();
- V' _' P( X; D' B) q! q8 r }
; s7 ^# V' E2 D2 e& W& j$ _! h7 \; ?; Z
4 w2 u: Y' z/ ?1 x3 \: e! S
protected override void LoadContent() {
* V! `; s4 s9 v* G2 A spriteBatch=new SpriteBatch(GraphicsDevice);) R$ b& f; x$ ~" t( w
font=Content.Load<SpriteFont>("DefaultFont");4 x% k& L% r5 w( w2 c) Q: |
}
0 W, C$ P; ^( k% p1 ^
+ P) A, ]* D! f ]" B0 i9 v! k* p( Y# ?& E P; ?
protected override void UnloadContent() {
! L, A8 r. b* G/ J }+ g4 S# F: ^. o5 T3 u9 \% [. K) {
! {/ y i6 [2 e5 R0 T$ s5 i3 R/ F) y
, W8 d: I* ^* U" k, r" q: x4 v protected override void Update(GameTime gameTime) {" }, }7 [, O9 _( J
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==# a2 |+ y+ ]% I' J% z
ButtonState.Pressed) {
" a) c2 |* g3 q. z Exit();
9 i, t0 X. W2 s0 G- g2 N }
3 g+ Q9 K! B- ]
4 }0 H- U1 q8 [, C9 Z2 K1 V
- S6 t* ?( l6 S2 C; I base.Update(gameTime);* g, E) W$ v1 Z9 c
}
, i! O4 K9 M; u5 d& X v/ R/ @) x5 L% g
7 }0 T; H& @6 T3 I protected override void Draw(GameTime gameTime) {8 g$ F1 K8 i: H3 M8 R1 G0 n
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);- a: j1 i; H1 C# V( p
5 H7 B0 T1 e/ E1 w* {
& d' b7 ?1 ^* s* O/ Y$ T8 Z" Y
spriteBatch.Begin();
2 n3 U& x( y& l/ {. d" h DrawString("中文输入测试,日本語テストを入力する",50,50);
' J3 y, o; I" q$ ?( E spriteBatch.End();" S6 V) g9 |9 G7 g! k6 }3 v/ n: S s
2 E! ?9 j2 i/ B
$ i: E5 S0 \' T0 u) |; b6 } base.Draw(gameTime);9 p/ U& v& m0 f
}
& A$ i; N# {8 A. f+ M- |. R; x" F$ G3 r* y1 }& q9 D
* R& }# k4 k1 G: m) G0 I private void DrawString(String str,int x,int y) {
; S8 e. f8 G4 n' d* d z spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);3 ?2 Y# n2 d6 R+ Y
}
' K1 O; _+ Y: h% W5 _. z }7 a- I3 l2 Y! o
}! E y* |" W5 X7 ? V) T
$ S7 e) V( `8 Z# _ |
|