原文5 c4 j0 _8 q. ]& R8 l+ t4 L$ r
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
4 [+ K5 l9 F9 Q' q+ M9 d2 F D
8 i' p5 H6 r' V8 }$ n9 {+ X) h
1 S9 G; x" S `- O- W& P在XNA中显示中文字符或其它UNICODE字符(非GDI+); \6 t; p% R9 U4 k, Z2 V: M7 A8 e! R
XNA3.0+VS2008SP1下调试通过
& W9 w6 Z3 l% A8 G; P0 w由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。
; E8 h5 F0 w' E2 A步骤如下:
% h' v1 T( o9 {# p ~建立字体文件5 Y" {8 h) d/ F* M
[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:
, z5 K# P9 ]9 N/ T' d& L9 u/ H b[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する) |7 E4 A! p0 e7 J' T. j
) e" V) y/ O5 p7 n | [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:3 a1 W% s# @1 ~. _" l8 b I5 G
[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;
9 t! q2 `" n4 g0 x4 y: dusing Microsoft.Xna.Framework.Content.Pipeline;
& Q2 D0 c' a' R- G4 h* y0 q/ b2 Tusing Microsoft.Xna.Framework.Content.Pipeline.Graphics;, t: a& I! L+ L% I3 ~# ?* r2 F
using Microsoft.Xna.Framework.Content.Pipeline.Processors;9 h5 h- j' t8 u, m7 }
+ U# E0 { e+ w. z
. b \+ J. X( R- i" Q: m
namespace FontProcessors
0 j7 B e5 t) L+ E) N{6 @" P) P, E" M0 O* m' Q/ ?
[ContentProcessor]
' F- V" w3 |% F* j7 Q' p- f+ d public class DefaultFontProcessor : FontDescriptionProcessor+ Q1 a, f S- _6 M1 R2 n
{ s" {; \1 [8 F9 H# q
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
! K/ j( b: N/ u {4 d6 d- L, C" t
//载入文件$ V0 L+ ^; p' x9 B( x8 H9 G
string fullPath = Path.GetFullPath("message.txt");
5 e+ q' Y4 Z6 z; L- g context.AddDependency(fullPath);
- @; | C" b9 }8 A string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);+ q8 z8 t, m4 {9 V s6 V8 N
, x( B- T6 i4 `* ?; O) m P! _1 @/ Y
//导入字符
# `* u1 K( H, G' J. z: v$ J foreach (char c in letters)3 F4 I# Q- p B9 p$ r
{
+ C( \' q; m* a input.Characters.Add(c);: Y* p# m& F! k. O8 X
}* W7 m% j3 Z# t$ k; j$ p! f2 N
return base.Process(input, context);; i8 T8 p7 l8 K# a# o6 H
}
* ~1 S9 d& [/ o3 p/ m }, B' _+ u* {+ M( T- ?: L4 @
}
+ w2 {7 F% G& t6 @
' ]( K& [- i# \% Y+ P$ C |
% Z* T/ U9 u# h8 s. U& i% W. B5 A- }. z6 Y/ `1 L* w
添加项目引用) k: X8 |* t8 u" F/ O2 Z
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用& v4 K; y/ a4 x% e/ I. f! p5 F# s5 x: Z
Game1.cs | using System;/ q- I& F# c& W" m& L7 Y
using System.Collections.Generic;
0 A6 e7 z* y) W/ W9 B! C4 {4 Eusing Microsoft.Xna.Framework;% F" s; M/ S) U$ X& p ^: {
using Microsoft.Xna.Framework.Audio;
. J, D+ f+ }/ M3 vusing Microsoft.Xna.Framework.Content;9 a X6 i8 u& y8 \% c
using Microsoft.Xna.Framework.GamerServices;) _+ q+ b) `) G7 s$ ~9 r
using Microsoft.Xna.Framework.Graphics; o0 t& U- M x
using Microsoft.Xna.Framework.Input;8 F- x/ O% J/ P) ?7 r) D
using Microsoft.Xna.Framework.Net;6 s8 ]; w8 `# k `0 T: O3 x5 s
using Microsoft.Xna.Framework.Storage;
9 t. B; U$ ~) q. ] _0 S
; k+ H4 I' S! N( v6 `1 N5 N* X& m2 A& {+ M& W$ U
namespace HelloWorld {
. E4 T" v2 r: x public class GameMain : Microsoft.Xna.Framework.Game {! q& p A5 j6 x- _5 @
private GraphicsDeviceManager graphics;
1 c0 I- w) n7 r$ h& L private SpriteBatch spriteBatch;; [; h! K" p0 Z, }
private SpriteFont font;
3 Y3 q8 [& L: L' E9 \$ f& V
: h4 p! P( U6 i6 D2 F, ~% e+ Q: s
public GameMain() {: F. u+ R1 W4 k6 Z) h
graphics=new GraphicsDeviceManager(this);1 [- g y5 D9 v5 L/ `. i
Content.RootDirectory="Content";
2 d- K$ l& |! O4 H0 i3 g }
4 |0 D K2 [/ O% Q: k3 a7 X. m! t2 P0 s- E+ C5 X& ?- L
/ i; D, H! t' i& ?- n
protected override void Initialize() {$ v" d _6 a) j4 q" S3 L: c d% q: {
base.Initialize();
6 y/ u/ N, N: j6 z6 Q }, F" Y d# b) Z4 V
1 O6 `6 D8 f9 D! C9 w9 H# E2 _3 O
; H& r- n% Q% d. z2 d5 h3 f
protected override void LoadContent() {
; E9 z8 h/ ]' J spriteBatch=new SpriteBatch(GraphicsDevice);! h; N( M& z) x- U$ z4 s
font=Content.Load<SpriteFont>("DefaultFont");
! i; U, ?$ @1 T" f }- T: O2 z' [+ N9 Z1 H7 l( j
" F/ E9 A+ o! u3 j* B9 |6 N
& { e1 h6 u! M) B7 o* F2 e protected override void UnloadContent() {
7 m1 m; f, i" A- y }
* _6 c& g& [7 W3 j/ n% K! E$ i4 |; d! ~/ Q
5 b9 d% P- m. ]* G8 V! A0 g
protected override void Update(GameTime gameTime) {0 h: h9 I/ `6 n( A; {
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==* _9 _. v! u) ~/ _& S. P) \& t) S
ButtonState.Pressed) {. b( T$ w* B; M3 P1 L3 k* e, L
Exit();
" s# Y. }4 {: ~, M( Q }5 g+ o2 n( f ~& J
3 P, [' M' N! Y5 p, B& f3 |, q
# c5 O9 T% c# G- S/ m; m5 I' r
base.Update(gameTime);4 D( h9 Q& X: f2 U1 S1 t& I
}
. F+ E% p2 {! l) q! }6 \+ @5 g( o+ H/ ?
3 E$ Q+ t/ G4 I5 `6 ]9 t, ^
protected override void Draw(GameTime gameTime) {7 Z/ R8 F' {# n, G) x6 ?: y1 g; \6 r3 I
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);) F( H/ E( H! N6 O+ M
! V8 F! Z+ b1 q! e. Z6 W _! I
+ r* B6 f7 T) U8 f( ^$ w) @* b3 } spriteBatch.Begin();
3 Q+ g$ n7 a# l! X2 ^( W DrawString("中文输入测试,日本語テストを入力する",50,50);' t2 F( T7 ]8 Z+ G9 [) h8 _/ C' N
spriteBatch.End();
}( |7 \4 b7 f# `/ z# Y
3 a$ L" k9 F0 E8 V. m
0 x( {4 R! N' W) W+ R# U. o base.Draw(gameTime);
6 r; G$ Y: Z! V$ \; f+ M }
6 F: g, F; |& n8 a& g' Q6 ?" R3 p5 p; b. s$ R: E2 A3 O9 s
( N! x7 [: u) I
private void DrawString(String str,int x,int y) {' j8 h( d- a; O2 w4 v9 r P
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);# Q0 M" e5 R, W3 Q
}
/ V6 M& I# ~/ p2 O }4 w, G6 r C3 h% P' c
}* i; i! [, a: J8 p
, ^, `0 K5 O- z5 F+ ]
|
|