コンテンツにスキップ

勉強会 5 コマ目(テキストの表示)

1. 文字列のフォーマット

1.1 文字列の中に変数の値をいれる

U"{}"_fmt(x) と書くと、{} には値 x を文字列にしたものが入ります。

U"{} 月 {} 日"_fmt(12, 31)U"12 月 31 日" という文字列になります。

# include <Siv3D.hpp>

void Main()
{
	int32 score = 1234;

	Print << U"スコア: {}"_fmt(score);

	int32 month = 12;

	int32 day = 31;

	Print << U"今日は {} 月 {} 日"_fmt(month, day);

	while (System::Update())
	{

	}
}

1.2 小数点以下の桁数を指定して変換する

double 型の値 x を、小数点以下の桁数を指定して変換する場合、U"{:.2f}"_fmt(x) のように書きます(この場合小数点以下 2 桁)。

小数点以下を表示しない場合は U"{:.0f}"_fmt(x) とします。

# include <Siv3D.hpp>

void Main()
{
	double x = 123.4567;

	Print << x;

	Print << U"{}"_fmt(x);

	Print << U"{:.2f}"_fmt(x);

	Print << U"{:.0f}"_fmt(x);

	while (System::Update())
	{

	}
}

2. テキストを表示する

2.1 テキストの自由な表示

好きな位置に好きな色でテキストを表示したい場合は、Font クラスを使います。まず、メインループの前に Font 変数名{ FontMethod::MSDF, 48 }; でフォントを作成します。フォントの作成はコストがかかるため、メインループの前で行います。

作成したフォント font を使って、

  • font(テキスト).draw(サイズ, x, y, color);
  • font(テキスト).draw(サイズ, pos, color);
    • posVec2{ x, y } で、Vec2 は 2 次元の座標を表すクラスです。

のようにして、テキストを、サイズ、位置、色を指定して表示します。color を省略すると白色になります。「テキスト」の部分は、文字列以外に数値などもそのまま渡せます。

# include <Siv3D.hpp>

void Main()
{
	Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });

	const Font font{ FontMethod::MSDF, 48 };

	int32 count = 0;

	while (System::Update())
	{
		font(U"C++").draw(50, Vec2{ 100, 100 }, Palette::Black);

		font(U"Siv{}D"_fmt(count)).draw(80, Vec2{ 200, 200 }, ColorF{ 0.2, 0.6, 0.9 });

		font(U"こんにちは").draw(25, Vec2{ 100, 400 }, ColorF{ 0.4 });

		font(count).draw(50, Vec2{ 300, 500 });

		++count;
	}
}
フォントの品質

FontMethod::MSDF 方式でフォントを作成するときの 48 は、フォントデータの詳細度を表しています。この値は実行時性能とのトレードオフです。詳細度を大きくすると、メモリ消費が増加して処理時間が増えます。小さくすると、複雑な字形の文字の描画品質が低下する場合があります。漢字の場合は 48 がバランスの取れた値です。英数字のみの場合は 32 でも十分です。

2.2 太文字のテキスト

太文字のフォントは Font 変数名{ FontMethod::MSDF, 48, Typeface::Bold }; で作成します。2.1 のような通常のフォントでは Typeface::Regular が指定されています。

# include <Siv3D.hpp>

void Main()
{
	Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });

	const Font regularFont{ FontMethod::MSDF, 48 }; // Typeface::Regular

	// 太文字のフォント
	const Font boldFont{ FontMethod::MSDF, 48, Typeface::Bold };

	while (System::Update())
	{
		regularFont(U"Hello, Siv3D!").draw(50, Vec2{ 100, 100 }, ColorF{ 0.3 });

		boldFont(U"Hello, Siv3D!").draw(50, Vec2{ 100, 200 }, ColorF{ 0.3 });
	}
}

2.3 テキストの基準位置

中心の座標を指定してテキストを表示するには .drawAt(サイズ, x, y, color); または .drawAt(サイズ, pos, color); を呼びます。中心が (x, y), あるいは pos になるようにテキストが表示されます。

右端の中心の座標を指定してテキストを表示するには .draw(サイズ, Arg::rightCenter(x, y), color); を呼びます。右端の中心が (x, y) になるようにテキストが表示されます。

