2015-04-05 111 views
3

使用BMP圖像的字體有沒有辦法來加載使用BMP圖像的自定義字體..在Monogame

我已經通過微軟在網上看到一個解決方案,提供這一點,但我不斷獲取內容的負載例外當試圖運行這個解決方案時。

看起來這是用來和XNA一起工作的,但對於Monogame來說可能不是這樣。

我想要我自己的自定義字體,因爲這種字體不會預裝在客戶端的計算機上。

我已經看過來自SpriteFont Converter的XNB文件,這不是我希望瞄準的解決方案。

任何幫助將不勝感激,謝謝

回答

2

的研究,我結束了在網上尋找解決辦法很長一段時間後負荷。這裏是一個鏈接教程:http://www.craftworkgames.com/blog/tutorial-bmfont-rendering-with-monogame/

此方法需要您下載一個叫bmFont軟件:http://www.angelcode.com/products/bmfont/

有了這個軟件,你將收到您的字體的輸出爲2個文件:

  1. .fnt文件,用於紋理中的圖案
  2. .png文件,它是實際字符。

爲了使這些文件與您monoproject工作(可以用XNA我想也行),你需要將該類添加到您的項目(注意:您需要更改命名空間):

// ---- AngelCode BmFont XML serializer ---------------------- 
// ---- By DeadlyDan @ [email protected] ------------------- 
// ---- There's no license restrictions, use as you will. ---- 
// ---- Credits to http://www.angelcode.com/ ----------------- 

using System; 
using System.IO; 
using System.Xml.Serialization; 
using System.Collections.Generic; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Content; 

namespace Dashboard 
{ 
    public class BmFont { 

     String fontFilePath; 
     FontFile fontFile; 
     Texture2D fontTexture; 
     FontRenderer _fontRenderer; 

     public BmFont(String fontTexture, String png, ContentManager c) { 
      fontFilePath = Path.Combine(c.RootDirectory, fontTexture); 
      fontFile = FontLoader.Load(fontFilePath); 
      this.fontTexture = c.Load<Texture2D>(png); 
      _fontRenderer = new FontRenderer(fontFile, this.fontTexture); 
     } 

     public void draw(String message, Vector2 pos, SpriteBatch _spriteBatch) { 
      _fontRenderer.DrawText(_spriteBatch, (int)pos.X, (int)pos.Y, message); 
     } 

    } 


    public class FontRenderer 
    { 

     public static FontFile Load(Stream stream) 
     { 
      XmlSerializer deserializer = new XmlSerializer(typeof(FontFile)); 
      FontFile file = (FontFile) deserializer.Deserialize(stream); 
      return file; 
     } 

     public FontRenderer (FontFile fontFile, Texture2D fontTexture) 
     { 
      _fontFile = fontFile; 
      _texture = fontTexture; 
      _characterMap = new Dictionary<char, FontChar>(); 

      foreach(var fontCharacter in _fontFile.Chars) 
      { 
       char c = (char)fontCharacter.ID; 
       _characterMap.Add(c, fontCharacter); 
      } 
     } 

     private Dictionary<char, FontChar> _characterMap; 
     private FontFile _fontFile; 
     private Texture2D _texture; 
     public void DrawText(SpriteBatch spriteBatch, int x, int y, string text) 
     { 
      int dx = x; 
      int dy = y; 
      foreach(char c in text) 
      { 
       FontChar fc; 
       if(_characterMap.TryGetValue(c, out fc)) 
       { 
        var sourceRectangle = new Rectangle(fc.X, fc.Y, fc.Width, fc.Height); 
        var position = new Vector2(dx + fc.XOffset, dy + fc.YOffset); 

        spriteBatch.Draw(_texture, position, sourceRectangle, Color.White); 
        dx += fc.XAdvance; 
       } 
      } 
     } 
    } 


    [Serializable] 
    [XmlRoot ("font")] 
    public class FontFile 
    { 
     [XmlElement ("info")] 
     public FontInfo Info 
     { 
      get; 
      set; 
     } 

     [XmlElement ("common")] 
     public FontCommon Common 
     { 
      get; 
      set; 
     } 

     [XmlArray ("pages")] 
     [XmlArrayItem ("page")] 
     public List<FontPage> Pages 
     { 
      get; 
      set; 
     } 

     [XmlArray ("chars")] 
     [XmlArrayItem ("char")] 
     public List<FontChar> Chars 
     { 
      get; 
      set; 
     } 

     [XmlArray ("kernings")] 
     [XmlArrayItem ("kerning")] 
     public List<FontKerning> Kernings 
     { 
      get; 
      set; 
     } 
    } 

