私のUIデザイナーは、UIの素敵なPhotoshop PSDを作成しました。私が抱えている最大の問題は、使用されているよりエレガントなフォントをゲーム内でレンダリング可能なものに変換することです。Photoshopでこれらのフォントスタイルを何らかのビットマップフォントに変換する方法はありますか?
コード内でこのようなテキストをレンダリングできるようにする必要があります。
私のUIデザイナーは、UIの素敵なPhotoshop PSDを作成しました。私が抱えている最大の問題は、使用されているよりエレガントなフォントをゲーム内でレンダリング可能なものに変換することです。Photoshopでこれらのフォントスタイルを何らかのビットマップフォントに変換する方法はありますか?
コード内でこのようなテキストをレンダリングできるようにする必要があります。
回答:
わかりました、あなたは特定のXNAコードを与えないことを許さなければならないでしょう、なぜなら私はそのプラットフォームに精通していないからです。
フォントだけが問題ではないので、私はあなたにアドバイスをします。そして、あなたの質問に答えます。これら2つのことで、GUIデザイナーとラブラブな関係を築くことができるはずです。そして、あなたとお二人はとても楽しくゲームを作ることができます。
最初に、デザイナーと一緒に座って、2セットのファイルを提供するように依頼します。1つ目は、GUIを構成する透明なファイルのセットです(PSDまたはDXT形式が最適です)。すべてのボタン、固定ラベル、背景、境界線、およびテキストボックスに対して、1つのファイルを取得します(テクスチャアトラス作成も実行できますが、GUIを組み立ててから、ブリッティング時にソース座標を調整することをお勧めします)。この時点では、非静的テキストは除外する必要があります(これについては後で説明します)。
2つ目は、実際のGUIデザインです。今回はPhotoshop形式です。このファイルについては、以前に与えたファイルのみを使用して、デザイナーにGUIデザイン全体を作成するように依頼します。
次に、彼女は各GUI要素を個別のレイヤーに配置し、効果は一切使用しません。彼女がすべてを配置する場所は、ファイナライズされたゲームですべてが実際に行われる場所であるため、このピクセルを完璧に実行するように彼女に指示します。
それが得られたら、レイヤーごとにCtrl-Tを押し、情報ペイン(F8)で各要素のXおよびY座標をメモします。ユニットがピクセルに設定されていることを確認してください(設定->ユニットとルーラー->ユニット)。これらは、スプライトを描画するときに使用する位置です。
フォントについては、ご存じのとおり、テキストレンダリングAPIを使用してPhotoshopでフォントを表示する場合とまったく同じようにフォントを表示することはできません。グリフを事前にレンダリングしてから、プログラムでテキストを組み立てる必要があります。これを行うには多くの方法がありますが、私が使用する方法について言及します。
まず、すべてのグリフを1つ以上のファイルにレンダリングします。英語のみを気にする場合は、すべてのグリフに対して1つのテクスチャで十分ですが、より拡張された文字セットが必要な場合は、複数のファイルを使用できます。必要なすべてのグリフが、デザイナーが選択したフォントで利用できることを確認してください。
したがって、グリフをレンダリングするには、の機能を使用し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ファイルの束の透明な背景に白いグリフを描画し、各コードポイント、グリフが配置されているファイル、その場所、および寸法を示すインデックスファイルを作成しました。また、各グリフを分離するために2つの追加ピクセルを配置していることに注意してください(さらなる効果に対応するため)
さて、これらのファイルのそれぞれについて、Photoshopに入れて、必要なすべてのフィルターを実行します。色、境界線、影、アウトライン、その他必要なものを設定できます。効果によってグリフが重ならないようにしてください。その場合、間隔を調整し、再レンダリングし、すすぎ、繰り返します。PNGまたはDXTとして保存し、インデックスファイルとともに、すべてをプロジェクトに入れます。
テキストの描画は非常にシンプルでなければなりません。印刷する文字ごとに、インデックスを使用してその位置を見つけ、それを描画し、位置を進めて繰り返します。間隔、カーニング(トリッキー)、垂直方向の間隔、さらには色を調整することもできます。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
そしてそこに行きます。他のすべてのフォントについて繰り返します(最適なサイズも)
編集:両方が異なる測定システムを使用するため、Graphics.MeasureString
代わり に使用するコードを変更しTextRenderer.MeasureText()
、測定されたグリフと描画されたグリフ、特に一部のフォントにあるオーバーハンググリフとの不一致につながる可能性があるためです。詳細はこちら。
他の誰かが言ったように、XNAではspritefontがあなたのために大変な仕事をします。クリエーターズクラブのWebサイトには、XNAスタイルのフォント画像でエクスポートするビットマップフォントエクスポーターがあります。( http://xbox.create.msdn.com/en-US/education/catalog/utility/bitmap_font_maker)その後、Photoshopなどで開いて見栄えを良くすることができます。そこから、コンテンツプロジェクトにテクスチャを追加し、コンテンツタイプでスプライトフォントテクスチャを選択します。コードでは、通常のスプライトフォントのようにロードします
ソリューションは非常にシンプルであり、多くのゲームで使用されています。あなたがしなければならないのは、あたかもスプライトであるかのようにフォントを扱うことです。
ゲームで使用したい数字と文字の全範囲をデザイナーに描いてもらいます。次に、さまざまなサイズの静的画像(.png、.bmp、使用する形式)にレンダリングします。次のようなものがあります。
あとは、「フォントシート」の各文字を画面のスプライトのようにレンダリングするだけです。文字列とスプライトの間を変換するヘルパークラスを構築することは確かに役立ちます。
私の実装はより複雑ですが、便利です。フォントシートは、複数のフォントがすべて1つの.pngファイルに含まれている上記の画像のように構築されています。.ini
各フォントの文字をその幅と高さとともにシート上の位置にマップするファイルがあります。これにより、デザイナー(および私)は、コードに触れることなくクールなフォントを作成できます。画面に文字列を描画するとき、フォントとchar
.iniファイルからルックアップしてフォントシートから文字の位置と境界を取得するメソッドがあり、その後、文字のソースTexture2D
をSpriteBatch.Draw()
使用して描画しますRectangle
問題です。
UIは広大で複雑なテーマです。フォントのレンダリングは難しい部分です。すべてを自分でやり直すのではなく、ゲーム内でFlashまたはHTMLコンテンツを表示できる既存のライブラリを使用することをお勧めします。
Awesomiumは有望に見え、XNAで動作するはずなので、試してみてください。非営利的なゲームで使用したり、大量のお金を稼いでいない場合は無料です。
インディーズ企業向け無料
昨年の企業の収益が10万ドル未満の場合、資格があります!
非商用利用は
無料、評価と開発は無料
プレーンな.spritefontインポーターよりもより洗練された効果を探している場合は、「ビットマップフォントジェネレーター」を検索してみてください。
個人的に私はこれを好む:http : //www.ironstarmedia.co.uk/2010/01/free-game-dev-utility-fancy-bitmap-font-generator/
他のアイデア:
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> </Start>
<End>~</End>
</CharacterRegion>
<CharacterRegion>
<Start>	</Start>
<End>	</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>
使用したことがないのでわかりませんが、人々はGlyph Designerを使用するように提案しました。ビデオチュートリアルは次のとおりです。
ここに で議論があります Photoshopに言及します。
Hieroフォントエディタも使用している人がいますます。
では、このウェブサイトあなたが見てしたい場合があり、他のフォントエディタのリストがあります。
どちらがあなたに最適か教えてください:)