原文) H; h# j; P8 f# p( E8 ?8 f
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx) C$ r3 z2 i' F% Q* D( X
7 H6 ^0 t- G [
$ _- v7 w6 f; S1 c
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
9 P- O. p; d2 R) M7 C6 X3 \XNA3.0+VS2008SP1下调试通过
- V* ^5 ~% S4 U由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
+ g. f6 I7 s! l- q* V1 z! R1 [步骤如下:0 G7 m+ p# M5 R' o
建立字体文件
7 a; [* h3 j$ k[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:" a- u% ~: _ T# q% [8 ^# s
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する" F: q* r F( i2 F% ^( P$ Z
9 \% W/ L! ^6 i& ]! N
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:
0 h# C) s) ?: E4 Y9 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;
+ p5 }* `( q& Q V0 pusing Microsoft.Xna.Framework.Content.Pipeline;) \8 Y6 g7 M3 p. `
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
7 n7 s4 ]3 A! {( D( Rusing Microsoft.Xna.Framework.Content.Pipeline.Processors;, O3 p/ I1 J" x! H* B) Y
; \! L: M- U; K! x9 }
+ J* I+ V4 ~) n; l; W1 Cnamespace FontProcessors
3 X' c* `; n) a- N{* G! ?7 m# L. U4 T/ p5 j% Y3 q
[ContentProcessor]6 Z$ ]6 N9 @& \% }, h" A M3 W; ]
public class DefaultFontProcessor : FontDescriptionProcessor5 A. S/ f, o) H
{
, n" r) J) |5 b, A# d- R. V$ N$ t public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)- f5 p* s9 l6 _4 \+ O
{) }+ m. a3 H/ T! A
//载入文件2 s' H1 [$ t( N; U2 X/ t
string fullPath = Path.GetFullPath("message.txt");
& c; ?( J4 Y0 J3 W; M% I context.AddDependency(fullPath);
1 M8 N+ T! Y3 {; p( ]* I, y string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);! G6 y B- N( z- i8 {
2 C# Z2 ~3 {0 V; D7 o* Q4 ^) ~; O- S3 C+ u: z) e2 J
//导入字符
6 N* K+ A+ @; s6 j foreach (char c in letters)) G& }: w( ]9 ?: ^$ _
{4 T u' l6 V% L* V$ p0 A
input.Characters.Add(c);% S! D& u' @0 r
}* z- O& `) f! w, N* w i2 |
return base.Process(input, context);( i5 t. a$ `8 X& ]" @8 `
}; {1 J! s" O; |0 T
}: U- f9 ~2 ]$ p1 ^3 N
}
& P3 j# L+ J" C# t6 D& r9 n/ z( ?4 N
|
$ Y! H1 D: J" I1 `4 z
4 P9 u3 k3 ~/ q9 h添加项目引用
7 j. u8 V" ^8 d) n- Q) r- ?# n4 x[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用* ~2 l: I) y& K/ }% t9 B
Game1.cs | using System;3 B% Y) d# }3 E$ G
using System.Collections.Generic;! A4 M" I: Y. k
using Microsoft.Xna.Framework;: {* k" o" X4 }8 ~. @5 I0 Y
using Microsoft.Xna.Framework.Audio;
; k* g( [2 Z/ w6 yusing Microsoft.Xna.Framework.Content;* R2 U U7 L5 A9 u% U
using Microsoft.Xna.Framework.GamerServices;: h! ?5 b: z9 d
using Microsoft.Xna.Framework.Graphics;
- [. i- I% f5 x0 N( [6 \$ Susing Microsoft.Xna.Framework.Input;
: T/ |( y; }7 R9 e- B4 e; J- Vusing Microsoft.Xna.Framework.Net;
5 v: f- N( \# z9 | Ausing Microsoft.Xna.Framework.Storage;
' `/ e8 m, c4 j }8 e" H$ F$ [( A* U. T4 P+ Z! x/ Y9 M
2 m. m% s4 o7 ]: c0 R! tnamespace HelloWorld {+ r: a" A- c: y; S# |& E" W m/ H
public class GameMain : Microsoft.Xna.Framework.Game {
0 N) H1 A9 `- K& K, i private GraphicsDeviceManager graphics; : ]* Z& n. f; L. ~" f# w C
private SpriteBatch spriteBatch;6 |8 G$ }' b8 d; @8 b/ y
private SpriteFont font;
) P, b( V1 c4 f, w, J- o2 X6 A# }: m% r+ d2 L
: G; b6 n" I: ?7 S- i( \ public GameMain() {
% K. U, C* n# I graphics=new GraphicsDeviceManager(this);/ A) m' F& t8 |# r: h
Content.RootDirectory="Content";% e3 b4 X) F0 E0 z
}" A. s% p/ c! S$ I. u& n
/ {8 M# ~4 O* K: B F6 d) x. |& E
3 h0 z! Y) |, x6 _# o& p1 @; l
protected override void Initialize() {1 Q9 k2 o U/ X3 {4 v
base.Initialize();
7 Z) Q h% A% x. f! d9 |+ e3 _ }
3 K& r) T6 F2 C% W
. _- ~( Y" S, w# I: i$ n2 Q
$ ~& k/ R1 E1 z: }; R protected override void LoadContent() { o& z) Y& H6 k) w6 q/ C
spriteBatch=new SpriteBatch(GraphicsDevice);
) \& y" g2 U6 ?# E1 I( ?7 J' j font=Content.Load<SpriteFont>("DefaultFont");6 O% s( w& L% f/ W6 R6 c
}
" f# P0 }" E) o- p5 D/ \9 V2 C' Z Y5 d& u1 C
# M0 b4 ~4 i4 P" t2 p3 v: t
protected override void UnloadContent() {
8 l2 h# y- G. }8 l: r" Y }) w8 Q k2 Q5 q. i3 R- e
2 l0 Q- d! b/ V0 i6 M% B$ q- x: p- A
protected override void Update(GameTime gameTime) {
% k) V* F! o D$ F* @; ?* y if (GamePad.GetState(PlayerIndex.One).Buttons.Back==: U( U W, s/ k4 _
ButtonState.Pressed) {
& I. K! h' X- x Exit();
2 Z8 u! D9 f6 C, Q6 A# ^ }* t# m! ]+ R: _8 @- `! t4 r
h, p; g) N t+ a) {2 V
5 k/ Z/ t7 x) B2 M3 O
base.Update(gameTime);- D4 g$ p$ }# m, m* |, M
}5 S1 Z3 W; Q8 R: E4 K5 i
/ Z# P# _! Z, ~8 _ F: Y# H
+ n9 Z9 x; Z H/ q' z, N protected override void Draw(GameTime gameTime) {4 ?; S( s4 ^& I4 W+ Q' E5 U
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
" _& ~1 q L' e/ s. ], d- ?: P3 V. U: ~" i
* ?- _3 J* v+ p4 R. o. T. R5 F/ k6 F
spriteBatch.Begin();
) s; @! L4 g. q* q! A! W DrawString("中文输入测试,日本語テストを入力する",50,50);
' @8 N6 A% u, ^/ S- {) `$ f spriteBatch.End();. `5 |- k- V3 x3 j7 _ \
% n/ T4 l3 ]6 D7 w" S6 M' ~' K% i
& d' |- ?- a! V) E: ]& Q) E) Y base.Draw(gameTime);
; J) I, M9 [, h. `% \4 i1 Q1 I* b1 l6 k }0 {0 b! d* `' A/ C7 \: Z
0 h& X# \$ \. U2 r9 |4 J! b' d
/ _9 R& U4 p# }9 r
private void DrawString(String str,int x,int y) {
2 A8 {: ]' t" U spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
- y4 Z/ R) ^/ H# l# D# b }
3 D/ ~5 U1 K) J8 t6 [- I }
7 t* l$ d, P7 Z5 R+ U0 }4 l, M* w: Y6 {}
0 O3 b. R' ]4 A: c8 }' P c8 H9 ]' s8 i7 p; H5 Q- p! b# z( u
|
|