馬寧的Windows Phone 7開發教程(4)——XNA顯示中文字型

來源:互聯網
上載者:User
文章目錄
  • 繪製字型
  • 添加中文支援
  • 相關資源

我最近勤快地連自己都有些不可思議。昨天有朋友在上一篇文章裡留言,批評Windows Phone 7暫時沒有支援中文版的問題。凡事都有個過程,在中文版出來前,咱們想自己想點辦法吧。Silverlight for Windows Phone那邊就不管了,肯定會有人想出辦法來的。如何讓Windows Phone 7遊戲顯示中文?把說“貼圖”的那個人拖出去打死!因為XNA 4.0中支援中文的辦法倒是現成的,這與XNA字型支援的方式有很大關係。

範例程式碼:

http://files.cnblogs.com/aawolf/XNA_aawolf_SIP_Chinese.rar

繪製字型

我們先來看一下XNA中如何繪製字型,MSDN上的描述很好:

http://msdn.microsoft.com/en-us/library/bb447673.aspx

關於字型授權的問題咱們就不糾結了,提醒一句,使用某種字型前首先確認是否能夠使用、再分發。繪製字型的第一步是,建立Sprite Font字型。XNA中使用的字型檔叫做Sprite Font,副檔名為.spritefont,XNA支援從.ttf將字型轉換為.spritefont。

首先,我們在VS 2010的Solution Explorer中找到WindowsPhoneGame1Content項目,右鍵菜單點擊“Add”-“New Folder”,將新檔案夾命名為Font,然後在Font上右鍵點擊,選擇“Add”-“New Item”,然後在對話方塊中選擇建立“Sprite Font”,將字型檔命名為StartFont。

在Solution Explorer中雙擊StartFont.spritefont檔案,我們會開啟一個XML檔案,我們省去XML注釋部分:

<?xml version="1.0" encoding="utf-8"?><XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">  <Asset Type="Graphics:FontDescription">    <FontName>Kootenay</FontName>    <Size>30</Size>    <Spacing>0</Spacing>    <UseKerning>true</UseKerning>    <Style>Regular</Style>    <CharacterRegions>      <CharacterRegion>        <Start>&#32;</Start>        <End>&#126;</End>      </CharacterRegion>    </CharacterRegions>  </Asset></XnaContent>

按照XML的注釋,我們可以很容易的瞭解每一項的功能,只看高亮部分:FontName,字型的名稱;Size,字型的大小;Style,指定字型是否為粗體、斜體等;CharacterRegion,字型區間,目前的設定為只顯示ASCII字型。這一點也是非常適合遊戲開發的,遊戲沒有必要提供完整的字元集支援。