基準位置は全部で 9 種類用意されています。Arg::rightCenter = Vec2{ x, y }Arg::rightCenter(pos) のように、Vec2 で指定することもできます。

基準位置 説明
Arg::topLeft(x, y) 左上。.draw() と同じ。
Arg::topCenter(x, y) 上中央
Arg::topRight(x, y) 右上
Arg::leftCenter(x, y) 左中央
Arg::center(x, y) 中央。.drawAt() と同じ。
Arg::rightCenter(x, y) 右中央
Arg::bottomLeft(x, y) 左下
Arg::bottomCenter(x, y) 下中央
Arg::bottomRight(x, y) 右下

# include <Siv3D.hpp>

void Main()
{
	Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });

	const Font font{ FontMethod::MSDF, 48 };

	while (System::Update())
	{
		font(U"Hello").drawAt(50, Vec2{ 400, 100 }, ColorF{ 0.1 });

		font(U"Siv3D").draw(50, Arg::rightCenter(780, 300), ColorF{ 0.1 });

		font(U"Hello").draw(50, Arg::rightCenter(780, 400), ColorF{ 0.1 });

		font(U"programming").draw(50, Arg::bottomCenter(Cursor::Pos()), ColorF{ 0.1 });
	}
}

2.4 テキストを指定した長方形内に描く

Font::draw() に、座標の代わりに Rect または RectF を渡すと、テキストをその長方形の中に収まるように描画します。テキストのすべての文字が長方形内に収まった場合、関数は true を返します。一方、テキストがあふれる場合、最後の文字が に置き換えられ、関数は false を返します。

Rect.stretched(t) を使うと、長方形の上下左右をそれぞれ t ピクセル拡大(負の場合は縮小)した長方形を得ることができます。

# include <Siv3D.hpp>

void Main()
{
	Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });

	const Font font{ FontMethod::MSDF, 48 };

	const String text = U"Siv3D (シブスリーディー) は、ゲームやアプリを楽しく簡単な C++ コードで開発できるフレームワークです。";

	const Rect rect1{ 100, 100, 400, 160 };

	const Rect rect2{ 100, 300, 400, 160 };

	while (System::Update())
	{
		rect1.draw();

		font(text).draw(18, rect1, Palette::Black);

		rect2.draw();

		// rect2.stretched(-20) は rect2 を上下左右 20 ピクセル縮めた Rect
		rect2.stretched(-20).draw(ColorF{ 0.9 });

		font(text).draw(18, rect2.stretched(-20), Palette::Black);
	}
}

2.5 文字に輪郭や影をつける

文字に影や輪郭をつけるには、次のいずれかのテキストスタイルを使います。輪郭スケールの単位はピクセルではありません。最大でも 0.2 が目安です。

  • TextStyle::Outline(輪郭スケール, 輪郭の色)
  • TextStyle::Shadow(影のオフセット, 影の色)
  • TextStyle::OutlineShadow(輪郭スケール, 輪郭の色, 影のオフセット, 影の色)

影のオフセットが大きい場合、影が途切れてしまうことがあります。それを防ぐには Font のメンバ関数 .setBufferThickness(影のための余裕サイズ) で、影の領域を大きめに確保しておきます。デフォルトは 2 ですが、4 にすると安全です。

# include <Siv3D.hpp>

void Main()
{
	Scene::SetBackground(ColorF{ 0.7, 0.9, 0.8 });

	const Font font{ FontMethod::SDF, 48, Typeface::Bold };

	// 文字の影のための余白を大きめに確保
	font.setBufferThickness(4);

	const String text = U"Hello, Siv3D!";

	while (System::Update())
	{
		// 輪郭
		font(text).draw(TextStyle::Outline(0.2, ColorF{ 0.1 }), 60, Vec2{ 40, 100 });

		// 影
		font(text).draw(TextStyle::Shadow(Vec2{ 1.5, 1.5 }, ColorF{ 0.1 }), 60, Vec2{ 40, 200 });

		// 輪郭+影
		font(text).draw(TextStyle::OutlineShadow(0.2, ColorF{ 0.1 }, Vec2{ 1.5, 1.5 }, ColorF{ 0.1 }), 60, Vec2{ 40, 300 });
	}
}