XNA-顯示中文
由上一篇的範例XNA-利用Content Pipeline輸出多國語言學會使用ContentProcessor輸出多國文字,
但是我不想使用資源檔的方式來存內文,我比較想用自己的xml檔,
構想是自己的xml檔輸入想顯示的文字,如下:
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
<!-- TODO: replace this Asset with your own XML asset data. -->
<Asset Type="MessagePipeline.MessageData">
<Msg name="title">你好</Msg>
<Msg name="name">我是天譴寶寶</Msg>
</Asset>
</XnaContent>
然後有一個MessageData的物件,用來載入此xml後在程式裡使用,內容只有一個Dictionary<string,string>物件,
然後還有Importer以及writer如下:
public class MessageData {
public Dictionary<string,string> Data = new Dictionary<string,string>();
}
[ContentImporter(DisplayName = "MessagePipeline.MessageImporter")]
public class MessageImporter : ContentImporter<MessageData> {
public override MessageData Import(string filename, ContentImporterContext context) {
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(filename);
MessageData messageData = new MessageData();
foreach (XmlNode xmlNode in xmlDocument.SelectNodes("XnaContent/Asset/Msg")) {
messageData.Data.Add(xmlNode.Attributes["name"].InnerText, xmlNode.InnerText);
}
return messageData;
}
}
[ContentTypeWriter]
public class MessageDataWriter : ContentTypeWriter<MessageData> {
protected override void Write(ContentWriter output, MessageData value) {
output.Write(value.Data.Count);
foreach (string key in value.Data.Keys) {
output.Write(key);
output.Write(value.Data[key]);
}
}
public override string GetRuntimeReader(Microsoft.Xna.Framework.TargetPlatform targetPlatform) {
return "MessagePipeline.MessageDataReader, ContentPipelineExtension1";
}
}
public class MessageDataReader : ContentTypeReader<MessageData> {
protected override MessageData Read(ContentReader input, MessageData existingInstance) {
MessageData data = existingInstance;
if (data == null) {
data = new MessageData();
}
int count = input.ReadInt32();
for (int i = 0; i < count; i++) {
data.Data.Add(input.ReadString(), input.ReadString());
}
return data;
}
}
其中Importer是之前沒有說過的,但是應該很好懂,就是將原始檔案轉成我的MessageData物件。
spritefont檔案會多出指定要輸入那些文字的node:
<TextFiles>
<Text>Message.xml</Text>
</TextFiles>
這裡我只使用Message.xml,若是以後想要有別種資料,例如用來顯示技能說明、故事對話之類的文字,可以再加。
再來是自訂processor,主要針對spritefont檔案,有兩個主要的物件:
public class MessageFontDescription : FontDescription {
public MessageFontDescription()
: base("Arial", 14, 0) {
}
[ContentSerializer(Optional = true, CollectionItemName = "Text")]
public List<string> TextFiles {
get { return textFiles; }
}
List<string> textFiles = new List<string>();
}
[ContentProcessor(DisplayName = "MessagePipeline.MessageProcessor")]
public class MessageProcessor : ContentProcessor<MessageFontDescription, SpriteFontContent> {
public override SpriteFontContent Process(MessageFontDescription input, ContentProcessorContext context) {
foreach (string path in input.TextFiles) {
string absolutePath = Path.GetFullPath(path);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(absolutePath);
foreach (XmlNode xmlNode in xmlDocument.SelectNodes("XnaContent/Asset/Msg")) {
string characters = xmlNode.InnerText;
// Scan each character of the string.
foreach (char usedCharacter in characters) {
input.Characters.Add(usedCharacter);
}
}
context.AddDependency(absolutePath);
}
return context.Convert<FontDescription, SpriteFontContent>(input, "FontDescriptionProcessor");
}
}
MessageProcessor要覆寫Process函式,他會取得我們的檔案,然後將裡面的字加到Characters裡,這部份和上一個範例差不多。
之後要將Message.xml的Importer屬性設定成我們自訂的物件
然後spritefont檔也要設定使用我們自訂的processor
如此以後想要增加文字敘述,就很方便了!!
程式執行結果:
範例下載:XNA-顯示中文.rar