接下來就是繪製代碼了,首先在類中增加SpriteFont的變數:

    public class Game1 : Microsoft.Xna.Framework.Game    {        GraphicsDeviceManager graphics;        SpriteBatch spriteBatch;        SpriteFont StartFont;        SpriteFont YaheiFont;        static string Text = "";

我們還增加了一個Text,可以用這個變數從SIP軟鍵盤中擷取使用者輸入的字串。然後是LoadContent函數:

        /// </summary>        protected override void LoadContent()        {            // Create a new SpriteBatch, which can be used to draw textures.            spriteBatch = new SpriteBatch(GraphicsDevice);            // TODO: use this.Content to load your game content here            StartFont = Content.Load<SpriteFont>(@"Font\StartFont");            YaheiFont = Content.Load<SpriteFont>(@"Font\Yahei");        }

請大家注意字型檔的路徑:將Content資源放到另外一個DLL裡可以方便遊戲替換資源,而路徑方面,只需要將Folder指定對就可以了。這裡順便把中文微軟雅黑字型也加了上了。因為要擷取SIP的輸入,所以還要修改 Update方法:

        protected override void Update(GameTime gameTime)        {            // Allows the game to exit            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)                this.Exit();            // TODO: Add your update logic here            if (Text == "" && !Guide.IsVisible)                Guide.BeginShowKeyboardInput(PlayerIndex.One,                        "Here's your Keyboard", "Type something...",                        "",                        new AsyncCallback(GetTypedChars),                        null);            base.Update(gameTime);        }        private static void GetTypedChars(IAsyncResult asynchronousResult)        {            Text = Guide.EndShowKeyboardInput(asynchronousResult);            Debug.WriteLine(Text);        }

我們修改了update方法,只有Text為空白時,SIP才會彈出,SIP部分的代碼上次已經說過了。最後一部分就是繪製Draw函數了:

        protected override void Draw(GameTime gameTime)        {            GraphicsDevice.Clear(Color.White);            // TODO: Add your drawing code here            spriteBatch.Begin();            spriteBatch.DrawString(StartFont, Text, new Vector2(10, 10), Color.Black);            //spriteBatch.DrawString(StartFont, "中國", new Vector2(10, 50), Color.Black);                        spriteBatch.End();            base.Draw(gameTime);        }

運行程式,會首先實現一個IME對話方塊,輸入”Hello,xna”之後,會顯示下面的介面:

大家注意到,我將第二個繪製“中國”的DrawString注釋掉了,如果不注釋掉會怎麼樣呢?產生一個Exception,因為我們Sprite Font的CharacterRegion只包含了ASCII字元,所以,中文字型顯然超過了字元範圍。

添加中文支援

MSDN上的另一篇文章描述了這個問題:

http://msdn.microsoft.com/en-us/library/bb447751.aspx

我們可以Font Description Processor來添加對於指定字元的支援,而不需要擴大CharacterRegions,讓很多無用的字元也被增加到字型檔中來。

首先,我們在Solution Explorer中找到遊戲的Project,在本例中,就是WindowsPhoneGame1,右鍵菜單“Add”-“New Item”,選擇“Text File”,命名為messages.txt。雙擊開啟messages.txt,在裡邊添加遊戲中要支援的所有中文字元。因為要使用File.ReadAllText,所以確保文字檔是以’\r’或’\n’結尾。

接下來要建立一個新的Content Processor Project,在Solution Explorer中選擇Solution,右鍵點擊”Add”-“New Project”,選擇”Content Pipeline Extension Library(4.0)”,命名為FontProcessor。下面是ContentProcessor1.cs中修改後的所有代碼:

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.ComponentModel;namespace FontProcessor{    /// <summary>    /// This class will be instantiated by the XNA Framework Content Pipeline    /// to apply custom processing to content data, converting an object of    /// type TInput to TOutput. The input and output types may be the same if    /// the processor wishes to alter data without changing its type.    ///    /// This should be part of a Content Pipeline Extension Library project.    ///    /// TODO: change the ContentProcessor attribute to specify the correct    /// display name for this processor.    /// </summary>    [ContentProcessor(DisplayName = "FontProcessor.ContentProcessor1")]    public class ContentProcessor1 : FontDescriptionProcessor    {        public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)        {            string fullPath = Path.GetFullPath(MessageFile);            context.AddDependency(fullPath);            string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);            foreach (char c in letters)            {                input.Characters.Add(c);            }            return base.Process(input, context);        }        [DefaultValue("messages.txt")]        [DisplayName("Message File")]        [Description("The characters in this file will be automatically added to the font.")]        public string MessageFile        {            get { return messageFile; }            set { messageFile = value; }        }        private string messageFile = @"..\WindowsPhoneGame1\messages.txt";    }}

首先,增加兩個引用,用於讀取檔案:

using System.IO;using System.ComponentModel;

然後增加MessageFile的屬性:

        [DefaultValue("messages.txt")]        [DisplayName("Message File")]        [Description("The characters in this file will be automatically added to the font.")]        public string MessageFile        {            get { return messageFile; }            set { messageFile = value; }        }        private string messageFile = @"..\WindowsPhoneGame1\messages.txt";

請注意其中的檔案路徑,因為檔案包含在WindowsPhoneGame1的目錄中,而本工程位於FontProcessor目錄中,所以我們要修改其路徑,否則會出現檔案無法找到的編譯錯誤。因為FontProcessor是在編譯時間使用的,所以Excepiton都是以編譯錯誤展現出來的。

我們還需要將ContentProcessor1的基類ContentProcessor替換為FontDescriptionProcessor。為messages.txt註冊Content Pipeline,增加依賴關係,告訴Content Pipeline,如果messages.txt變化,則字型需要重新編譯。最後是讀取這個檔案,為其中的每一個字元增加字型的支援。另外,確保你的messages.txt檔案,採用了UTF-8的編碼方式。

完成這些之後,我們要首先編譯一下FontProcessor,然後在Solution Explorer中,右鍵點擊WindowsPhoneGame1Content的References目錄,選擇“Add references”,在Project Tab頁中,選擇FontProcessor。接下來,在Solution Explorer中,右鍵點擊Project Dependencies,將FontProcessor前的CheckBox選中。

然後,建立一個新的Sprite Font字型,叫做YaheiFont,字型名稱為“Microsoft Yahei”,選中yahei.spritefont,在屬性頁面中的Content Processor項中,將“Sprite Font Description - XNA Framework”切換為“FontProcessor.ContentProcessor1”。

最後,在遊戲中增加雅黑字型,將Game中的繪製函數改為:

        protected override void Draw(GameTime gameTime)        {            GraphicsDevice.Clear(Color.White);            // TODO: Add your drawing code here            spriteBatch.Begin();            spriteBatch.DrawString(StartFont, Text, new Vector2(10, 10), Color.Black);            spriteBatch.DrawString(YaheiFont, "中國", new Vector2(10, 50), Color.Black);                        spriteBatch.End();            base.Draw(gameTime);        }

最後的效果就是:(向毛主席保證,這不是貼圖!)

相關資源

馬寧的Windows Phone 7開發教程(1)——Windows Phone開發工具初體驗

馬寧的Windows Phone 7開發教程(2)——Windows Phone XNA 4.0 3D遊戲開發

馬寧的Windows Phone 7開發教程(3)——XNA下使用MessageBox和軟鍵盤

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.