原文9 }7 K, ~ f) K
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
& d( o2 v, { i# O4 c( ~& i4 }
7 w! E/ k0 }5 z l! T' Q0 }# l
9 [* {+ ^' ` u- y, n5 V! |在XNA中显示中文字符或其它UNICODE字符(非GDI+)3 S( b2 n U( g+ r7 J$ G
XNA3.0+VS2008SP1下调试通过& V* o% A& b- {: ~( o
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
$ h$ V* V) R+ m" ]3 Q步骤如下:
; H/ t" ]8 H7 p" B1 K9 Z G建立字体文件9 i {; P9 F$ h$ i5 Q$ _+ |: ]
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:2 D4 ?* ?6 R: X5 i, U: `+ }# G _
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
& _6 u% j7 x2 k$ t( M+ Q$ b# }( ?& A8 _4 b2 u$ h8 M' u0 u m
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:- X# o$ t4 t, @! x! Q. p/ h" d
[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;0 o, N6 Z5 L- g( e
using Microsoft.Xna.Framework.Content.Pipeline;
& ?; G) j; s8 M9 p3 G4 zusing Microsoft.Xna.Framework.Content.Pipeline.Graphics; }# ^) K" J: ]' Q6 n9 z6 R" }
using Microsoft.Xna.Framework.Content.Pipeline.Processors;8 g, U: ?: ^ Q# N
7 I* [5 W8 D, J% w
3 D! T. l6 @+ Z2 Vnamespace FontProcessors
5 D1 Q7 ?3 G1 ^' F: y& Z& L* b{
0 x( i, x( A- |) [9 E [ContentProcessor]
4 K# a! g: A4 r! s$ R2 J% t public class DefaultFontProcessor : FontDescriptionProcessor
: l- N% G3 D: ^' G {
* ?; E: e. H9 y, D1 S' O! m public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
- F, v) }( E; E& f% | { G" o$ v" s: n2 x) E
//载入文件
# n3 C+ u% ~* G string fullPath = Path.GetFullPath("message.txt");
4 p4 v) l8 B, D5 P4 ?: P+ n context.AddDependency(fullPath);& V% y% q' h+ E
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
4 X9 {0 x3 m, b% E; y+ O% q1 M
, L0 {7 v. ~8 p0 D7 D0 w/ \: y" Y# E4 M+ z! Y
//导入字符) T6 \- `8 @& F! F8 R5 [0 G
foreach (char c in letters)
$ K1 o9 Q: ?: d6 g1 j' U {1 |' N; y) R$ l# z( u- Z! T
input.Characters.Add(c);
# a3 d L; E, v8 J7 K9 i0 M }/ f6 }. D& h' X( y% j9 H, r' ?7 `
return base.Process(input, context);
2 C6 a3 z( \4 i: m: t( M: z }
! g6 m4 O Z5 }; \8 ^ }! I l$ q0 k* X' f& `9 ^+ d3 ^: Z
}% A! D( ~$ ^, n1 Q3 L7 A+ H
5 ~+ W6 I; S y# h- d" H2 M! |
|
+ o% l8 h5 V- g, }
8 l. K5 F' }8 T5 L* r, W添加项目引用 P! O: i, W- ?
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
i" }6 E( i* U0 i3 oGame1.cs | using System;
# [7 ]; Z8 l P7 o# H( |using System.Collections.Generic;0 G- |3 V0 E4 v; D$ ^$ c
using Microsoft.Xna.Framework;
3 r7 Y) R% O- U, t% A' musing Microsoft.Xna.Framework.Audio;" k }7 g& \$ H8 M# a, w( M
using Microsoft.Xna.Framework.Content;: U3 T5 q! y6 c; K! G% f
using Microsoft.Xna.Framework.GamerServices;& e5 k0 y& G1 G1 i
using Microsoft.Xna.Framework.Graphics;' l6 o9 E6 t/ P" ~
using Microsoft.Xna.Framework.Input;7 `- [5 R( ^7 \( X! x+ p# f9 j; n
using Microsoft.Xna.Framework.Net;: N! _" L- O2 x9 G
using Microsoft.Xna.Framework.Storage;
5 j1 b) z: |4 j6 C+ s. m1 s. V; H1 W$ C0 d7 E
2 S. m. W4 d: U& ? y
namespace HelloWorld {0 M) c2 I" E: ^6 o' X, f4 I
public class GameMain : Microsoft.Xna.Framework.Game {5 Z: L( E$ x+ ?6 P7 F& ]
private GraphicsDeviceManager graphics;
7 H J' q0 `: _4 ` private SpriteBatch spriteBatch;! P7 d9 ~; d' w' j' ^0 @6 P
private SpriteFont font;
. q2 A D0 P+ I
' m; A* W8 h# E2 K2 `8 ~
, {9 r: u7 S& ]4 w/ H% F n public GameMain() {5 Z6 r0 b! f4 z: T
graphics=new GraphicsDeviceManager(this);
& w( P& n' G) \8 k( ?- t% w Content.RootDirectory="Content";( r7 p" v, k2 M# S9 K: J/ C& C
}# |: |1 j: O: [9 _
|2 k8 b5 A7 M+ e: R" C" [1 N0 w) i1 _
protected override void Initialize() {+ ?" B# G5 d H- A, W
base.Initialize();2 l. ]1 y3 I3 j e1 R
}- q. M5 b0 j1 d# k% I& A
" y. r( d- d% o# z. ~$ Y! h" C6 b B- P* g7 x5 k+ u
protected override void LoadContent() {' O+ j$ K1 z! R, S4 v2 C1 c$ Z3 }! c) W
spriteBatch=new SpriteBatch(GraphicsDevice);: H2 R! {- k- x _; S6 q2 J0 e( b
font=Content.Load<SpriteFont>("DefaultFont");
% b( C/ W4 s! N; y7 i3 C) n }
; X' K# X' o1 Z9 T. X: [
1 ?* W+ J8 I5 v1 ]0 b( U' e$ @ W( R( f
protected override void UnloadContent() {0 `" C" F# n! W
}" u+ Y8 |7 y- b/ Y: H" u1 `/ P
. _+ p/ X9 Q- S1 ]/ ?* |. Y
6 d: Z/ W( \. u6 T. I, j* D' R# B1 I4 o protected override void Update(GameTime gameTime) {! f8 P. M l9 l7 y7 B W$ R l
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==2 A* e( n3 E9 j" t+ [- D) H
ButtonState.Pressed) {( D3 E0 F. f' O" j( |6 I+ F, c
Exit();
/ R5 H+ U5 C; O0 G1 j }
, w# H+ ?) r; y& x4 [
) n. z% j! L: t, c; j0 K7 p; M9 D4 p' M
base.Update(gameTime);
% D& R& _* B6 P t }
' D% G% Y$ O, k& L2 K r5 @$ A" r9 |% k+ I6 i9 M1 ~8 }
! P* |( Q. \2 V# S" ?
protected override void Draw(GameTime gameTime) {- }/ K8 `5 u2 Q) i6 [6 T
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);! r" @+ T+ X* m9 P. l2 D
1 ^% I0 A/ j$ Z i& ?' i0 B* m! a
* v# w9 z' A7 V7 F+ P spriteBatch.Begin();% y9 v7 v" M$ S4 y2 Y
DrawString("中文输入测试,日本語テストを入力する",50,50);+ w' ]9 C/ d' b* D4 c8 m" x; r
spriteBatch.End();
8 h% J; l) A+ J) ~% e0 U. V
9 O ~: }$ w- E% \1 T: J" {( Y! @( U- |1 m, W3 G) s3 v
base.Draw(gameTime);- B& M5 Z: f- {, h6 g; Z( y
}
7 I1 F5 M& ]$ F
3 N% ~8 M- r" ?' H
# u/ @4 E; Z- \6 [; ? private void DrawString(String str,int x,int y) {7 ?( ]7 L: O5 J6 j8 B; E5 w, W
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);
a; I( S3 x, |) G0 k( ~ }, [7 E3 N& ?* B" b* A7 E
}
' T; x; c, F: V}2 {0 {1 j9 D9 a2 }7 n
7 V" d4 M H% C4 U+ Q y. y2 M& [
|
|