De acuerdo, vas a tener que perdonarme por no darte un código XNA específico, porque no conozco esa plataforma, pero lo que voy a decirte debería funcionar en cualquier motor de juego que te permita dibujar sprites.
Las fuentes no son su único problema, por lo que le daré un consejo y luego responderé a su pregunta. Con estas dos cosas, deberías poder hacer una relación amorosa con tu diseñador de GUI, y ambos podrán hacer juegos muy felices.
Lo primero es que te sentarás con tu diseñador y le pedirás que te dé dos conjuntos de archivos. El primero es un conjunto de archivos transparentes que componen su GUI (óptimamente en formato PSD o DXT). Para cada botón, etiqueta fija, fondo, borde y cuadro de texto, obtendrá un archivo (también puede hacer un atlas de texturas, pero le recomiendo que lo haga después de ensamblar su GUI, y luego ajuste sus coordenadas de origen al pulsar). El texto no estático se debe omitir en este punto (lo volveré a ver más adelante).
Lo segundo que obtendrá es el diseño de la GUI real, esta vez en formato Photoshop. Para este archivo, le pedirá a su diseñador que haga todo el diseño de la GUI, utilizando solo los archivos que le entregó anteriormente.
Luego colocará cada elemento de la GUI en una capa separada, sin ningún efecto. Le dirás que haga este píxel perfecto, porque los lugares donde va a poner todo, es donde todo estará realmente en el juego finalizado.
Una vez que obtenga eso, para cada capa, presionará Ctrl-T, y en el panel de Información (F8), tomará nota de las coordenadas X e Y para cada elemento. Asegúrese de que sus unidades estén configuradas en píxeles (Preferencias-> Unidades y reglas-> Unidades). Estas son las posiciones que usará al dibujar sus sprites.
Ahora, para las fuentes, como puede saber claramente ahora, no podrá hacer que sus fuentes se vean exactamente de la misma manera que las ve en Photoshop utilizando las API de representación de texto. Tendrás que pre-renderizar tus glifos y luego ensamblar tus textos programáticamente. Hay muchas formas de hacer esto, y mencionaré la que uso.
Lo primero es representar todos tus glifos en uno o más archivos. Si solo le importa el inglés, una textura para todos los glifos será suficiente, pero si desea tener un conjunto de caracteres más extendido, puede usar varios archivos. Solo asegúrese de que todos los glifos que desee estén disponibles en la fuente que elija su diseñador.
Por lo tanto, para representar los glifos, puede usar las facilidades de System.Drawing
para obtener las métricas de fuente y dibujar sus glifos:
Color clearColor = Color.Transparent;
Color drawColor = Color.White;
Brush brush = new SolidBrush(drawColor);
TextRenderingHint renderingType = TextRenderingHint.AntiAliasGridFit; // Antialias is fine, but be careful with ClearType, which can blergh your renders when you apply effects
StringFormat stringFormat = StringFormat.GenericTypographic;
string fileNameFormat = "helvetica14_{0}.png";
string mapFileFormat = "helvetica14.txt";
string fontName = "Helvetica";
string fontPath = @"c:\windows\fonts\helvetica.ttf";
float fontSize = 14.3f;
int spacing = 2;
Font font = new Font(fontName, fontSize);
int x = 0;
int y = 0;
int width = 1024; // Force a maximum texture size
int height = 1024;
StringBuilder data = new StringBuilder();
int lineHeight = 0;
int currentPage = 1;
var families = Fonts.GetFontFamilies(fontPath);
List<char> codepoints = new List<char>();
HashSet<char> usedCodepoints = new HashSet<char>();
foreach (FontFamily family in families)
{
var typefaces = family.GetTypefaces();
foreach (Typeface typeface in typefaces)
{
GlyphTypeface glyph;
typeface.TryGetGlyphTypeface(out glyph);
foreach (KeyValuePair<int, ushort> kvp in glyph.CharacterToGlyphMap) // Render all available glyps
{
char c = (char)kvp.Key;
if (!usedCodepoints.Contains(c))
{
codepoints.Add(c);
usedCodepoints.Add(c);
}
}
}
}
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(clearColor);
g.TextRenderingHint = renderingType;
foreach (char c in codepoints)
{
string thisChar = c.ToString();
Size s = g.MeasureString(thisChar, font); // Use this instead of MeasureText()
if (s.Width > 0)
{
s.Width += (spacing * 2);
s.Height += (spacing * 2);
if (s.Height > lineHeight)
lineHeight = s.Height;
if (x + s.Width >= width)
{
x = 0;
y += lineHeight;
lineHeight = 0;
if (y + s.Height >= height)
{
y = 0;
g.Dispose();
bitmap.Save(string.Format(fileNameFormat, currentPage));
bitmap.Dispose();
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
g = Graphics.FromImage(bitmap);
g.Clear(clearColor);
g.TextRenderingHint = renderingType;
currentPage++;
}
}
g.DrawString(thisChar, font, brush, new PointF((float)x + spacing, (float)y + spacing), stringFormat);
data.AppendFormat("{0} {1} {2} {3} {4} {5}\n", (int)c, currentPage, x, y, s.Width, s.Height);
x += s.Width;
}
}
g.Dispose();
bitmap.Save(string.Format(fileNameFormat, currentPage));
bitmap.Dispose();
File.WriteAllText(mapFileFormat, data.ToString());
Con esto, dibujó glifos blancos sobre un fondo transparente en un montón de archivos PNG e hizo un archivo de índice que le indica para cada punto de código, en qué archivo se encuentra el glifo, su ubicación y dimensiones. Tenga en cuenta que también pongo dos píxeles adicionales para separar cada glifo (para acomodar más efectos)
Ahora, para cada uno de esos archivos, lo pones en Photoshop y haces todos los filtros que quieras. Puede establecer colores, bordes, sombras, contornos y cualquier otra cosa que desee. Solo asegúrate de que los efectos no hagan que los glifos se superpongan. Si es así, ajuste el espacio, vuelva a renderizar, enjuague y repita. Guarde como PNG o DXT y, junto con el archivo de índice, coloque todo en su proyecto.
Dibujar texto debe ser muy simple. Para cada carácter que desee imprimir, encuentre su ubicación utilizando el índice, dibuje, avance la posición y repita. También puede ajustar el espaciado, el interletraje (complicado), el espaciado vertical e incluso el color. En lua:
function load_font(name)
local font = {}
font.name = name
font.height = 0
font.max_page = 0
font.glyphs = {}
font.pages = {}
font_definition = read_all_text("font/" .. name .. ".txt")
for codepoint, page, x, y, width, height in string.gmatch(font_definition, "(%d+) (%d+) (%d+) (%d+) (%d+) (%d+)") do
local page = tonumber(page)
local height_num = tonumber(height)
if height_num > font.height then
font.height = height_num
end
font.glyphs[tonumber(codepoint)] = { page=tonumber(page), x=tonumber(x), y=tonumber(y), width=tonumber(width), height=height_num }
if font.max_page < page then
font.max_page = page
end
end
for page = 1, font.max_page do
font.pages[page] = load_image("font/" .. name .. "_" .. page .. ".png")
end
return font
end
function draw_text(font, chars, range, initial_x, initial_y, width, color, spacing)
local x = initial_x - spacing
local y = initial_y - spacing
if range == nil then
range = { from=1, to=#chars }
end
for i = 1, range.to do
local char = chars[i]
local glyph = font.glyphs[char]
if char == 10 then -- line break
x = initial_x - spacing
y = y + ((font.height - (spacing * 2)) * 1.4)
elseif glyph == nil then
if unavailable_glyphs[char] == nil then
unavailable_glyphs[char] = true
end
else
if x + glyph.width - spacing > initial_x + width then
x = initial_x - spacing
y = y + ((font.height - (spacing * 2)) * 1.4)
end
if i >= range.from then
draw_sprite(font.pages[glyph.page], x, y, glyph.x, glyph.y, glyph.width, glyph.height, color)
end
x = x + glyph.width - (spacing * 2)
end
end
end
Y ahi tienes. Repita para cualquier otra fuente (y también el tamaño óptimo)
Editar : cambié el código para usarlo en Graphics.MeasureString
lugar de TextRenderer.MeasureText()
porque ambos usan diferentes sistemas de medición y pueden generar inconsistencias entre el glifo medido y el dibujado, especialmente con glifos sobresalientes que se encuentran en algunas fuentes. Más información aquí .