原文+ G9 w- x d( X6 n: V
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx N: x9 s/ L' H0 U) s* d
! W3 B; a! C. j % S5 \+ c3 t; \3 C$ e
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
" k n0 n, s9 y$ x J+ kXNA3.0+VS2008SP1下调试通过& _1 n8 ^9 v0 z$ | G- P8 i, r
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
9 l* p' u# q2 R1 `' l. T& @步骤如下:
% C N" x( p+ H- E+ y8 |8 C建立字体文件2 J. f' k6 e( n+ f% f% r5 i
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:, ] h7 X1 L4 u. W7 @* Q
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する- Q7 _9 r' k- f
9 }8 e2 a1 E; \) n* d. L
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:- l; [; K5 g; ^$ Q6 z. P0 e% n
[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;5 h$ V* \* P; A# f% z2 N
using Microsoft.Xna.Framework.Content.Pipeline;
0 b1 o/ h* z$ Tusing Microsoft.Xna.Framework.Content.Pipeline.Graphics;
5 @/ U1 d8 x! gusing Microsoft.Xna.Framework.Content.Pipeline.Processors;" a+ N4 B3 l6 N- ?* I5 i. D' b( m
: q* E+ Y7 H6 x8 W3 O: R) Q+ C1 ^6 \4 Z- K2 m
namespace FontProcessors
" A; J+ p! `; F# l+ f( G{
8 c$ u- s1 `9 P [ContentProcessor]' l. r1 U; Q; t- r
public class DefaultFontProcessor : FontDescriptionProcessor
) _: _/ T2 D* d8 s/ Z& z& e {
& z5 Z( W1 K; _ public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
. X7 e4 t) B L- [- k1 S4 _( Q" g {
4 F4 [) P1 M6 I) K8 d% P6 z1 Z //载入文件
; b+ q. W+ C3 F3 @; X# u0 ]* ~4 }9 _ string fullPath = Path.GetFullPath("message.txt");5 a8 h- G% K. S# n4 b A/ V" ?. E5 L
context.AddDependency(fullPath);6 m( g: c% {3 O0 U8 L% E
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
/ g, Y- R7 u- q) `) e8 ~; }& ^& r4 a# D$ S5 t
; O% r) t) t- ]' ^0 u
//导入字符- u# V+ o" ]7 f; ~) d+ Z/ X C
foreach (char c in letters)
8 F3 F P& I& t" s4 J5 ^% d {; h8 @% ~- K6 g* g/ B1 ^2 y( X* K: {- x
input.Characters.Add(c);/ H& m; Y0 m' A3 z
}
( {/ Z2 C& i) d return base.Process(input, context);
" A3 i3 {9 c s3 x" [7 t: h }
6 ~0 Z- ?. d% [& Q5 T% ^ }
: ]3 Z2 T7 l3 [- x9 c" v. ]7 p6 ~}
1 @6 t- T5 W' c6 \1 s5 f, u8 d/ l# w* N0 f9 ]' c' E) [5 w
| 7 _" p7 c- B# ]: J% w- T/ T* p: ~! z8 @
1 L, u" |2 u. ~, }; j
添加项目引用! |$ u! ~& ]! T& p
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
+ X) D6 y. I2 W Q2 qGame1.cs | using System;
* @7 u+ q" d6 D( M4 ?+ Dusing System.Collections.Generic;
/ |! Q' ?% I/ v# x; Z/ pusing Microsoft.Xna.Framework;0 a2 G R$ o* R; T0 Y; i# _% L0 \
using Microsoft.Xna.Framework.Audio;* n2 i5 Y: J( z* t, M& S) W
using Microsoft.Xna.Framework.Content;$ V" q" y* |' i6 z6 L2 X
using Microsoft.Xna.Framework.GamerServices;
! L% w, w9 d, p! B: Xusing Microsoft.Xna.Framework.Graphics;
# B, x2 B7 B, y' _% k, musing Microsoft.Xna.Framework.Input;
" R+ ^2 p) B J3 n4 A# V" X/ rusing Microsoft.Xna.Framework.Net;/ |7 E/ J! R. d
using Microsoft.Xna.Framework.Storage;2 z4 R0 x) F% C1 N) U4 E
6 ^6 E+ T# x' H; |2 R: Z3 C0 D% Z- {: A% ^
namespace HelloWorld {
$ K: H/ K# G4 E- \! W* N public class GameMain : Microsoft.Xna.Framework.Game {
7 | `% @2 O$ B+ B" h# x; a private GraphicsDeviceManager graphics; ! Z7 w& P3 ~8 a3 H
private SpriteBatch spriteBatch;$ u* G, Q" D. w; O" L
private SpriteFont font; / @( [ g4 F/ V( {
M0 K+ x+ K$ s
2 \+ V0 x* F4 n/ [/ f9 J
public GameMain() {( |5 d) [6 J5 ?' N0 |: d J* D$ W+ U
graphics=new GraphicsDeviceManager(this);
! }; d1 o/ ^3 O! ?6 d Content.RootDirectory="Content";
5 ]0 W. w% z' Y5 e# e }
6 i0 J2 A+ p) M9 `6 p- }4 g' `4 q3 \ v. l0 f
4 _9 S h# q9 ]! t. x' e, k, ^
protected override void Initialize() {
* S! E" J, G; A+ ]2 w) e base.Initialize();1 V4 W( Q% s, `4 @# V$ G( t+ H* Z5 V
}1 e+ w/ L' e4 w, \" l W! E1 ~
) A6 V+ d/ M' p W% c! y2 G1 X
* a2 \0 D3 [* s" f5 U+ ]: K protected override void LoadContent() {- i, P/ p4 y3 p# j' l+ E7 l7 Q
spriteBatch=new SpriteBatch(GraphicsDevice);
* }: ^7 g* ]" K: R font=Content.Load<SpriteFont>("DefaultFont");; y% z! ^* K/ T) |
}% R/ K* q+ V* }1 p2 |& ~
- Y* I- }- Z6 s3 M
: i6 ~. \1 |3 M/ t4 X: o5 S7 K B4 m protected override void UnloadContent() {0 b3 j! V2 f& E2 q
}
8 G' V5 J; |0 S" a; Y, v4 \3 z9 J2 b) T: o# L
& y' d6 c s8 V3 b protected override void Update(GameTime gameTime) {& |8 b! d% P' E$ i$ ~
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==+ S$ _* l8 T+ _( \: I; v2 W
ButtonState.Pressed) {' C! b. h) S7 N6 W
Exit();' D2 d4 z$ Q- l- M% {6 n; G4 s, G( b- R
}
2 H* F2 G3 u7 W0 E/ f
8 ?7 O% v* l I
- e3 I2 A J* Y7 h. H- h: C" [: g base.Update(gameTime);/ s3 ^0 m, h- K
}) Y3 _ @6 g1 a8 k, |4 o
$ {: b3 w+ @' r
4 [# ]3 h3 ]: ]8 }; C5 p protected override void Draw(GameTime gameTime) {
6 O8 j; w; g$ A! @7 T0 y graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
* R, P4 `- Q6 U, i) T& K$ r$ N4 j E4 c& p2 c
" Y8 f# c. E/ ~% T4 D$ V$ a spriteBatch.Begin();; |5 }' I* h. ]5 M* A
DrawString("中文输入测试,日本語テストを入力する",50,50);) w& Z& F Q# a5 B4 o) s: ~
spriteBatch.End();% B1 W% C! c( v ^* x& H2 Q
! E3 p: I, ~$ W8 N, t$ \5 I5 K
( }; k# O: ~$ ~! |, r2 E base.Draw(gameTime);
$ i' A! ?3 Q! Y- m9 b" b3 L }
' s" S) K0 F7 S9 w2 O9 @3 r4 V6 T# @: _( E% ]
: P; t0 N/ `( o0 c2 A7 h private void DrawString(String str,int x,int y) {
) S* R! ?! J# \, }$ P spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
( r( V8 w. {1 }2 v2 ^1 v- V$ q+ V, m$ q }
9 q# \7 ?9 A" ~; z p c: Q" j }
' ]1 m1 e4 _' x" @}
" [6 W. C' _) l. E% L$ w9 B
- T2 p5 j8 h4 l" I! Y* M, G |
|