天天看點

XNA遊戲開發之字元篇

遊戲中開發不同于一般應用程式的開發,它更注重于界面美觀,我們需要在遊戲界面設計中花費大量的時間以便使它看起來更炫、更酷,當然這其中就少不了遊戲中的字元文本,那麼如何制作出漂亮的遊戲文本呢?今天我們就一起來看一下。

在xna中2d文本的繪制方式種類比較多,這有助于我們制作出更美觀的文本效果,下面我就逐一來看一下。

一、spritefont

這種方式在xna遊戲開發中應該算是最基本的一種形式,使用方法就是在遊戲對應的content項目中添加spritefont檔案(右鍵add—new item—sprite font)。之後你會看到生成了一個xml格式的檔案:

XNA遊戲開發之字元篇

view code

在這個檔案中定義了你使用的字型類型、字型大小、字元間距等資訊。值得一提的是上面的字型區間,它的意思是指你在遊戲中使用的的字元範圍,從上面的值可以看出是ascii的32-126,具體對應字元如下:

ascii碼

字元

32

[空格]

33

!

34

"

35

#

36

$

37

%

38

&

39

'

40

(

41

)

42

*

43

+

44

,

45

-

46

.

47

/

48

49

1

50

2

51

3

52

4

53

5

54

6

55

7

56

8

57

9

58

:

59

;

60

<

61

=

62

>

63

?

64

@

65

a

66

b

67

c

68

d

69

e

70

f

71

g

72

h

73

i

74

j

75

k

76

l

77

m

78

n

79

o

80

p

81

q

82

r

83

s

84

t

85

u

86

v

87

w

88

x

89

y

90

z

91

[

92

\

93

]

94

^

95

_

96

