2015-04-05 3 views
3

Есть ли способ, чтобы загрузить пользовательский шрифт с помощью BMP изображения ..Использование BMP изображения шрифта в Monogame

Я видел решение в Интернете, Microsoft обеспечения, но я продолжаю получать исключение содержания нагрузки при попытке запустить это решение.

Похоже, что это использовалось для работы с XNA, но, возможно, это не так с Monogame.

Я хочу свой собственный шрифт, так как этот шрифт не будет предварительно установлен на компьютере клиента.

Я уже смотрел файлы XNB из SpriteFont Converter, и это не решение, к которому я хочу стремиться.

Любой помощь будет признателен, спасибо

ответ

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 и time.fnt производства программного обеспечения BmFonts. Они являются результатом шрифта Avenir Next Condensed, который я хотел использовать.

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); 
    } 



} 

Там вы идете. Теперь вам все будет в порядке, посмотрите, как это работает для вас самих. Жесткая часть будет воспроизводиться с вашим размером шрифта, так как вам нужно будет создать файл для каждого размера шрифта, который вам нужен.

Несмотря на то, что эти методы предлагают вам возможность непосредственно начертить шрифт, не требуя, чтобы конечный пользователь установил его на свой компьютер (который использовался для сбоя).

Наслаждайтесь, Kevin

Смежные вопросы