Макет інтерфейсу користувача до коду


17

Мій дизайнер інтерфейсу зробив прекрасний PSD-інтерфейс для Photoshop і все прекрасне. Найбільшою проблемою у мене є перетворення деяких більш елегантних шрифтів, які використовуються, у щось, що можна відтворити в грі. Чи є спосіб перетворити ці стилі шрифту у Photoshop в якийсь шрифт растрових зображень?

Мені потрібно мати можливість відобразити такий текст всередині свого коду:

введіть тут опис зображення


Ви перевіряли подібні сайти? blogs.msdn.com/b/garykac/archive/2006/08/30/732007.aspx
ssb

Дуже дякую за нагороду, але я помітив, що ви не позначили це як прийняту відповідь. Ви незадоволені відповіддю? Ви очікували відповіді іншого типу? Я збираю графічні інтерфейси ігор як частину своєї денної роботи, тому думаю, що я можу відповісти на ваші запитання. Не соромтеся запитувати роз'яснення або більш детальні пояснення, якщо це потрібно.
Піжама Panda

Просто нагляд з мого боку. :) Я це зараз виправив. Насолоджуйтесь і дякую!
Vaughan Hilts

Відповіді:


18

Гаразд, вам доведеться пробачити мене за те, що я не дав вам конкретного коду XNA, тому що я не знаю на цій платформі, але те, що я вам скажу, має працювати над будь-яким ігровим двигуном, який дозволяє малювати спрайти.

Шрифти - не єдина ваша проблема, тому я збираюся дати вам поради, а потім я відповім на ваше запитання. Завдяки цим двом речам, ви зможете скласти прекрасні стосунки зі своїм дизайнером GUI, і ви обоє зможете дуже щасливо робити ігри.

Перше, що ти збираєшся сісти з дизайнером, і ти попросиш її надати два набори файлів. Перший - це набір прозорих файлів, які складають ваш графічний інтерфейс (оптимально у форматі PSD або DXT). Для кожної кнопки, фіксованої мітки, фону, рамки та текстового поля ви отримаєте один файл (ви також можете виконати атласування текстури, але я б рекомендував це зробити після того, як ви збираєте графічний інтерфейс, а потім налаштовуєте вихідні координати при блиску). На даний момент нестатичний текст повинен бути опущений (я його перегляну пізніше).

Друге, що ви отримаєте - це власне дизайн GUI, на цей раз у форматі Photoshop. Для цього файлу ви попросите свого дизайнера скласти весь дизайн GUI, використовуючи лише ті файли, які вона вам раніше надала.

Потім вона збирається розмістити кожен елемент GUI в окремому шарі, не використовуючи жодних ефектів. Ви збираєтесь сказати їй зробити цей піксель ідеальним, адже місця, де вона збирається все поставити, - це там, де все буде фактично в завершеній грі.

Як тільки ви зрозумієте, що для кожного шару ви натискаєте Ctrl-T, а на панелі інформації (F8) ви візьмете до уваги координати X і Y для кожного елемента. Переконайтеся, що для ваших одиниць встановлено пікселі (Налаштування-> Одиниці та лінійки-> Одиниці). Це пози, які ви будете використовувати під час малювання своїх спрайтів.

Тепер для шрифтів, як ви, очевидно, знаєте зараз, ви не зможете змусити ваші шрифти виглядати точно так само, як ви бачите їх у Photoshop за допомогою API-редагування тексту. Вам доведеться заздалегідь віддати свої гліфи, а потім програматично зібрати свої тексти. Є багато способів зробити це, і я згадаю той, який я використовую.

Перше - передати всі свої гліфи в один або кілька файлів. Якщо ви хвилюєтесь лише англійською мовою, однієї текстури для всіх гліфів буде достатньо, але якщо ви хочете мати більш розширений набір символів, ви можете використовувати кілька файлів. Просто переконайтеся, що всі гліфи, які ви хочете, доступні для шрифту, який обрав ваш дизайнер.

Отже, для візуалізації гліфів ви можете використовувати засоби System.Drawingдля отримання метрики шрифту та малювання своїх гліфів:

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