`

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

{

124

|

125

}

126

~

當然它幾乎涵蓋了所有常用英文字元。之是以要定義這個區間主要是為了減少遊戲資源,畢竟在一個遊戲中并不是所有的字元我們都要用到。到這裡可能會有朋友問,既然如此我要是使用中文怎麼辦,這個區間肯定不夠啊,中文有兩萬多個字元,定義這個區間的意義也不大啊?

事實上我們如果需要用到中文字元的話一般并不是修改這個區間(當然修改它是可以做到的,但是占用資源十分大,畢竟字元太過了),而是通過font description processor來處理。具體做法就是:準備一個txt檔案,其中存放我們遊戲中要用到的中文字元,例如我們建立一個fontdescription.txt檔案,裡面寫上"中文字型"四個字存放到遊戲的content項目中;接着在解決方案中添加一個content pipeline extension library(4.0)類型的項目,然後編寫一個類繼承于fontdescriptionprocesor,重寫process方法。在這個方法中我們讀取外部的一個txt檔案,當然你也可以直接寫到代碼中或存儲到其他位置,然後将txt檔案中的字元(當然我們這裡是中文字元了)讀取到fontdescription中,具體代碼如下:

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

using system;

using system.collections.generic;

using system.linq;

using microsoft.xna.framework;

using microsoft.xna.framework.graphics;

using microsoft.xna.framework.content.pipeline;

using microsoft.xna.framework.content.pipeline.graphics;

using microsoft.xna.framework.content.pipeline.processors;

using system.io;

using system.text;

using system.componentmodel;

namespace contentpipelineextensiondemo

[contentprocessor(displayname = "contentpipelineextensiondemo.mycontentprocessor")]//這個名字将用于spritefont的content processor屬性

public class mycontentprocessor : fontdescriptionprocessor

private string fdescription = @"../xnagamefontcontent/fonts/fontdescription.txt";//注意這裡的路徑,因為fontdescription.txt檔案在xnagamefontcontent項目的fonts檔案夾中

public override spritefontcontent process(fontdescription input, contentprocessorcontext context)

string path = path.getfullpath(fdescription);

context.adddependency(path);

string content = file.readalltext(path,encoding.utf8);//fontdescription.txt檔案必須儲存成utf-8格式,此處也需使用utf-8讀取

foreach (char c in content)//讀取檔案中字元,存放到fontdescription中

input.characters.add(c);

return base.process(input, context);

XNA遊戲開發之字元篇

做完上面兩步之後,此時檔案目錄結構如圖:

XNA遊戲開發之字元篇

這裡需要注意兩點:fontdescription.txt檔案必須儲存成utf-8;由于檔案在content項目中預設xnagamefontcontent中的檔案都需要進行編譯,編譯時會自動檢測裡面的檔案類型,而txt檔案不屬于這其中任何類型,是以我們需要修改它的buildaction屬性為none。接下來我們在xnagamefontcontent下面中添加對contentpipelineextensiondemo生成的dll檔案的引用,然後在xnagamefontcontent項目上右鍵選擇project dependencies,彈出如下圖視窗:

XNA遊戲開發之字元篇

在project項中選擇xnagamefont,depends on中勾選contentpipelineextensiondemo,确定,以此添加遊戲項目對内容管道擴充的依賴(這樣一來就可以修改spritefont檔案的processor為我們自定義的擴充内容)。最後我們在xnagamefontcontent項目中添加spritefontforchinese.spritefont檔案(上面txt中隻是定義了中文字元的範圍,在這裡可以指定字型類型、字型大小等資訊),檔案内容如下:

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

<?xml version="1.0" encoding="utf-8"?>

<xnacontent xmlns:graphics="microsoft.xna.framework.content.pipeline.graphics">

<asset type="graphics:fontdescription">

<fontname>華文行楷</fontname>

<size>30</size>

<spacing>0</spacing>

<usekerning>true</usekerning>

<style>regular</style>

<characterregions>

<characterregion>

<start> </start>

<end>~</end>

</characterregion>

</characterregions>

</asset>

</xnacontent>

XNA遊戲開發之字元篇

修改檔案的content processor屬性為我們自定義的contentpipelineextensiondemo.mycontentprocessor(這就是上面添加依賴關系的原因),然後我們就可以在遊戲中使用我們文本中的中文漢字了。具體使用時的代碼如下:

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

using microsoft.xna.framework.audio;

using microsoft.xna.framework.content;

using microsoft.xna.framework.gamerservices;

using microsoft.xna.framework.input;

using microsoft.xna.framework.input.touch;

using microsoft.xna.framework.media;

namespace xnagamefont

public class mygame : microsoft.xna.framework.game

graphicsdevicemanager graphics;

spritebatch spritebatch;

spritefont sf1;//spritefont文本

vector2 sfposition;//spritfont文本所在位置

spritefont sfchinese;//spritefont中文文本

vector2 sfchineseposition;//spritefont中文文本的顯示位置

public mygame()

graphics = new graphicsdevicemanager(this);

content.rootdirectory = "content";

graphics.preferredbackbufferwidth = 480;

graphics.preferredbackbufferheight = 800;

targetelapsedtime = timespan.fromticks(333333);

protected override void initialize()

sfposition = new vector2(130,200);

sfchineseposition = new vector2(160, 400);

base.initialize();

protected override void loadcontent()

spritebatch = new spritebatch(graphicsdevice);

sf1 = content.load<spritefont>(@"fonts/spritefont");

sfchinese = content.load<spritefont>(@"fonts/spritefontforchinese");

protected override void unloadcontent()

protected override void update(gametime gametime)

if (gamepad.getstate(playerindex.one).buttons.back == buttonstate.pressed)

this.exit();

base.update(gametime);

protected override void draw(gametime gametime)

graphicsdevice.clear(color.cornflowerblue);

spritebatch.begin();

spritebatch.drawstring(sf1, "spritefont", sfposition, color.white);

spritebatch.drawstring(sfchinese, "中文字型", sfchineseposition, color.red);

spritebatch.end();

base.draw(gametime);

XNA遊戲開發之字元篇

運作效果如圖:

XNA遊戲開發之字元篇

二、spritefonttexture

由于spritefont文本對于顯示效果的調整很有限,是以xna又對其進行了擴充。spritefonttexture事實上是以圖檔來作為xna的字元集,我們實作隻要制作好相關字元的圖檔,然後像使用spritefont一樣使用就可以了。當然使用起來很簡單,主要問題就是如何來制作圖檔字庫了。這個不用擔心,很多牛人早已經想過這類問題了,下面我們看幾種這類工具:

2.1 ttf2bmp

XNA遊戲開發之字元篇

我們将需要的字元編碼範圍确定下來,在min char中輸入最小字元編碼,在max char中輸入最大字元編碼,然後點選export就可以生成類似于下面的圖檔:

XNA遊戲開發之字元篇

将上圖添加到xnagamefontcontent下面的fonts檔案夾中,接下來就可以寫代碼使用了,當然這時我們的字元圖檔在xnagamefontcontent下面中預設的是textrue圖檔類型,還需要修改圖檔的processor屬性為sprite font texture - xna framework。具體使用代碼如下:

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

spritefont sftexture;//sprite font texture文本(ttf2bmp制作)

vector2 sftextureposition;//sprite font texture文本位置

sftextureposition = new vector2(60, 350);

sftexture = content.load<spritefont>(@"fonts/spritefonttexture");

spritebatch.drawstring(sftexture, "sprite font texture", sftextureposition, color.yellow);

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

2.2 spritefont2

XNA遊戲開發之字元篇

使用這個工具我們制作下面一張sprite font texture圖檔:

XNA遊戲開發之字元篇

然後添加到xnagamefontcontent項目的fonts檔案夾,當然别忘了修改片的processor屬性為sprite font texture - xna framework。然後再就可以在程式中使用我們制作的字型:

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

spritefont sftextureextend;//sprite font texture文本效果擴充(spritefont2制作)

vector2 sftextureextendposition;//sprite font texture extend文本位置

sftextureextendposition = new vector2(100, 330);

sftextureextend = content.load<spritefont>(@"fonts/spritefonttexture2");

spritebatch.drawstring(sftextureextend, "sft 2", sftextureextendposition, color.white);

XNA遊戲開發之字元篇

運作效果:

XNA遊戲開發之字元篇

2.3 xna bitmap font plus

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

!"#$%&'()*+,-./

0123456789:;<=>?

@abcdefghijklmno

pqrstuvwxyz[\]^_

`abcdefghijklmno

