原文% m7 Z+ Z7 O2 h& Q
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx2 ~6 }* P( X7 }) y0 c2 D
( z# v+ p, O( E& l5 @6 d) l
! |0 x Y: s6 A1 Z% z& C
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
) v# ]: j& s# G0 x: P! v: ?0 rXNA3.0+VS2008SP1下调试通过
" g1 [9 L0 n, `. G; f j由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。& l% r9 m% U( \9 M7 w0 b! j
步骤如下:1 b! I: g7 H. J% {( l* V3 z
建立字体文件, N {# a4 R4 g k, M! i
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:. d& P! S/ G2 u o
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
' T4 U7 b& A- j! j5 k8 c8 L1 n2 P7 A) V$ L" ? j
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:- C; Y& ~' h. J
[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;. x) M+ a+ t7 A
using Microsoft.Xna.Framework.Content.Pipeline;
$ e0 L" A- B$ P0 K+ Vusing Microsoft.Xna.Framework.Content.Pipeline.Graphics;
, T) _0 Z n) O( lusing Microsoft.Xna.Framework.Content.Pipeline.Processors;5 E5 m9 J# }3 R/ {
! T" T: @, K, q* |
/ e$ {# L {7 g7 P+ F) o' i
namespace FontProcessors
6 T$ e1 l9 X5 c* L% L7 ~$ M{
/ v" X& X r+ R# M [ContentProcessor]
& a9 ]0 }# u4 D7 k9 ?& [. V public class DefaultFontProcessor : FontDescriptionProcessor& j# {* q8 f# ]# m. |
{& E* x+ E+ b- J8 ~5 A. N& ]
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)* x& H% T0 }. |4 o; A8 V0 ^/ o
{
" s5 @; G8 T% I //载入文件
. F+ K a6 M, R! t/ H* ~ string fullPath = Path.GetFullPath("message.txt");( I$ y* n' {5 D5 x
context.AddDependency(fullPath);
& K* t+ P* \+ \ l* ~( G3 [ string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
8 t9 v y& J8 V! a5 r4 D* a
" W! E* g& X5 X5 p7 \, b* z0 [( a8 b6 P0 A+ T) V! {0 Y
//导入字符, w) K' w; G- G5 \9 G J+ n$ X! `# F
foreach (char c in letters)
* A, x( v5 P% ~1 }* x0 y2 G; J {; u, {" ]: {' a; N. \6 N
input.Characters.Add(c);
3 d# \8 H$ H+ T4 l. l) C( B; h }( N" |% e; y$ p Z
return base.Process(input, context);$ y. a* Z* C, J; ^( u/ f
}
( [* U6 Q& u3 y }
' `! j/ O9 H; P: ?/ r}9 a) g) U2 X7 h) T& \( f
6 q5 `& r6 k! G4 ]& U |
1 L0 h) a8 u4 m9 L* ?* f/ v' V
3 F5 |6 y+ @; r4 X添加项目引用
* u/ t, u8 s0 L7 K2 L7 m[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
+ {5 a. `' e. N" x5 ]Game1.cs | using System;
7 h, ~$ o, q( ?) N) U: F: Qusing System.Collections.Generic;
5 r7 N. d1 f V( U2 e# y0 jusing Microsoft.Xna.Framework;8 x4 W5 F+ R9 Z/ i0 U x
using Microsoft.Xna.Framework.Audio;$ Y7 n2 F; U# Z
using Microsoft.Xna.Framework.Content;
$ ~% @0 ?1 W' T* r+ ~using Microsoft.Xna.Framework.GamerServices;0 o X/ D. e! l; I
using Microsoft.Xna.Framework.Graphics;
" ^' W/ r# F! N& i4 J8 Y9 j# ^( {using Microsoft.Xna.Framework.Input;% K$ s' U; }. C0 j" @/ \! f+ r$ M
using Microsoft.Xna.Framework.Net;# J, j) B9 v" }' [# E# K
using Microsoft.Xna.Framework.Storage;' @& p+ X; @9 |! g# E+ y
7 R9 H# b# D# {% l0 t
) N; I% w. v9 l8 h+ _( f0 T! v! j
namespace HelloWorld {
# w! W- F* A" U6 v4 T& ] public class GameMain : Microsoft.Xna.Framework.Game {1 Z" u& X% {# p8 \+ E
private GraphicsDeviceManager graphics; 2 T, O( B" m* ^7 z3 ?
private SpriteBatch spriteBatch;
% t7 ]5 q! _6 Z5 E private SpriteFont font;
9 I# h7 i& p0 Y/ {5 h5 a
7 h5 U: A4 R) G' n" M4 R* y
" q5 ~0 Z- d0 Z+ j: _( r public GameMain() {! E7 ^. s# C# @
graphics=new GraphicsDeviceManager(this);
2 b4 `' b4 D7 B/ n/ ~' k" D Content.RootDirectory="Content";* g8 u; Y* U9 N# m6 o
}- ^/ K# `% b4 o9 P4 H
/ s% b) B/ M! L, g* J6 Q" J. G
4 x% j+ |, c( b
protected override void Initialize() {
) y0 o1 `: h7 s base.Initialize();
; O$ z/ I! }5 L; a }
# Z' @. s8 R6 d/ t9 n4 `2 E$ K
2 i0 }1 U( E3 U) V+ \$ Z1 v protected override void LoadContent() {2 t( U- p4 r1 Z" q( Y
spriteBatch=new SpriteBatch(GraphicsDevice);
3 P) H7 g7 [. v/ ?; C1 w font=Content.Load<SpriteFont>("DefaultFont");
: T5 V5 x2 w& @. R }# P, ~' X0 }/ s" B$ i
9 r( v0 e9 X" r9 V
$ ], u6 K( j( f
protected override void UnloadContent() {
& B2 Q, E7 \3 V' ?2 y3 r! z }
8 ^$ K6 T! Z8 u2 S2 A
1 i* B- [ Z: H1 e+ W' V
% p9 C1 F5 L4 ] protected override void Update(GameTime gameTime) {6 ^" @: t: H' r& y
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==5 m* q: v% v3 k+ W0 j m/ k
ButtonState.Pressed) {; |& g4 k" A9 F2 R: {; W0 s y
Exit();5 k3 z4 R( V- x8 l3 x7 r$ k
}
9 k$ R' c! t% ~( C5 Y @- k! o
( Q6 v9 ^/ B) l& n/ D) r5 @( {2 [- t2 Q# s
base.Update(gameTime);
3 j6 M8 H3 I, z: e5 O- | }6 H. z9 P( ~) s6 F( h/ Q
0 F) K, }, E3 x( o+ A1 a
0 H6 w) ^& f+ I) b/ ~ protected override void Draw(GameTime gameTime) {
$ T# C# o0 s4 ^; L: L, P graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
3 K" L( i3 r- @* k" H6 _1 d* D' Z/ H5 l) a
/ V2 p) ~ h0 \- n( n- ] spriteBatch.Begin();
: L3 g8 D% v0 S; ]' }) h DrawString("中文输入测试,日本語テストを入力する",50,50);1 p- m7 w( [& [
spriteBatch.End();
* c* P1 k6 V. ^) }2 H2 b/ w/ a1 s2 B" j; n, q! [$ Q3 b( ^' M
' H6 w) Y% ]1 ~) M/ b( a8 z9 p; W base.Draw(gameTime);
- {$ S! h2 A: n0 b$ J; a, K* v, u }- J' K: i% Y9 G; D5 {* i7 R2 w# D1 o: R
5 [# p/ Q0 X: L, a( M' \9 R# b* ]7 O. Y; o
private void DrawString(String str,int x,int y) {& P; ` y- R+ ^
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
) e/ M& f6 k) e* \/ g }1 D2 L) E, v6 I2 ?# z' w% W
}; L I8 a+ c* f
}
0 W$ f& v/ H6 p( o' C9 _& I* c# g$ i3 J6 D
|
|