原文
o* z2 T$ _4 ]* g5 N# T6 ghttp://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
5 P L8 { R5 l% q( |' h- e' v O9 p+ F* M8 Q. y) X
1 { ?7 V& L, a9 A
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
/ K) I) v' j0 F o. iXNA3.0+VS2008SP1下调试通过
- w+ a# e3 L7 h4 p6 a' f由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。! w' H3 e# U* ^5 {3 p }9 _( Q9 @& J
步骤如下:" R' }) O9 t: v
建立字体文件, s& c7 X* N1 O @5 Q
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:- ^: k% C1 n" z
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する* X7 }- J U0 m
0 L; q+ ]3 }9 X) S( P | [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:5 T* x( W1 m: U1 p1 [+ L" e
[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;( l! K6 N: E. E) k
using Microsoft.Xna.Framework.Content.Pipeline;
. [9 `; u9 `; a2 t7 V t3 ausing Microsoft.Xna.Framework.Content.Pipeline.Graphics;# H8 ?. `+ j5 A- S1 D/ l
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
' W; [; _) n+ F7 p5 h- k* y# Z+ h
: C0 c* t; d8 y& {8 c
0 @1 B! h) N) p' u4 C. N! Enamespace FontProcessors
* l% B4 q; D+ C; _# }5 P{* \+ F3 k7 B) `1 S5 ?
[ContentProcessor]# V& S: G# d z+ d# @2 ?
public class DefaultFontProcessor : FontDescriptionProcessor9 T5 F6 k- H3 s; `: Z) X
{; o/ h" Y* n, i8 b& z
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
& `0 M8 f& U" m: X2 z {
$ A8 S; V& f X% \2 ` //载入文件9 r. G F1 {* {0 @) ]
string fullPath = Path.GetFullPath("message.txt");
3 ?' V: s4 V7 q6 {& Y9 F% ^& ?% g context.AddDependency(fullPath);
" k4 _8 E+ _) g9 F6 J& [ string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
7 Z! B' {3 B$ ] }6 [
8 l( o: z4 |3 C9 V( d
+ Q+ E: l( z& Q! c$ } //导入字符
4 h* S- o" c+ K r, M foreach (char c in letters)
* N1 X6 Y% p" H" O0 N" j0 {0 d: K {
8 s' A% m" J# b% T. j& [ input.Characters.Add(c);
' o8 s, F6 Q# a/ U }
6 g7 c8 `" w- z1 ^& Y, K return base.Process(input, context);
9 G1 B! K3 P, \; ~9 p( ` }0 Z) P% X9 f8 g2 e5 I
}( ~7 K* n- M- q; y* ]
}
6 b: v1 r! P% @8 g& C
/ \( U; [; z) ?0 J9 z | - ~0 T: |0 ]( X1 E: y
! b5 h, S9 u+ W2 R/ ^0 D4 o添加项目引用
- E7 j( s0 Z. B! I[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用5 T+ y8 d: \1 s; W$ ]# ^
Game1.cs | using System;
9 W$ j5 T6 L7 z6 [using System.Collections.Generic;9 ]) o; [, A& i
using Microsoft.Xna.Framework;$ i! K* ]2 w; \% u2 B1 H. ` E
using Microsoft.Xna.Framework.Audio;+ V* |' B9 c3 A4 a; @2 c
using Microsoft.Xna.Framework.Content;+ O! j) `5 M3 y9 I
using Microsoft.Xna.Framework.GamerServices;
: N3 v4 o( y$ K# V( {! R7 c! [using Microsoft.Xna.Framework.Graphics;
) D0 ~: C6 V# R% H3 q% F7 xusing Microsoft.Xna.Framework.Input;3 I1 B) Z8 K& R- V* y9 p
using Microsoft.Xna.Framework.Net;3 x1 o* S* s G& j" n/ s! A( D2 ]
using Microsoft.Xna.Framework.Storage;
( g7 _6 D/ w, c) Z; g) |1 o) O3 W* Y3 Y! H
: i; R) ^8 T& j8 Y0 a/ ynamespace HelloWorld {3 h5 y4 K+ H: x: m0 d
public class GameMain : Microsoft.Xna.Framework.Game {
) j$ z" q7 K6 @' X$ A" V' z private GraphicsDeviceManager graphics;
U C/ {6 o8 _; B$ G6 [ private SpriteBatch spriteBatch;
, u2 X6 s2 Y8 c8 J. @3 w private SpriteFont font; : D. e5 `; q0 [' r8 g7 M
3 B/ l0 \4 L+ E) g( g* i5 w9 ?+ b4 c) w) A
public GameMain() {
' [1 k8 G9 b' r4 D3 Q graphics=new GraphicsDeviceManager(this);" x8 D- P3 B; y0 U- d% S
Content.RootDirectory="Content";- X1 W, g& k* M2 r: z& [ O
}# `. c; U& F$ d% ~; y/ q. Q
, M1 i# S% I; Q. l; W
^: N) U6 g# U( I" D9 v5 p protected override void Initialize() {
; S9 z0 i6 k2 t/ U5 `# Q base.Initialize();% l' r- ~) A2 d; [' u4 y
}. U) `: h0 E2 [2 r& R$ {" B+ Z8 h% u! F, C
1 I/ p* |: b- Y: y! q( i3 T
9 N" m# i3 o+ m6 U: y( ?" H/ e protected override void LoadContent() {
( U: D$ x$ O8 a0 \, ]3 ]( ^ spriteBatch=new SpriteBatch(GraphicsDevice);
1 K( ~+ ^' `4 I* | font=Content.Load<SpriteFont>("DefaultFont");8 A# U2 v& J0 E$ m! Z* U, C0 d
}$ }& f: u# M$ y) D$ x
0 E4 O' B7 s6 r0 n
& |3 ~! H5 J! Z protected override void UnloadContent() {
& u! ?6 @0 Z3 K6 n% B- f0 p }
' \3 A7 t! z3 |8 W+ g( @5 _ z) E$ s
% a. S1 ]2 w7 T! @* } protected override void Update(GameTime gameTime) {
7 }# }( @1 g, b) f$ S* t if (GamePad.GetState(PlayerIndex.One).Buttons.Back==
( C5 }. T4 [0 t! L2 T ButtonState.Pressed) {- j$ G* K3 p$ G9 L4 U; O8 A, q
Exit();
, q2 G9 k5 z; `6 G }
/ P9 h0 R5 Z7 d" P( y% f0 E5 i
; K/ m" R Z# f0 f' }2 x1 r6 I% V( d: q) c
base.Update(gameTime);
" p$ T( v @3 i& x# r9 K. p) \ }
+ }& m# k( }% x1 n( f5 c. c
; l3 L/ X+ M7 V: r1 b8 k
7 y! Y1 U$ W2 T7 V protected override void Draw(GameTime gameTime) {+ w+ V. T" d1 t5 F- b
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);+ }0 ]9 o; Q* j& ^2 N
3 ?" [+ d6 G$ T6 B( f3 W. l
0 z( Z0 [# }, t% `
spriteBatch.Begin();
4 [% J- l0 a4 S& e- u( @ DrawString("中文输入测试,日本語テストを入力する",50,50);
2 S* J' p- n( Y5 i& \2 I X spriteBatch.End();
2 }7 a) I- h, L6 [$ a
( a8 U0 k0 _0 v1 i# A$ H* P# I8 [: o# p3 ]# {- A7 {8 E9 Q: z; L
base.Draw(gameTime);
7 \3 I+ j- U* z8 a9 u }
* }2 c! x9 v! q( j) q# U' L, t7 N6 k8 D# v
; E7 j0 G8 C* G. T7 f. H
private void DrawString(String str,int x,int y) { e, Z) Q2 ]! c0 f3 a9 ?0 A
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
/ H- S5 z' P( B/ S( U) l2 H }
8 T, R3 [7 Q* X }( O, L r' e' ^8 O" U2 C( P S2 E
}
- A. w: w* p2 l3 X6 g
3 x% s; a7 @5 _$ N# r2 R$ @ |
|