原文0 O: f; ]# v& z/ N& [5 [
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx: B7 N; x' _- H% v( X4 W
: F$ E5 I& D: p , n+ Q% R$ u# @5 J4 q( E* E+ @
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
4 B1 R- ~6 {0 d! _XNA3.0+VS2008SP1下调试通过
+ K( \5 c3 c0 ^% ^2 y) n& d$ y由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。$ X( Z# ^0 w: g2 I7 D" D
步骤如下:
( z+ W# r0 U$ a; ^ j9 ]4 O1 f建立字体文件$ b# h; G2 \# w9 \+ E
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:
: g. r) V- {. B, _7 D) J, D- [[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
& _* z4 J# p3 X* h3 z
6 ~' @# y2 z8 \* `; j | [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:
5 k' h, t5 z' O2 ~9 H% [( K7 P' K[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;
& s; ^5 Q3 I- {- }3 S, [- @using Microsoft.Xna.Framework.Content.Pipeline;
; b' d- J. k* j! i* ^using Microsoft.Xna.Framework.Content.Pipeline.Graphics; B! ~, ]7 Q7 }# _% U5 o$ s
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
: [( d8 }6 j! s: I6 z2 q8 Q. q
2 ] i; W$ ^: w: R% L8 b
. u9 ^* ?% l# l! V, tnamespace FontProcessors" t. t, K8 X' k
{
" O& v+ o9 V! Y( E' w1 J [ContentProcessor]: ?& _8 U3 Q- R
public class DefaultFontProcessor : FontDescriptionProcessor8 y& m! J: c0 A( c
{
7 ]: M' |: L( x P- Y public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context); g* ]8 e$ ^/ ]' o5 x/ t
{
6 d1 Z0 c, M' E! [% O //载入文件
6 Z3 b9 {1 _2 b- w$ [ string fullPath = Path.GetFullPath("message.txt");1 T) q3 h, b d n% n1 K1 x! h
context.AddDependency(fullPath);
- h& ?/ _6 |$ v- ~( Q5 C. o string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
6 {6 E( |7 N" L/ c! ?0 ~: h" c* K
t: I. Y8 G5 Y0 ^# f6 `
. n9 \1 y- u% Q. Y6 W //导入字符+ D3 E' I# e9 u+ u W# S, ^! {8 Y
foreach (char c in letters)* C7 K9 a4 q% i
{0 o: J2 \: G0 J; F0 ]2 ^
input.Characters.Add(c);) ?; m- |% m* Z& O+ B; q, H/ n+ b
}
; n }. B7 y4 D% N# t return base.Process(input, context);
( n, g! E: q+ h. c8 D }! f7 @2 h6 |5 |' m6 M |' t* T& I
}0 G5 n: E' P) W+ v
}, R: U: m2 [7 m' v3 l' V0 b' s
. g( q# w! J& P6 x, m" `' \ |
- {( M% t( `% G) p
$ _1 u* t# U/ A5 h8 I" Y! O添加项目引用
2 W$ c( G" I. w/ Y[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
5 Y( Y* C( ^0 U3 L( k+ mGame1.cs | using System;
L& H" n0 d: Q! f" ?using System.Collections.Generic;
5 \. {6 Y6 N; ~; T' E8 \using Microsoft.Xna.Framework;
; ~" B X: f* X! Husing Microsoft.Xna.Framework.Audio;
' h5 A( ]7 Z5 Cusing Microsoft.Xna.Framework.Content;
! {# R3 e! s# \2 s, z* Tusing Microsoft.Xna.Framework.GamerServices;6 {) t& s0 x4 Q
using Microsoft.Xna.Framework.Graphics;8 d* `+ B- R- K/ b7 v
using Microsoft.Xna.Framework.Input;8 f6 Y/ L6 m( |# n- [7 B* |
using Microsoft.Xna.Framework.Net;
9 ~& ]# L/ d* r' F4 S# J5 Cusing Microsoft.Xna.Framework.Storage;
: Q: W- Z! U; d2 {7 L
* u, i6 v. P( m( I5 W2 m
0 C/ W, B4 j0 s& F$ b; M" x* m) V- dnamespace HelloWorld {- M1 L. s/ |: |6 K1 y1 L" [+ N
public class GameMain : Microsoft.Xna.Framework.Game {
7 e/ o! y4 p; I7 T4 T private GraphicsDeviceManager graphics;
; k9 y. f- x( |7 G9 ~# y# _" s private SpriteBatch spriteBatch;
j7 Z1 c+ i" O0 f private SpriteFont font; 9 v% Y8 Y' L# @* W) ~4 V6 q
. c/ M; t, y# Z! f5 f% `# Y
& J* c, E7 @! f4 h public GameMain() {7 p& H" q6 t* G) j
graphics=new GraphicsDeviceManager(this);0 p* S0 s7 E' R7 f" \& ^9 J1 X( @
Content.RootDirectory="Content";6 L% t+ P0 K {
}4 B: j) H- Z8 Y/ J! g6 a
; n5 L1 I% t) g6 A$ D- Q5 @; e L- K3 b! Q
protected override void Initialize() {9 S4 J5 x; S* s* k d7 d. ~
base.Initialize();
9 B; L4 W. F: @6 B. S- o: ] }
0 {2 T$ f5 v& e8 d1 j4 l
' m7 S6 \3 s. R w& T
! n/ d4 I7 Q+ |5 E8 F+ T protected override void LoadContent() {
# r2 @9 v8 r9 a1 o( M6 h/ P spriteBatch=new SpriteBatch(GraphicsDevice);
0 J7 Y7 K) k) J$ i* H font=Content.Load<SpriteFont>("DefaultFont"); D5 z- h. a, u
}2 B2 M( E6 L1 p+ A% L% j
: { q# M- A0 I7 w8 V0 Y
! Y% d G. E4 f% M
protected override void UnloadContent() {7 d" l8 `! T% @0 Q% E0 v5 r! M) {
}
$ |! @" N" H4 F
0 l4 U8 g, s: w8 W4 p
; F; R: u7 w- t" D/ W protected override void Update(GameTime gameTime) {7 Q0 m% ]# o' O! D4 t6 f$ c4 `
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==6 f" ?# q( e9 N/ K* N6 n+ J
ButtonState.Pressed) {- B g" I4 y% J9 U
Exit();9 a7 e( B( h$ k
}- r2 }9 S3 C8 ~6 ]! u3 G
! ]# ^$ B; W7 z5 i9 ^
0 H% }- P) V; z6 f
base.Update(gameTime);9 |7 @- u+ j0 \8 n+ `6 @3 }
}
" j5 w# Q A' @$ s& c) n( H5 m# H4 O" X& R) [2 ]+ f
* ]2 c: g" H4 n protected override void Draw(GameTime gameTime) {
$ R- P+ y H) \( W9 r graphics.GraphicsDevice.Clear(Color.CornflowerBlue);: y% s8 ^4 M# T
) _* W9 d7 {3 _/ x7 L8 a1 u
+ `7 I% f* `. j spriteBatch.Begin();
* \2 `0 z7 q3 k( T% g. ` DrawString("中文输入测试,日本語テストを入力する",50,50);% R1 ^3 d5 y( ], i
spriteBatch.End();& j, U' A' s* s/ d
m0 q; @7 H- I8 ?7 _ Q4 C9 N2 z A/ x
base.Draw(gameTime);
) p6 s' Y# `/ I7 i# d }
6 h6 g" s' i+ p3 w' G$ b `0 [, a3 i" m& e5 Z) l1 e( p
P% T3 ?+ F1 o% q ]1 I: j private void DrawString(String str,int x,int y) {; W( `$ A9 B6 J/ L, }1 \
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
% o: |" @5 O/ h) p }
' T- B" [; P" ~ }
2 Z' b, C: T; ^8 r6 D1 _. Y& T}0 P7 o4 c8 o C$ `' I( G B
" ~$ J' W4 w% h) @0 Y3 t% q8 v |
|