コンテンツにスキップ

28. ボタン

チュートリアル 3 ~ 27 の内容を使って、ゲームやアプリで使えるボタンを作成します。

28.1 基本の関数

  • 与えられた長方形をボタンとして描画し、ボタンが押されたかどうかを返す関数 Button を作成します
  • デザイン性のために、角を少し丸めた長方形として描画します

コード
# include <Siv3D.hpp>

bool Button(const Rect& rect)
{
	const RoundRect roundRect = rect.rounded(6);

	// 背景を描く
	roundRect.draw(ColorF{ 0.9, 0.8, 0.6 });

	// ボタンが押されたら true を返す
	return rect.leftClicked();
}

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

	while (System::Update())
	{
		if (Button(Rect{ 80, 300, 300, 80 }))
		{
			Print << U"A";
		}

		if (Button(Rect{ 420, 300, 300, 80 }))
		{
			Print << U"B";
		}
	}
}

28.2 装飾の追加

  • ボタンの見た目を整えるために、影や枠を追加します

コード
# include <Siv3D.hpp>

bool Button(const Rect& rect)
{
	const RoundRect roundRect = rect.rounded(6);

	// 影と背景を描く
	roundRect
		.drawShadow(Vec2{ 2, 2 }, 12, 0)
		.draw(ColorF{ 0.9, 0.8, 0.6 });

	// 枠を描く
	rect.stretched(-3).rounded(3)
		.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });

	// ボタンが押されたら true を返す
	return rect.leftClicked();
}

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

	while (System::Update())
	{
		if (Button(Rect{ 80, 300, 300, 80 }))
		{
			Print << U"A";
		}

		if (Button(Rect{ 420, 300, 300, 80 }))
		{
			Print << U"B";
		}
	}
}

28.3 テキストの追加

  • フォントと文字列を渡し、ボタンにテキストを描画します

コード
# include <Siv3D.hpp>

bool Button(const Rect& rect, const Font& font, const String& text)
{
	const RoundRect roundRect = rect.rounded(6);

	// 影と背景を描く
	roundRect
		.drawShadow(Vec2{ 2, 2 }, 12, 0)
		.draw(ColorF{ 0.9, 0.8, 0.6 });

	// 枠を描く
	rect.stretched(-3).rounded(3)
		.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });

	// テキストを描く
	font(text).drawAt(40, rect.center(), ColorF{ 0.4, 0.3, 0.2 });

	// ボタンが押されたら true を返す
	return rect.leftClicked();
}

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

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

	while (System::Update())
	{
		if (Button(Rect{ 80, 300, 300, 80 }, font, U"Bread"))
		{
			Print << U"Bread";
		}

		if (Button(Rect{ 420, 300, 300, 80 }, font, U"Rice"))
		{
			Print << U"Rice";
		}
	}
}

28.4 マウスカーソルの変更

  • マウスカーソルがボタンの上にある場合、手の形に変更します

コード
# include <Siv3D.hpp>

bool Button(const Rect& rect, const Font& font, const String& text)
{
	// マウスカーソルがボタンの上にある場合
	if (rect.mouseOver())
	{
		// マウスカーソルを手の形にする
		Cursor::RequestStyle(CursorStyle::Hand);
	}

	const RoundRect roundRect = rect.rounded(6);

	// 影と背景を描く
	roundRect
		.drawShadow(Vec2{ 2, 2 }, 12, 0)
		.draw(ColorF{ 0.9, 0.8, 0.6 });

	// 枠を描く
	rect.stretched(-3).rounded(3)
		.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });

	// テキストを描く
	font(text).drawAt(40, rect.center(), ColorF{ 0.4, 0.3, 0.2 });

	// ボタンが押されたら true を返す
	return rect.leftClicked();
}

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

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

	while (System::Update())
	{
		if (Button(Rect{ 80, 300, 300, 80 }, font, U"Bread"))
		{
			Print << U"Bread";
		}

		if (Button(Rect{ 420, 300, 300, 80 }, font, U"Rice"))
		{
			Print << U"Rice";
		}
	}
}

28.5 無効状態の追加

  • ボタンが無効状態のとき、グレーの半透明を重ね、操作も無効にします

コード
# include <Siv3D.hpp>

bool Button(const Rect& rect, const Font& font, const String& text, bool enabled)
{
	// マウスカーソルがボタンの上にある場合
	if (enabled && rect.mouseOver())
	{
		// マウスカーソルを手の形にする
		Cursor::RequestStyle(CursorStyle::Hand);
	}

	const RoundRect roundRect = rect.rounded(6);

	// 影と背景を描く
	roundRect
		.drawShadow(Vec2{ 2, 2 }, 12, 0)
		.draw(ColorF{ 0.9, 0.8, 0.6 });

	// 枠を描く
	rect.stretched(-3).rounded(3)
		.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });

	// テキストを描く
	font(text).drawAt(40, rect.center(), ColorF{ 0.4, 0.3, 0.2 });

	// 無効の場合は
	if (not enabled)
	{
		// グレーの半透明を重ねる
		roundRect.draw(ColorF{ 0.8, 0.8 });
	}

	// ボタンが押されたら true を返す
	return (enabled && rect.leftClicked());
}

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

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

	while (System::Update())
	{
		if (Button(Rect{ 80, 300, 300, 80 }, font, U"Bread", true))
		{
			Print << U"Bread";
		}

		if (Button(Rect{ 420, 300, 300, 80 }, font, U"Rice", true))
		{
			Print << U"Rice";
		}
	}
}

28.6 【完成】絵文字の追加

  • ボタンに絵文字を追加します
  • 絵文字の表示のために、テキストの位置を調整します

コード
# include <Siv3D.hpp>

bool Button(const Rect& rect, const Texture& emoji, const Font& font, const String& text, bool enabled)
{
	// マウスカーソルがボタンの上にある場合
	if (enabled && rect.mouseOver())
	{
		// マウスカーソルを手の形にする
		Cursor::RequestStyle(CursorStyle::Hand);
	}

	const RoundRect roundRect = rect.rounded(6);

	// 影と背景を描く
	roundRect
		.drawShadow(Vec2{ 2, 2 }, 12, 0)
		.draw(ColorF{ 0.9, 0.8, 0.6 });

	// 枠を描く
	rect.stretched(-3).rounded(3)
		.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });

	// 絵文字を描く
	emoji.scaled(0.4).drawAt((rect.x + 60), rect.center().y);

	// テキストを描く
	font(text).drawAt(40, rect.center().movedBy(30, 0), ColorF{ 0.4, 0.3, 0.2 });

	// 無効の場合は
	if (not enabled)
	{
		// グレーの半透明を重ねる
		roundRect.draw(ColorF{ 0.8, 0.8 });
	}

	// ボタンが押されたら true を返す
	return (enabled && rect.leftClicked());
}

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

	const Texture breadEmoji{ U"🍞"_emoji };
	const Texture riceEmoji{ U"🍚"_emoji };

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

	while (System::Update())
	{
		if (Button(Rect{ 80, 300, 300, 80 }, breadEmoji, font, U"Bread", true))
		{
			Print << U"Bread";
		}

		if (Button(Rect{ 420, 300, 300, 80 }, riceEmoji, font, U"Rice", true))
		{
			Print << U"Rice";
		}
	}
}