Mockup UI ke kode

17

Desainer UI saya telah membuat PSD photoshop yang bagus dari UI dan semuanya cantik. Masalah terbesar yang saya alami adalah mengubah beberapa font yang lebih elegan yang digunakan menjadi sesuatu yang dapat di-render dalam game. Apakah ada cara untuk mengubah gaya font ini di Photoshop ke jenis bitmap?

Saya harus dapat membuat teks seperti ini di dalam kode saya:

masukkan deskripsi gambar di sini

Vaughan Hilts
sumber
Sudahkah Anda memeriksa situs seperti ini? blogs.msdn.com/b/garykac/archive/2006/08/30/732007.aspx
ssb
Terima kasih banyak atas hadiahnya, tetapi saya perhatikan Anda tidak menandainya sebagai jawaban yang diterima. Apakah Anda tidak puas dengan jawabannya? Apakah Anda mengharapkan jenis jawaban yang berbeda? Saya merakit GUI game sebagai bagian dari pekerjaan saya, jadi saya pikir saya mungkin bisa menjawab pertanyaan Anda. Jangan sungkan untuk meminta klarifikasi atau penjelasan yang lebih menyeluruh jika Anda membutuhkannya.
Panda Pajama
Hanya pengawasan di pihak saya. :) Saya sudah memperbaiki ini sekarang. Nikmati dan terima kasih!
Vaughan Hilts

Jawaban:

18

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.Drawinguntuk 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.MeasureStringalih-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 .

Piyama Panda
sumber
2
Mengapa saya mendapat downvote tentang ini? Jika Anda akan melakukan downvote, tolong berikan komentar tentang kesalahan saya sehingga saya bisa memperbaikinya lain kali.
Panda Pajama
Bukan saya. Ini adalah jawaban mendalam yang sangat bagus. +1 :-)
Kromster berkata mendukung Monica
6

