Пользовательский интерфейс макеты для кода


17

Мой дизайнер UI сделал прекрасный PSD для фотошопа из UI, и все красиво. Самая большая проблема, с которой я сталкиваюсь, - это преобразование некоторых из более элегантных шрифтов, используемых во что-то визуализируемое в игре. Есть ли способ конвертировать эти стили шрифтов в Photoshop в какой-нибудь растровый шрифт?

Мне нужно иметь возможность визуализировать текст в моем коде:

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


Вы проверили сайты, как это? blogs.msdn.com/b/garykac/archive/2006/08/30/732007.aspx
ssb

Большое спасибо за награду, но я заметил, что вы не отметили это как принятый ответ. Вы недовольны ответом? Вы ожидали другого типа ответа? Я собираю игровые графические интерфейсы как часть своей повседневной работы, поэтому думаю, что смогу ответить на ваши вопросы. Не стесняйтесь просить разъяснений или более подробных объяснений, если вам это нужно.
Панда Пижама

Просто недосмотр с моей стороны. :) Я исправил это сейчас. Наслаждайтесь и спасибо!
Вон Хилтс

Ответы:


18

Хорошо, вам придется простить меня за то, что я не предоставил вам конкретный код XNA, потому что я не разбираюсь в этой платформе, но то, что я собираюсь сказать, должно работать на любом игровом движке, который позволяет рисовать спрайты.

Шрифты - не единственная ваша проблема, поэтому я дам вам совет, а затем я отвечу на ваш вопрос. С этими двумя вещами вы сможете установить дружеские отношения с вашим дизайнером GUI, и вы оба сможете очень счастливо делать игры.

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

Второе, что вы получите, это фактический дизайн графического интерфейса, на этот раз в формате Photoshop. Для этого файла вы попросите своего дизайнера сделать весь дизайн графического интерфейса, используя только те файлы, которые она вам ранее предоставила.

Затем она собирается поместить каждый элемент графического интерфейса в отдельный слой, без каких-либо эффектов. Вы скажете ей сделать этот пиксель идеальным, потому что места, где она собирается все поместить, это то, где все будет на самом деле в финальной игре.

Как только вы получите это, для каждого слоя вы нажмете Ctrl-T, и на информационной панели (F8) вы запомните координаты X и Y для каждого элемента. Убедитесь, что ваши единицы установлены в пикселях (Preferences-> Units & Rulers-> Units). Это позиции, которые вы собираетесь использовать при рисовании своих спрайтов.

Теперь, что касается шрифтов, как вы, наверное, уже сейчас знаете, вы не сможете заставить свои шрифты выглядеть точно так же, как вы видите их в 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 и создали индексный файл, который сообщает вам для каждой кодовой точки, в каком файле находится глиф, его местоположение и размеры. Обратите внимание, что я также поместил два дополнительных пикселя, чтобы отделить каждый глиф (чтобы обеспечить дальнейшие эффекты)

Теперь для каждого из этих файлов вы помещаете его в фотошоп и выполняете все необходимые фильтры. Вы можете установить цвета, границы, тени, контуры и все, что вы хотите. Просто убедитесь, что эффекты не перекрывают глифы. Если это так, отрегулируйте интервал, выполните повторную визуализацию, промойте и повторите. Сохраните как 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
Почему я получил отрицательный голос по этому поводу? Если вы собираетесь понизить голос, пожалуйста, по крайней мере, прокомментируйте, что я сделал неправильно, чтобы я мог исправить это в следующий раз.
Панда Пижама

Не я. Это отличный всесторонний ответ. +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 и применить их к такой текстуре.
Вон Хилтс

Здесь я сделаю видео
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 тысяч долларов в прошлом году, вы подходите!
Бесплатно для некоммерческого использования
Бесплатно для оценки и разработки


Это довольно изящная идея - я предполагаю, что она абстрагирует часть кода пользовательского интерфейса, который я должен написать. Я попробую. Благодарность!
Вон Хилтс

Поскольку это порт движка Webkit, вы должны иметь возможность выполнять большинство стилей текста, которые вам нужны, с помощью CSS, включая контуры обводки, тени и градиенты.
ChrisC

это слишком сложно для простого рисования шрифтов
CobaltHex

1
@CobaltHex Я видел такое отношение столько раз и столько испорченного пользовательского интерфейса, который возник из первоначального «да, давайте сделаем пользовательский интерфейс с нуля, это должно быть легко, мы изобретем колесо, пока мы на нем», которое я вырастил надоело. В качестве упражнения проверьте макет OP и представьте, что вам нужно визуализировать весь интерфейс в одном стиле на нескольких платформах, разрешениях экрана и соотношениях. Теперь необходимость в правильном пользовательском интерфейсе становится понятной, поэтому я позволил себе опубликовать этот ответ, даже если это не является прямым решением данной проблемы.
Лоран Кувиду

Я не говорю, что вы создаете пользовательский интерфейс с нуля, но если вы просто хотите нарисовать шрифт, вставка всего движка рендеринга немного
излишня

1

Если вы ищете более причудливые эффекты, чем обычный импортер .spritefont, попробуйте поискать «генератор растровых шрифтов».

Лично я предпочитаю этот: http://www.ironstarmedia.co.uk/2010/01/free-game-dev-utility-fancy-bitmap-font-generator/

Некоторые другие идеи:

  • Используйте генератор растровых шрифтов, а затем отредактируйте растровое изображение, которое оно создает в фотошопе и т. Д.
  • Поместите как можно больше статического текста в предварительно нарисованные спрайты. Затем заполните только такие вещи, как теги игрока и подсчитайте итоги, используя .spritefonts или шрифты, сгенерированные из генератора растровых шрифтов.

Я определенно видел это (и это очень круто, между прочим), но я надеялся напрямую превратить мои стили текста в Photoshop в пригодные для использования растровые шрифты.
Вон Хилтс

0

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

Как только вы добавите XML-файл в ваш проект Content, загрузите его с 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. Мне нужны растровые шрифты или что-то подобное с тем, что все мои тени, свечения и тому подобное еще применяются.
Вон Хилтс

Смотрите мои правки, шрифт (ы), например: i.imgur.com/VaBpQ.png
Vaughan Hilts

0

Я не уверен, поскольку я никогда не использовал это, но люди предложили мне использовать Glyph Designer. Вот видеоурок:

http://vimeo.com/32777161

Здесь идет обсуждение упоминания фотошопа.

Есть люди, использующие также редактор шрифтов Hiero .

На этом сайте есть список других редакторов шрифтов, которые вы можете посмотреть.

Дайте мне знать, какой из них лучше всего подходит для вас :)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.