За допомогою цього ви намалювали білі гліфи над прозорим фоном на купі файлів PNG та створили індексний файл, який повідомляє вам про кожну кодову точку, у якому файлі знаходиться гліф, його місцезнаходження та розміри. Зауважте, що я також поклав два додаткові пікселі, щоб розділити кожен гліф (для отримання подальших ефектів)

Тепер для кожного з цих файлів ви помістите його в Photoshop і зробіть усі потрібні фільтри. Ви можете встановити кольори, межі, тіні, контури та все, що завгодно. Просто переконайтеся, що наслідки не дозволяють гліфам перекриватися. Якщо так, відрегулюйте відстань, повторіть, промийте та повторіть. Збережіть як PNG або DXT, а разом з індексним файлом покладіть усе на свій проект.

Малювання тексту має бути дуже простим. Для кожного знаку, який ви хочете роздрукувати, знайдіть його розташування за допомогою індексу, намалюйте його, просуньте позицію та повторіть. Ви також можете налаштувати інтервали, кернінг (хитрість), вертикальний інтервал і навіть забарвлення. У луа:

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

І ось ти йдеш. Повторіть для кожного іншого шрифту (і оптимального розміру також)

Редагувати : Я змінив код, який потрібно використовувати Graphics.MeasureStringзамість того, TextRenderer.MeasureText()що вони обидва використовують різні системи вимірювання, і це може призвести до невідповідностей між вимірюваним гліфом та намальованим, особливо з перекритими гліфами, знайденими в деяких шрифтах. Більше інформації тут .


2
Чому я отримав протиріччя з цього приводу? Якщо ви збираєтесь звернутись до голосування, будь-ласка, будь-ласка, дайте коментарі щодо того, що я зробив не так, щоб я можу це виправити наступного разу.
Піжама Panda

Не я. Це відмінна глибока відповідь. +1 :-)
Кромстер каже, що підтримує Моніку

6