    [Serializable] 
    public class FontInfo 
    { 
     [XmlAttribute ("face")] 
     public String Face 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("size")] 
     public Int32 Size 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("bold")] 
     public Int32 Bold 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("italic")] 
     public Int32 Italic 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("charset")] 
     public String CharSet 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("unicode")] 
     public Int32 Unicode 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("stretchH")] 
     public Int32 StretchHeight 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("smooth")] 
     public Int32 Smooth 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("aa")] 
     public Int32 SuperSampling 
     { 
      get; 
      set; 
     } 

     private Rectangle _Padding; 
     [XmlAttribute ("padding")] 
     public String Padding 
     { 
      get 
      { 
       return _Padding.X + "," + _Padding.Y + "," + _Padding.Width + "," + _Padding.Height; 
      } 
      set 
      { 
       String[] padding = value.Split (','); 
       _Padding = new Rectangle (Convert.ToInt32 (padding[0]), Convert.ToInt32 (padding[1]), Convert.ToInt32 (padding[2]), Convert.ToInt32 (padding[3])); 
      } 
     } 

     private Point _Spacing; 
     [XmlAttribute ("spacing")] 
     public String Spacing 
     { 
      get 
      { 
       return _Spacing.X + "," + _Spacing.Y; 
      } 
      set 
      { 
       String[] spacing = value.Split (','); 
       _Spacing = new Point (Convert.ToInt32 (spacing[0]), Convert.ToInt32 (spacing[1])); 
      } 
     } 

     [XmlAttribute ("outline")] 
     public Int32 OutLine 
     { 
      get; 
      set; 
     } 
    } 

    [Serializable] 
    public class FontCommon 
    { 
     [XmlAttribute ("lineHeight")] 
     public Int32 LineHeight 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("base")] 
     public Int32 Base 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("scaleW")] 
     public Int32 ScaleW 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("scaleH")] 
     public Int32 ScaleH 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("pages")] 
     public Int32 Pages 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("packed")] 
     public Int32 Packed 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("alphaChnl")] 
     public Int32 AlphaChannel 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("redChnl")] 
     public Int32 RedChannel 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("greenChnl")] 
     public Int32 GreenChannel 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("blueChnl")] 
     public Int32 BlueChannel 
     { 
      get; 
      set; 
     } 
    } 

    [Serializable] 
    public class FontPage 
    { 
     [XmlAttribute ("id")] 
     public Int32 ID 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("file")] 
     public String File 
     { 
      get; 
      set; 
     } 
    } 

    [Serializable] 
    public class FontChar 
    { 
     [XmlAttribute ("id")] 
     public Int32 ID 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("x")] 
     public Int32 X 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("y")] 
     public Int32 Y 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("width")] 
     public Int32 Width 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("height")] 
     public Int32 Height 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("xoffset")] 
     public Int32 XOffset 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("yoffset")] 
     public Int32 YOffset 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("xadvance")] 
     public Int32 XAdvance 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("page")] 
     public Int32 Page 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("chnl")] 
     public Int32 Channel 
     { 
      get; 
      set; 
     } 
    } 

    [Serializable] 
    public class FontKerning 
    { 
     [XmlAttribute ("first")] 
     public Int32 First 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("second")] 
     public Int32 Second 
     { 
      get; 
      set; 
     } 

     [XmlAttribute ("amount")] 
     public Int32 Amount 
     { 
      get; 
      set; 
     } 
    } 

    public class FontLoader 
    { 
     public static FontFile Load (String filename) 
     { 
      XmlSerializer deserializer = new XmlSerializer (typeof (FontFile)); 
      TextReader textReader = new StreamReader (filename); 
      FontFile file = (FontFile) deserializer.Deserialize (textReader); 
      textReader.Close (); 
      return file; 
     } 
    } 
} 

我稍微修改了這個類,以便以面向對象的方式實現它。以下是您如何在主Game.cs文件中使用此類與您的自定義字體。

對於此示例,我有文件time_0.png和由軟件產生的BmFonts time.fnt。它們是字體Avenir Next的縮寫,我想使用它。

public class Game1 : Game 
{ 
    // Graphic variables used for the game to work 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 
    BmFont fontTime; 



    public Game1() 
    { 
     graphics = new GraphicsDeviceManager (this); 
     Content.RootDirectory = "Content";    
     graphics.IsFullScreen = true;  
    } 

    protected override void LoadContent() 
    { 
     // Create a new SpriteBatch, which can be used to draw textures. 
     spriteBatch = new SpriteBatch (GraphicsDevice); 
     fontTime = new BmFont ("time.fnt", "time_0.png", this.Content); 
    } 

    protected override void Draw (GameTime gameTime) 
    { 
     graphics.GraphicsDevice.Clear (Color.CornflowerBlue); 



     spriteBatch.Begin(); 
      fontTime.draw (DateTime.Now.ToString("HH mm"), new Vector2 (100, 50)), spriteBatch); 
     spriteBatch.End(); 
     base.Draw (gameTime); 
    } 



} 

你走了。現在你應該都很好,看看它爲你自己工作。 困難的部分將隨着你的字體大小玩轉,因爲你需要爲你想要的每種字體大小生成一個文件。

雖然這種技術爲您提供了直接嵌入字體的可能性,而不需要最終用戶在他的計算機上安裝(曾經崩潰)。

享受, 凱文