原文; p/ G# E l' [* s
http://blog.csdn.net/lqr801225/archive/2009/05/26/4218688.aspx
* R' A8 b/ V7 N @ V* M6 Z4 i# b9 K, Q9 V
: x7 z8 ^/ K5 `- N( D' h7 z
在XNA中显示中文字符或其它UNICODE字符(非GDI+)
- Q$ `- R' k2 J& {XNA3.0+VS2008SP1下调试通过 k% V5 C5 G8 |
由于XNA内置的DrawString方法并不能输出全角UNICODE字符,只能设定字符的起始和终止的内码,欧洲语系的字元不多,可以一次导入并生成字体,但像亚洲语系这样动辄上千的字元又是全角,好像设计者并没有考虑到这些情况。为了实现字符输出,已经有一些方法,例如利用.net中的GDI+。下面的实现方法是通过生成自定义的文字托管方式来实现的。# T& K2 _2 G2 l7 H1 K
步骤如下:
. i# O$ F% w8 f3 f) D建立字体文件
, N' Z$ ?. @# ^, @% \/ S' x[li]在当前项目中的“Content”中点击右键 [/li][li]加入新的文件,类型是"Sprite Font",起名为"DefaultFont.spritefont" [/li][li]打开这个XML格式的文件,将"FontName"节中的字体改成含有目标语言字体的字体文件,这里使用“幼圆” [/li] 字典文件:7 T5 r# v. j `& g2 Y
[li]把游戏中需要的文字放到一个文本文件“message.txt”中,方便随时修改,以换行符结尾,内容如下: message.txt | 中文输入测试,日本語テストを入力する6 O( K: h, C3 t9 B3 ]
2 r6 f# U4 r2 {: v( F3 H
| [/li][li]将这个文件放置在项目的Content目录下。 [/li][li]另存为一下这个文件,以“UTF-8”编码格式。 [/li][li]在解决方案浏览器中选择这个文件,在属性窗口的高级中的“生成操作”中选择“无”,“复制到输出目录”里选择“始终复制”。 [/li] 文字处理类:* R1 X3 Z: Q& p+ F/ T8 y
[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;
. G! k) y4 i; f/ q* a1 d: r0 Vusing Microsoft.Xna.Framework.Content.Pipeline;% M; G: ^5 M0 U! w& @
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;! K+ b& O& T8 w9 a
using Microsoft.Xna.Framework.Content.Pipeline.Processors;+ d f% v. j' }$ A- n
" ^" ^ K! b2 v- ^) f
6 ?% U+ F3 n e5 U% M2 m
namespace FontProcessors+ Q7 D5 w& }5 d" y
{
2 ^& D$ E' T" {, n5 N8 j [ContentProcessor]5 K1 g, D; c+ a5 Z9 b# `- c# o
public class DefaultFontProcessor : FontDescriptionProcessor! z( \+ P( i8 R7 C- v. X) S1 B
{: n2 g7 w \( K& g% @7 O
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)
- N7 I0 s7 Y6 F0 G: i: D$ v6 T {
5 Z4 w/ \' V# z9 S1 M; d! D5 N4 g //载入文件! t( o2 a9 m" I" b
string fullPath = Path.GetFullPath("message.txt");
6 a8 z. A! h: z6 } context.AddDependency(fullPath);
# j$ ?7 j& \! p. v7 [( d( r string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);
1 n0 l7 K* f/ b' q% s2 l, k9 ~7 N7 @
! w! T$ u' X4 i* F
; w, }# T, L' [; _ //导入字符$ c' {6 r2 u. ~0 {# L1 t, i
foreach (char c in letters): y. o# X# }' D* y! R" q6 x
{
/ u: j' d7 o8 j& f; y3 g% l input.Characters.Add(c);$ ~# J- Q6 r: E6 M2 `/ t$ {9 }4 a
}6 `5 M3 X, ]* M7 g1 h
return base.Process(input, context); F3 A$ v. t5 ~3 X3 |( E! V
}
+ M: o$ `7 K( m8 l" k# E' b }3 f' d9 }' q2 q% P- h4 P; l
}
9 H; s! A3 R6 ~# M! s l7 k
: `7 ]1 G! h+ U3 h7 S | 0 l. f$ ?) H1 Y
8 [" k L/ X. R- J
添加项目引用! W9 E0 Y a4 j) P' U
[li]在本项目的Content下的"引用"上点击右键,添加项目引用,在弹出的对话框中选择刚才建立的项目:“FontProcessors” [/li][li]在解决方案管理器选择本项目中的字体文件"DefaultFont.spritefont" [/li][li]在属性窗口中的Content Processor中选择我们建立的处理类:"DefaultFontProssor" [/li] 在项目用使用
# E6 d) f+ H. E) W# P! {, o0 QGame1.cs | using System;9 i. M) S) N2 o3 }
using System.Collections.Generic;# P1 i4 b1 c% `* R
using Microsoft.Xna.Framework;; ^, O3 y! [+ C! ~* Y( G
using Microsoft.Xna.Framework.Audio;3 w+ m. T E( Q" J
using Microsoft.Xna.Framework.Content;8 t# n; g1 u2 P
using Microsoft.Xna.Framework.GamerServices;9 b6 N/ b" I% J7 f9 j
using Microsoft.Xna.Framework.Graphics;
- K7 [: g! Q3 a/ C+ Musing Microsoft.Xna.Framework.Input;
7 e' i O; H0 t& O2 d& }using Microsoft.Xna.Framework.Net;
/ \* O% a4 x6 ^& ?$ E$ M1 {using Microsoft.Xna.Framework.Storage;& I E6 y- _% W$ y! s0 F& p
- i3 I( ]2 y( Q9 Q% u- H) p6 y
$ ?; ?% k7 X8 J* D# d3 G' u
namespace HelloWorld {
' [& }! { u* S3 T9 | public class GameMain : Microsoft.Xna.Framework.Game {+ P! I1 l% g( Y a% [
private GraphicsDeviceManager graphics;
4 W8 I0 M9 L) s$ B" q private SpriteBatch spriteBatch;7 r9 x u! g, @
private SpriteFont font; - C w7 J j; O
+ A1 R2 I1 E. F) I1 _& A
) {- X- Z$ I( C
public GameMain() {+ q/ E, L; b! l* n4 e3 e
graphics=new GraphicsDeviceManager(this);
( d- w" q2 \2 P" X* J Content.RootDirectory="Content";
E( y; ^* r( P; T/ e3 l }
# d# @7 f1 x; b+ c ~6 Y* L6 m5 Y/ C& N
& q- r& R' S+ Z" ]/ c
protected override void Initialize() {8 B+ N( C" _. N0 O5 o- c# K$ y9 Q! Y
base.Initialize();2 |6 u2 D( l3 c/ j) _
}
& w. g1 Q0 X6 v, L7 F8 x0 m, f% E& i
/ P* T4 C, x! q protected override void LoadContent() {3 x9 S2 ~3 |; F2 A
spriteBatch=new SpriteBatch(GraphicsDevice);
2 t6 H) [0 ~( P4 n& f$ W" I font=Content.Load<SpriteFont>("DefaultFont");5 [* ]$ B) Y, T' j9 K4 E
}5 R. w6 J* w( t
6 n+ R3 c* _1 v& Y! \4 D* T$ ?' z4 k
' d: h+ O3 y" Q$ D& ]: c
protected override void UnloadContent() {" @ o1 i8 l# q( u. z
}# E1 N, ^& k! u9 A! @" v( \: k
" E/ R; R* Q# \
, X) c( N- T4 y protected override void Update(GameTime gameTime) {, N9 {/ P; i6 t1 f$ a
if (GamePad.GetState(PlayerIndex.One).Buttons.Back==
9 f, U9 d+ j1 Z9 E2 e. Z# c ButtonState.Pressed) {+ a- _+ R) G# C2 e: |
Exit();
& J& C: b" D8 a% A' C+ h+ L }
6 P5 E1 K! J0 |2 n" _
2 o( c" \5 u0 f- G& @, A) @# ]. f4 O1 X8 R/ W4 m: Y
base.Update(gameTime);1 i# y7 Q+ K& T+ d3 X8 Z
}
* R$ V. G4 b- y
7 @. y. U1 W) t$ C0 q& y2 h+ H* v5 l
protected override void Draw(GameTime gameTime) {
& f- e, U2 `: `& L' H5 A } graphics.GraphicsDevice.Clear(Color.CornflowerBlue);- o' H1 d( _9 s1 k- j. x) v
4 J& L4 h1 t( g' E: `) r6 A; o& A' K- q! U/ B, J
spriteBatch.Begin();
- d3 Q7 g% Z t' { DrawString("中文输入测试,日本語テストを入力する",50,50);8 p5 |. R/ M3 v' x, g$ }0 F; Z a
spriteBatch.End();% [) ^3 F2 L8 d
6 b4 Z! J; l, c) l5 S' y/ A
( @1 h) K6 k' z) H, L base.Draw(gameTime);+ y# _$ W) d9 Q8 X# r4 O
}. g3 Z& c. Q9 B& G; G
( G2 k4 o& T/ k/ V
: a+ ?* g/ j* h private void DrawString(String str,int x,int y) {" s* q8 e" P1 _6 V4 X0 m
spriteBatch.DrawString(font,str,new Vector2(x,y),Color.White);, O. L( n# _3 H l6 b; p' f& o
}
; g; l! {: j6 D9 P }; a+ L) ~4 W( X) j
}
: [: v+ [4 L* p0 l1 Z0 t8 D/ @; R
0 a! k4 F+ p/ `( H, z" G8 ]3 d |
|