Ну, як хтось сказав, у XNA spritefont робить важкий підйом для вас. на веб-сайті клубу творців є експортер шрифтів растрових зображень, який експортує зображення у форматі шрифту XNA. ( http://xbox.create.msdn.com/en-US/education/catalog/utility/bitmap_font_maker ) Потім ви можете відкрити його у фотошопі чи будь-якому іншому та зробити його гарним. Звідти ви додаєте текстуру до свого змістового проекту, а в типі вмісту вибираєте текстуру шрифту спрайту. У своєму коді ви завантажуєте його як звичайний шрифт спрайту

(Приклад: http://www.youtube.com/watch?v=SynGWrWYUQI )


Проблема в тому, що я не зовсім впевнений, як можна взяти стилі з шрифту Photoshop і застосувати їх до такої текстури.
Vaughan Hilts

Тут я зроблю відео
CobaltHex


BMFont робить те саме, але, на мою думку, це краща програма. angelcode.com/products/bmfont
Cypher

ех, експортуючи базовий spritefont, ви можете налаштувати його як завгодно у фотошопі
CobaltHex

4

Рішення досить просте і використовується великою кількістю ігор. Все, що вам потрібно зробити - це ставитися до своїх шрифтів так, ніби вони були спрайтами.

Попросіть ваш дизайнер намалювати весь діапазон цифр і букв, які ви хочете використовувати у своїй грі. Потім відтворіть їх у статичні зображення різного розміру (.png, .bmp, незалежно від формату). У вас вийде щось подібне:

введіть тут опис зображення

Тепер все, що вам потрібно зробити, - це передати кожну букву зі свого "аркуша шрифту" так, ніби це спрайт на екран. Це, безумовно, допомагає побудувати клас помічників для перекладу між рядками та спрайтами.

Моя реалізація є більш складною, але зручною. Аркуш шрифту побудований, як на зображенні вище, з декількома шрифтами, всі в одному .png-файлі. У мене є .iniфайл, який відображає букву кожного шрифту на місце на аркуші, разом із його шириною та висотою. Це дозволяє моєму дизайнеру (і мені самому) збивати гайки, створюючи круті шрифти, не торкаючись жодного коду. При малюванні рядки на екрані, у мене є метод , який дивиться шрифт і charз INI - файлу , щоб отримати положення і кордони листи з листа шрифту, то я просто Намалюйте Texture2DзSpriteBatch.Draw() допомогою джерела Rectangleлисти розглянутий.


2

Інтерфейс користувача - це величезна і складна тема. Відображення шрифту - складна частина. Раджу використовувати вже існуючу бібліотеку, яка дозволяє відображати Flash або HTML вміст у грі, а не переробляти все самостійно.

Awesomium виглядає багатообіцяючим і повинен працювати з XNA , тому ви можете спробувати. Це безкоштовно для використання в некомерційних іграх або якщо ви не заробляєте багато грошей:

Безкоштовно для компаній Інді
    Якщо у минулому році ваша компанія заробила менше 100 тис. Доларів, ви можете отримати право!
Безкоштовно для некомерційного використання
Безкоштовно для оцінки та розвитку


Це досить витончена ідея - я думаю, вона також абстрагує частину коду інтерфейсу, який я повинен написати. Я спробую. Спасибі!
Vaughan Hilts

Оскільки це порт двигуна Webkit, ви повинні мати можливість виконувати більшість потрібних текстових стилів за допомогою CSS, включаючи контури обведення, тіні та градієнти.
ChrisC

це шлях над ускладненням для простого малювання шрифтів
CobaltHex

1
@CobaltHex Я так багато разів бачив таке ставлення і стільки зіпсованого інтерфейсу, що випливав із початкового "так, давайте зробимо інтерфейс з нуля. Це повинно бути легко, ми будемо винаходити колесо, поки ми на ньому", що я виріс набридло. Як вправу, перевірте макет зображення OP і уявіть, що вам потрібно зробити цілий інтерфейс у тому ж стилі на кількох платформах, роздільній здатності екрана та співвідношенні. Тепер необхідність у належному інтерфейсі стає зрозумілою, тому я взяв на себе сміття опублікувати цю відповідь, навіть якщо це не є прямим рішенням даної проблеми.
Лоран Кувіду

Я не кажу, що ви створюєте користувальницький інтерфейс з нуля, але якщо ви просто хочете намалювати шрифт, вставлення цілого механізму візуалізації трохи
непосильне

1

Якщо ви шукаєте більш фантазійні ефекти, ніж звичайний імпортер .spritefont, можете спробувати знайти "генератор шрифтів растрових зображень".

Особисто я віддаю перевагу цьому: http://www.ironstarmedia.co.uk/2010/01/free-game-dev-utility-fancy-bitmap-font-generator/

Деякі інші ідеї:

  • Використовуйте генератор шрифтів растрових зображень, а потім відредагуйте растрові карти, які він створює далі, у Photoshop тощо.
  • Покладіть якомога більше статичного тексту в попередньо намальовані спрайти. Потім заповніть такі речі, як ігрові позначки та наберіть підсумки, використовуючи .spritefonts або шрифти, створені з генератора шрифтів растрових зображень.

Я напевно це бачив (і це, до речі, дуже круто), але я сподівався безпосередньо перетворити свої текстові стилі Photoshop в зручні шрифти растрових зображень.
Вуан Хілтс

0

XNAробить усе важке для вас. За допомогою Spritefontвас можна легко перетворити файл шрифту на вашій машині у тип спрайту, про який ви запитуєте, визначивши файл XML.

Коли ви додасте XML-файл до свого проекту вмісту, завантажте його ContentManager:

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

Ось приклад файлу .spritefont з мого вмістового проекту:

<?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>

1
Проблема в тому, що це просто звичайні шрифти TrueType. Мені потрібні растрові шрифти чи щось подібне з усіма моїми сенсорами, світіннями тощо.
Vaughan Hilts

Дивіться мої редагування, такі шрифти: i.imgur.com/VaBpQ.png
Vaughan

0

Я не впевнений, як ніколи не користувався ним, але люди запропонували мені використовувати дизайнер Glyph. Ось відеоурок:

http://vimeo.com/32777161

Тут йде дискусія з згадування про фотошоп.

Є люди, які також використовують редактор шрифтів Hiero .

На цьому веб-сайті є список інших редакторів шрифтів, які ви хочете переглянути.

Дайте мені знати, який із вас найкраще працює :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.