原文
" a3 h* S3 p3 ]1 P( O8 k% Khttp://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
; q4 T& A$ t6 ]. d! i7 a4 L6 C1 A) E. I# W7 Z8 g
& ^5 c# Z& F3 |. x& ~' D! ~8 @8 U
在XNA中显示中文字符或其它UNICODE字符(非GDI+)( @- H1 K: a. c, ]% g, p" Y
XNA3.0+VS2008SP1下调试通过6 _6 c! Y% n) N- W
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
$ `& @9 L, }* s步骤如下:) `' Q' R' @+ [3 A3 P
建立字体文件: u) Y, p o, s7 z( N: j
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:% K& B5 B, k' Y% g( r" G
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する
( o! v+ e2 w: E+ N& T2 R
G) ?4 F. a; B, o | [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:: w2 ?( A+ v8 ^2 e; y1 f8 M% P$ 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;
* v) T( F z8 [& g7 _8 eusing Microsoft.Xna.Framework.Content.Pipeline;
4 B1 P2 T) z' e, e. ~using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
* V( t' H6 k z* T7 n& C' P( V. ausing Microsoft.Xna.Framework.Content.Pipeline.Processors;
& v: H4 X: B! V0 B/ @# n. K
5 \& U* J9 ~: r5 e( L; ]/ M
0 x" c: n( l& C+ z( Wnamespace FontProcessors; s" S+ L9 f- Y, F
{
% h% n- E. q1 d$ @5 M, C1 { [ContentProcessor]
3 L$ [1 A/ l, H& l, C8 c; u public class DefaultFontProcessor : FontDescriptionProcessor
+ A9 y+ H; M5 q9 y( D2 p0 K7 f {4 j% a& V# s/ {( c
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)) {$ p, {, {) H b% S$ n1 C
{6 p/ v7 Z, a. {- L5 n- K
//载入文件
3 H+ W" y, R9 I/ y* c7 | string fullPath = Path.GetFullPath("message.txt");
+ X1 }* l" V' A8 A( u/ J* w context.AddDependency(fullPath);9 w- M+ i3 {0 g9 \- h
string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
: L3 z# Z( L" }% \) { B* }/ Z' j+ b' N# P8 b% @+ l( n
9 b7 P/ r3 o7 Y6 ~
//导入字符/ o2 A0 d" J3 X# m
foreach (char c in letters)& _3 ^3 f; o! J& h
{
7 @/ R6 {5 k6 i input.Characters.Add(c);: I, `* u; P" v' k; T: N$ f
}) m; _6 f+ B, O6 `3 K7 o
return base.Process(input, context);$ S; Y( s9 Y" d+ p. J0 Q1 }
}4 L" g6 x4 H& _0 `4 \; b
}
% Z8 {8 L1 ?, r5 U; w% A# f}2 h. T/ a2 n6 q- L- _
4 L$ m. v6 e1 k8 Y" \# {
|
( N# C) L1 t% r0 t% P5 v# `1 L$ ~7 y8 e
添加项目引用1 h2 E& E/ {2 i
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
8 y; \5 [1 B0 v% B ]7 L XGame1.cs | using System;
9 a& H7 q! D( `& B" yusing System.Collections.Generic;5 j8 S; I3 W$ E) t: ~' t( ~
using Microsoft.Xna.Framework;
- h9 T/ M) K/ x* jusing Microsoft.Xna.Framework.Audio;
# A% E- {0 q& qusing Microsoft.Xna.Framework.Content;
( g: t# x! q# U9 ausing Microsoft.Xna.Framework.GamerServices;
9 ?5 p @" N5 O8 I8 X! C& yusing Microsoft.Xna.Framework.Graphics;
% o. J7 V0 E- R' ?, }using Microsoft.Xna.Framework.Input;
7 Q& ?. X0 I* w" busing Microsoft.Xna.Framework.Net;6 d9 _4 d; S: n8 Q3 n: l2 A
using Microsoft.Xna.Framework.Storage;
( g S4 L( K- C! s5 | F% i- z5 x B! S: m r
4 N/ }9 U. `: t. `; Inamespace HelloWorld {
. m* Q5 Z9 |! Y# c: r& p( |3 f public class GameMain : Microsoft.Xna.Framework.Game {
6 Y/ v6 L* W* H, H. y# d private GraphicsDeviceManager graphics;
3 r3 v, C/ {- T/ i1 g private SpriteBatch spriteBatch;+ ?8 P# ^0 I+ n+ K
private SpriteFont font; 9 H( w2 R* Z" q* M. J0 b
6 N. S4 q I0 S2 k( R, }+ X: O$ |" `9 f, r7 K; B9 f
public GameMain() {6 H7 n9 |1 b8 r! H' w$ t) p8 ^
graphics=new GraphicsDeviceManager(this);
& `- v5 [2 m4 t* T5 z& u. R Content.RootDirectory="Content";
" ]! s" e S- n6 ]$ ` }
) l/ w& N9 h8 ~, l6 B7 m9 O" ^8 c: s" j& y5 Z7 _/ M
7 T% f6 n2 D+ C5 b( @ [ protected override void Initialize() {
. M' G% ?" J0 S5 a d h# g. }8 b base.Initialize();
; I. O) G9 z% L( |! Q1 c }
- f: y% q( V/ f2 t( [5 W, K) [
$ V6 C: J# }( w5 e: P) H+ f1 v7 ~; k- n8 u) V
protected override void LoadContent() {4 u8 }# D% ~; S3 o" s9 x
spriteBatch=new SpriteBatch(GraphicsDevice);
h3 b4 r9 m& C font=Content.Load<SpriteFont>("DefaultFont");
. i' i$ i# D, K; h }
- P- ?4 \: z) A
$ l8 @; i+ E7 ?. v) n0 b6 \6 p# ]& @1 V
protected override void UnloadContent() {8 g# l. s' I7 E9 c' i1 X- O' H
}' `/ i2 c% q X M
( B/ E! Q2 u! t3 s9 j% E! `8 v
* T# Y3 Q' V% S protected override void Update(GameTime gameTime) {
8 h0 s7 v/ h1 C, P d* k1 [' D if (GamePad.GetState(PlayerIndex.One).Buttons.Back==/ C$ q! P' [/ y2 V% `
ButtonState.Pressed) {) H: t+ {+ f% ]4 l
Exit();
( J: n' C, X& g2 i, J$ P2 X }
3 j9 T6 e9 c1 m" l w, [, b5 k4 i
9 b) {! j4 |6 y" G; K1 W+ b) L' P! S& G$ _! C) B
base.Update(gameTime);: [8 G7 \$ ]& w* T% y1 c$ y
}! ~( _0 x2 u1 F4 H5 H' I
" G0 s9 |' F" N/ m' n9 d0 [
4 q% ^/ [* O; b# \$ V6 U1 K protected override void Draw(GameTime gameTime) {# ~ n* X0 G6 q5 F( }
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
6 G/ [ l" [" I6 T. F* y! X+ I! p. ~) S3 O; U. _; J* X
& ~* m0 c% V- F spriteBatch.Begin();* d& @1 Z; [' G7 b
DrawString("中文输入测试,日本語テストを入力する",50,50);4 Q$ u0 ^8 o5 ?" q+ H2 Q% _5 |7 o; y2 b# _
spriteBatch.End();
& d9 f- v' X3 |5 @9 v. d0 o" c5 M" y8 Z& X
$ x$ f+ W# O0 g3 V
base.Draw(gameTime);
/ L# T- J n! C$ \) F" U }$ ?- I, l- m* T$ p( k# z) z
3 t0 ~8 c+ |. u6 i3 {8 |8 U7 \# J# J5 L- ?: q& W6 C+ k4 l
private void DrawString(String str,int x,int y) {
6 B8 S6 w5 c* z- S) @ spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);5 N/ H2 @ N/ N( {4 f' ~7 Q* U
}& R$ m. Q& ^) t. n
}! t5 `' E+ P6 z1 k6 Z P1 x3 P
}1 m* _7 U5 | \2 `/ a5 u, f
, @2 y) _7 P: U* i* v4 u. V8 b. r
|
|