pqrstuvwxyz{|}~

XNA遊戲開發之字元篇

然後調整字元的樣式,修改字元間距:

XNA遊戲開發之字元篇

接着 ctrl+c複制,此時字元資訊複制到了剪貼闆,打開xna bitmap font plus,它會自動加載剪貼闆的内容,如下圖:

XNA遊戲開發之字元篇

當然此時我們需要調整字元行數、偏移量和間隔等資訊,點選generate bitmap font按鈕檢視效果是否符合我們的要求:

XNA遊戲開發之字元篇

當調整好之後,我們就可以點選save image as…按鈕來儲存生成的圖檔:

XNA遊戲開發之字元篇

最後将圖檔添加到xnagamefontcontent項目的fonts檔案夾,修改圖檔的processor屬性為sprite font texture - xna framework。就可以在程式中使用我們制作的字型:

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

spritefont sftextureplus;//sprite font texture文本(xna bitmap font plus制作)

vector2 sftextureplusposition;//sprite font texture 文本位置

sftextureplusposition = new vector2(40, 350);

sftextureplus = content.load<spritefont>(@"fonts/spritefonttexture3");

spritebatch.drawstring(sftextureplus, "sprite font texture 3", sftextureplusposition, color.white);

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

下面給出所有以上這幾種字型綜合到一起的代碼:

XNA遊戲開發之字元篇
XNA遊戲開發之字元篇

sfposition = vector2.zero;

sfchineseposition = new vector2(0, 100);

sftextureposition = new vector2(0, 200);

sftextureextendposition = new vector2(0, 300);

sftextureplusposition = new vector2(0, 400);

XNA遊戲開發之字元篇

最終效果:

XNA遊戲開發之字元篇

ok,就到這裡吧!

最後附上源代碼(上面提到的幾個工具,都可以點選相關連結下載下傳):

XNA遊戲開發之字元篇

繼續閱讀