Oke, Anda harus memaafkan saya karena tidak memberi Anda kode XNA spesifik, karena saya tidak berpengetahuan luas di platform itu, tetapi apa yang akan saya katakan adalah Anda harus bekerja pada mesin game apa pun yang memungkinkan Anda menggambar sprite.
Font bukan satu-satunya masalah Anda, jadi saya akan memberi Anda saran, dan kemudian saya akan menjawab pertanyaan Anda. Dengan dua hal ini, Anda harus dapat membuat hubungan mesra dengan desainer GUI Anda, dan Anda berdua akan dapat dengan sangat senang membuat game.
Hal pertama adalah Anda akan duduk bersama desainer Anda, dan Anda akan memintanya memberi Anda dua set file. Yang pertama adalah satu set file transparan yang membentuk GUI Anda (secara optimal dalam format PSD atau DXT). Untuk setiap tombol, label tetap, latar belakang, batas dan kotak teks, Anda akan mendapatkan satu file (Anda juga dapat melakukan tekstur atlasing, tapi saya sarankan Anda melakukannya setelah Anda merakit GUI Anda, dan kemudian sesuaikan koordinat sumber Anda ketika blitting). Teks non-statis harus ditinggalkan pada saat ini (saya akan mengunjungi lagi nanti).
Hal kedua yang akan Anda dapatkan adalah desain GUI yang sebenarnya, kali ini dalam format Photoshop. Untuk file ini, Anda akan meminta desainer Anda untuk membuat seluruh desain GUI, hanya menggunakan file yang dia berikan sebelumnya.
Dia kemudian akan menempatkan setiap elemen GUI ke dalam lapisan yang terpisah, tanpa menggunakan efek apa pun. Anda akan memberitahunya untuk melakukan pixel ini dengan sempurna, karena lokasi di mana dia akan meletakkan semuanya, adalah di mana semuanya akan benar-benar ada dalam permainan yang diselesaikan.
Setelah Anda mendapatkan itu, untuk setiap lapisan, Anda akan menekan Ctrl-T, dan pada panel Info (F8), Anda akan mencatat koordinat X dan Y untuk setiap elemen. Pastikan unit Anda disetel ke piksel (Preferensi-> Unit & Penguasa-> Unit). Ini adalah posisi yang akan Anda gunakan saat menggambar sprite Anda.
Sekarang, untuk font, seperti yang mungkin Anda ketahui dengan jelas sekarang, Anda tidak akan bisa membuat font Anda terlihat persis seperti yang Anda lihat di Photoshop menggunakan API rendering teks. Anda harus melakukan pra-render mesin terbang Anda, dan kemudian secara sistematis mengumpulkan teks Anda. Ada banyak cara untuk melakukan ini, dan saya akan menyebutkan yang saya gunakan.
Hal pertama adalah membuat semua mesin terbang Anda menjadi satu atau lebih file. Jika Anda hanya peduli dengan bahasa Inggris, satu tekstur untuk semua mesin terbang akan cukup, tetapi jika Anda ingin memiliki rangkaian karakter yang lebih luas, Anda dapat menggunakan beberapa file. Pastikan semua mesin terbang yang Anda inginkan tersedia pada font yang Anda pilih.
Jadi, untuk membuat mesin terbang, Anda dapat menggunakan fasilitas System.Drawing
untuk mendapatkan metrik font dan menggambar mesin terbang Anda:
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());
Dengan ini, Anda telah menggambar mesin terbang putih di atas latar belakang transparan pada sekelompok file PNG, dan membuat file indeks yang memberitahu Anda untuk masing-masing codepoint, di mana file mesin terbang itu berada, lokasi dan dimensinya. Perhatikan bahwa saya juga meletakkan dua piksel tambahan untuk memisahkan setiap mesin terbang (untuk mengakomodasi efek lebih lanjut)
Sekarang, untuk setiap file itu, Anda meletakkannya di photoshop, dan lakukan semua filter yang Anda inginkan. Anda dapat mengatur warna, batas, bayangan, garis besar, dan apa pun yang Anda inginkan. Pastikan saja bahwa efeknya tidak membuat mesin terbang tumpang tindih. Jika demikian, sesuaikan jarak, render ulang, bilas, dan ulangi. Simpan sebagai PNG atau DXT, dan bersama dengan file indeks, letakkan semuanya di proyek Anda.
Menggambar teks harus sangat sederhana. Untuk setiap karakter yang ingin Anda cetak, temukan lokasinya menggunakan indeks, gambarkan, naikkan posisi dan ulangi. Anda juga dapat menyesuaikan jarak, kerning (rumit), jarak vertikal, dan bahkan pewarnaan. Dalam 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
Dan begitulah. Ulangi untuk setiap font lain (dan ukuran optimal juga)
Sunting : Saya mengubah kode yang akan digunakan Graphics.MeasureString
alih-alih TextRenderer.MeasureText()
karena mereka berdua menggunakan sistem pengukuran yang berbeda, dan dapat menyebabkan ketidakkonsistenan antara mesin terbang yang diukur dan yang ditarik, terutama dengan mesin terbang yang menggantung ditemukan di beberapa font. Informasi lebih lanjut di sini .