Seperti kata orang lain, di XNA, spritefont melakukan pekerjaan berat untuk Anda. di situs pembuat klub ada eksportir font bitmap yang mengekspor gambar font gaya XNA. ( http://xbox.create.msdn.com/en-US/education/catalog/utility/bitmap_font_maker ) Kemudian, Anda dapat membukanya di photoshop atau apa pun dan membuatnya terlihat cantik. Dari sana, Anda menambahkan tekstur ke proyek konten Anda, dan dalam jenis konten, pilih tekstur font sprite. Dalam kode Anda, Anda memuatnya seperti font sprite normal

(Contoh: http://www.youtube.com/watch?v=SynGWrWYUQI )

CobaltHex
sumber
Masalahnya adalah saya tidak begitu yakin bagaimana seseorang dapat mengambil gaya dari font Photoshop dan menerapkannya pada tekstur seperti ini.
Vaughan Hilts
Di sini, saya akan membuat video
CobaltHex
BMFont melakukan hal yang sama, tetapi menurut saya adalah program yang lebih baik. angelcode.com/products/bmfont
Cypher
eh, dengan mengekspor spritefont dasar, Anda dapat menyesuaikannya sesuka Anda di photoshop
CobaltHex
4

Solusinya cukup sederhana dan digunakan oleh sejumlah besar game. Yang harus Anda lakukan adalah memperlakukan font Anda seolah-olah itu adalah sprite.

Mintalah desainer Anda menggambar seluruh jajaran angka dan huruf yang ingin Anda gunakan dalam gim Anda. Kemudian render gambar tersebut ke berbagai gambar statis ukuran (.png, .bmp, format apa pun yang Anda gunakan). Anda akan memiliki sesuatu seperti ini:

masukkan deskripsi gambar di sini

Sekarang yang harus Anda lakukan adalah membuat setiap huruf dari "font sheet" Anda seolah-olah itu adalah sprite ke layar. Jelas membantu membangun kelas pembantu untuk menerjemahkan antara string dan sprite.

Implementasi saya lebih kompleks, tetapi praktis. Lembar font dibangun seperti gambar di atas dengan banyak font semua dalam satu file .png. Saya punya .inifile yang memetakan setiap huruf font ke posisi di lembar, bersama dengan lebar dan tinggi. Ini memungkinkan perancang saya (dan saya sendiri) membuat font keren tanpa harus menyentuh kode apa pun. Saat menggambar string ke layar, saya memiliki metode yang mencari font dan chardari .ini file untuk mendapatkan posisi dan batas-batas huruf dari lembar font, maka saya hanya menggambar Texture2Ddengan SpriteBatch.Draw()menggunakan sumber Rectanglehuruf dalam pertanyaan.

Nol
sumber
2

UI adalah subjek yang luas dan kompleks. Render font adalah bagian yang sulit. Saya menyarankan Anda untuk menggunakan perpustakaan yang sudah ada yang memungkinkan Anda untuk menampilkan konten Flash atau HTML dalam game, alih-alih mengulang semuanya sendiri.

Awesomium terlihat menjanjikan dan harus bekerja dengan XNA , jadi Anda bisa mencobanya. Ini gratis untuk digunakan untuk permainan non-komersial, atau jika Anda tidak menghasilkan banyak uang:

Gratis untuk Perusahaan Indie
    Jika perusahaan Anda menghasilkan kurang dari $ 100 ribu tahun lalu, Anda memenuhi syarat!
Gratis untuk Penggunaan Non-Komersial
Gratis untuk Evaluasi & Pengembangan

Laurent Couvidou
sumber
Itu ide yang sangat bagus - saya kira itu abstrak beberapa kode UI yang harus saya tulis juga. Saya akan mencobanya. Terima kasih!
Vaughan Hilts
Karena ini adalah port dari mesin Webkit Anda harus dapat melakukan sebagian besar gaya teks yang Anda butuhkan dengan CSS, termasuk garis besar stroke, drop shadow dan gradien.
ChrisC
itu adalah cara pengompleksan hanya untuk menggambar font
CobaltHex
1
@CobaltHex Saya telah melihat sikap ini berkali-kali dan begitu banyak UI manja yang diturunkan dari awal "yey mari kita buat UI dari awal pasti mudah, kita akan menemukan kembali roda sementara kita berada di sana" yang saya kembangkan muak. Sebagai latihan, periksa gambar mock-up OP, dan bayangkan Anda harus merender seluruh UI dengan gaya yang sama di beberapa platform, resolusi layar, dan rasio. Sekarang kebutuhan untuk UI yang tepat menjadi jelas, itu sebabnya saya mengambil kebebasan untuk mengirim jawaban ini, bahkan jika itu bukan solusi langsung untuk masalah yang diberikan.
Laurent Couvidou
Saya tidak mengatakan bahwa Anda membuat UI dari awal, tetapi jika Anda hanya ingin menggambar font, memasukkan seluruh mesin rendering agak berlebihan
CobaltHex
1

Jika Anda mencari efek yang lebih bagus daripada importir .spritefont biasa, Anda dapat mencoba mencari "generator font bitmap".

Secara pribadi saya lebih suka yang ini: http://www.ironstarmedia.co.uk/2010/01/free-game-dev-utility-fancy-bitmap-font-generator/

Beberapa ide lain:

  • Gunakan generator font bitmap dan kemudian edit bitmap yang dihasilkannya lebih lanjut di photoshop, dll.
  • Masukkan sebanyak mungkin teks statis ke dalam sprite yang telah dibuat. Kemudian isi hanya hal-hal seperti gamertag dan skor total menggunakan .spritefonts atau font yang dihasilkan dari generator font bitmap.
Nick
sumber
Saya pasti sudah melihatnya (dan ini sangat keren), tetapi saya berharap untuk secara langsung mengubah gaya teks Photoshop saya menjadi font bitmap yang dapat digunakan.
Vaughan Hilts
0

XNAmelakukan semua kerja keras untuk Anda. Dengan SpritefontAnda dapat dengan mudah mengkonversi file font pada mesin Anda menjadi jenis sprite sheet yang Anda tanyakan dengan mendefinisikan file XML.

Setelah Anda menambahkan file XML ke proyek Konten Anda memuatnya dengan ContentManager:

ContentManager.Load<SpriteFont>(@"MyFont");

Berikut adalah contoh file .spritefont dari proyek konten saya:

<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains an xml description of a font, and will be read by the XNA
Framework Content Pipeline. Follow the comments to customize the appearance
of the font in your game, and to change the characters which are available to draw
with.
-->
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
<Asset Type="Graphics:FontDescription">

    <!--
Modify this string to change the font that will be imported.
//TODO: A different font should be chosen before shipping for licensing reasons
-->
    <FontName>Pericles</FontName>

    <!--
Size is a float value, measured in points. Modify this value to change
the size of the font.
-->
    <Size>8.5</Size>

    <!--
Spacing is a float value, measured in pixels. Modify this value to change
the amount of spacing in between characters.
-->
    <Spacing>0</Spacing>

    <!--
UseKerning controls the layout of the font. If this value is true, kerning information
will be used when placing characters.
-->
    <UseKerning>true</UseKerning>

    <!--
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
and "Bold, Italic", and are case sensitive.
-->
    <Style>Bold</Style>

    <!--
If you uncomment this line, the default character will be substituted if you draw
or measure text that contains characters which were not included in the font.
-->
    <DefaultCharacter>@</DefaultCharacter>

    <!--
CharacterRegions control what letters are available in the font. Every
character from Start to End will be built and made available for drawing. The
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
character set. The characters are ordered according to the Unicode standard.
See the documentation for more information.
-->
    <CharacterRegions>
        <CharacterRegion>
            <Start>&#32;</Start>
            <End>&#126;</End>
        </CharacterRegion>
        <CharacterRegion>
            <Start>&#9;</Start>
            <End>&#9;</End>
        </CharacterRegion>
    </CharacterRegions>
</Asset>
</XnaContent>
Jim
sumber
1
Masalahnya adalah ini hanya font TrueType. Saya perlu font bitmap atau sesuatu dengan sejenisnya dengan semua dropshadow saya, glows dan sejenisnya masih diterapkan.
Vaughan Hilts
Lihat hasil edit saya, font seperti ini: i.imgur.com/VaBpQ.png
Vaughan Hilts
0

Saya tidak yakin karena saya tidak pernah menggunakannya tetapi orang menyarankan saya untuk menggunakan Glyph Designer. Berikut ini adalah video tutorialnya:

http://vimeo.com/32777161

Di sini ada diskusi tentang itu menyebutkan photoshop.

Ada orang yang menggunakan juga editor font Hiero .

Di situs web ini ada daftar editor font lain yang mungkin ingin Anda lihat.

Beritahu saya yang mana yang paling cocok untuk Anda :)

mm24
sumber