使用BMP圖像的字體有沒有辦法來加載使用BMP圖像的自定義字體..在Monogame
我已經通過微軟在網上看到一個解決方案,提供這一點,但我不斷獲取內容的負載例外當試圖運行這個解決方案時。
看起來這是用來和XNA一起工作的,但對於Monogame來說可能不是這樣。
我想要我自己的自定義字體,因爲這種字體不會預裝在客戶端的計算機上。
我已經看過來自SpriteFont Converter的XNB文件,這不是我希望瞄準的解決方案。
任何幫助將不勝感激,謝謝
使用BMP圖像的字體有沒有辦法來加載使用BMP圖像的自定義字體..在Monogame
我已經通過微軟在網上看到一個解決方案,提供這一點,但我不斷獲取內容的負載例外當試圖運行這個解決方案時。
看起來這是用來和XNA一起工作的,但對於Monogame來說可能不是這樣。
我想要我自己的自定義字體,因爲這種字體不會預裝在客戶端的計算機上。
我已經看過來自SpriteFont Converter的XNB文件,這不是我希望瞄準的解決方案。
任何幫助將不勝感激,謝謝
的研究,我結束了在網上尋找解決辦法很長一段時間後負荷。這裏是一個鏈接教程:http://www.craftworkgames.com/blog/tutorial-bmfont-rendering-with-monogame/
此方法需要您下載一個叫bmFont軟件:http://www.angelcode.com/products/bmfont/
有了這個軟件,你將收到您的字體的輸出爲2個文件:
爲了使這些文件與您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);
}
}
你走了。現在你應該都很好,看看它爲你自己工作。 困難的部分將隨着你的字體大小玩轉,因爲你需要爲你想要的每種字體大小生成一個文件。
雖然這種技術爲您提供了直接嵌入字體的可能性,而不需要最終用戶在他的計算機上安裝(曾經崩潰)。
享受, 凱文