コンテンツにスキップ

5. Siv3D 入門 ①

5.1 基本の構造

Siv3D を使って開発する C++ プロジェクトでは、<Siv3D.hpp> をインクルードするだけで、Siv3D のさまざまな関数やクラスを使うことができます。

# include <Siv3D.hpp>

void Main()
{
	while (System::Update())
	{

	}
}

while (System::Update()) { } というループがメインループで、プログラムの実行中はずっと繰り返されます。System::Update() は、Esc を押すか、ウィンドウを閉じると false を返すので、そのときにループが終了します。メインループの実行頻度は、プログラムを実行しているパソコンのモニタの表示周期(リフレッシュレート)に依存します。一般に毎秒 60 回や 120 回です。

5.2 文字列や数値を簡易出力する

Print に向かって << でリテラルや変数を送ることで、それらの値を表示できます。

# include <Siv3D.hpp>

void Main()
{
	Print << (100 + 23);
	
	Print << U"Hello";

	// 文字列クラス
	String s = U"Siv3D";
	Print << s;

	// int32 型の配列
	Array<int32> a = { 1, 2, 3, 4, 5 };
	Print << a;

	// 座標(整数)を表す Point 型
	Print << Point{ 10, 20 };

	// 座標(浮動小数点数)を表す Vec2 型
	Print << Vec2{ 1.5, 2.5 };

	// 色を表す ColorF 型
	Print << ColorF{ 1.0, 0.5, 0.0, 1.0 };

	while (System::Update())
	{

	}
}

UTF-32 でエンコードされた文字列

U"Hello" のように U プレフィックスの付く文字列リテラルは UTF-32 でエンコードされた文字列を表します。Siv3D は標準で UTF-32 でエンコードされた文字列を扱います。UTF-32 は UTF-8 と異なり、数字やアルファベット、ひらがなや漢字をすべて 1 要素の char32 型で表現できるため、メモリ消費量の増加と引き換えに文字列の操作が簡単になります。

5.3 簡易出力の消去

Print で出力した結果は、ウィンドウの左上に表示され続けます。次のコードを実行すると、ウィンドウに 0, 1, 2, 3, ... と数値が出力され続け、あふれた古い出力は消去されます。

# include <Siv3D.hpp>

void Main()
{
	int32 count = 0;

	while (System::Update())
	{
		// 現在のカウントを表示する
		Print << count;

		++count;
	}
}

Print で出力した文字列をすべて消去するには、ClearPrint() を呼びます。Siv3D には自由な書体やサイズ、色を指定して文字列を描画するためのクラスが別途用意されているため、簡易的な出力機能である Print は、デバッグ用途に使うことが多いです。

# include <Siv3D.hpp>

void Main()
{
	int32 count = 0;

	while (System::Update())
	{
		// ここでこれまでの出力を消去するので
		ClearPrint();

		// 最新のカウントだけが表示される
		Print << count;

		++count;
	}
}

5.4 ウィンドウの大きさと背景色を変更する

デフォルトのウィンドウサイズは 800x600 ピクセルですが、Window::Resize(幅, 高さ) を使って任意のサイズに変更できます。また、Scene::SetBackground(色) を使って背景色を変更できます。

色は ColorF{ r, g, b } あるいは ColorF{ grayscale } を使って RGB の各成分を 0.0 ~ 1.0 の範囲で指定します。例えば、水色は ColorF{ 0.0, 0.5, 1.0 }, 白色は ColorF{ 1.0 } です。

# include <Siv3D.hpp>

void Main()
{
	// ウィンドウのサイズを 1280x720 に変更する
	Window::Resize(1280, 720);

	// 背景色を水色に変更する
	Scene::SetBackground(ColorF{ 0.0, 0.5, 1.0 });

	while (System::Update())
	{

	}
}

5.5 図形を描画する

Siv3D には、長方形や円、線分、多角形などの図形を表現するクラスが用意されています。図形クラスの値を作成し、.draw(色) メンバ関数を呼ぶことで描画できます。色を省略した場合は白色で描画されます。Siv3D に用意されているおもな図形クラスとその主な作成方法を以下に示します。

座標系

Siv3D の実行画面は、左上が原点 (0, 0) で、右方向が X 軸の正の方向、下方向が Y 軸の正の方向です。座標は X 座標、Y 座標の 2 つの数値で表現できるほか、Point 型または Vec2 型を使うこともできます。Point は整数座標、Vec2 は浮動小数点数座標を表します。

Rect | 長方形(整数座標)

左上の座標 (X, Y) と幅、高さを指定して作成します。

  • Rect{ X, Y, 幅, 高さ }
  • Rect{ X, Y, 幅と高さ }
  • Rect{ Point{ X, Y }, 幅, 高さ }
  • Rect{ Point{ X, Y }, Size{ 幅, 高さ } }

RectF | 長方形(浮動小数点数座標)

左上の座標 (X, Y) と幅、高さを指定して作成します。Rect では 0.5 のような小数を扱うことができませんが、RectF では小数を扱うことができます。

  • RectF{ X, Y, 幅, 高さ }
  • RectF{ X, Y, 幅と高さ }
  • RectF{ Point{ X, Y }, 幅, 高さ }
  • RectF{ Point{ X, Y }, Size{ 幅, 高さ } }
  • RectF{ Vec2{ X, Y }, 幅, 高さ }
  • RectF{ Vec2{ X, Y }, SizeF{ 幅, 高さ } }

Circle | 円

中心の座標と半径を指定して作成します。

  • Circle{ 中心の X 座標, 中心の Y 座標, 半径 }
  • Circle{ Point{ 中心の X 座標, 中心の Y 座標 }, 半径 }
  • Circle{ Vec2{ 中心の X 座標, 中心の Y 座標 }, 半径 }

Line | 線分

始点と終点の座標を指定して作成します。

  • Line{ 始点の X 座標, 始点の Y 座標, 終点の X 座標, 終点の Y 座標 }
  • Line{ Point{ 始点の X 座標, 始点の Y 座標 }, Point{ 終点の X 座標, 終点の Y 座標 } }
  • Line{ Vec2{ 始点の X 座標, 始点の Y 座標 }, Vec2{ 終点の X 座標, 終点の Y 座標 } }

Triangle | 三角形

3 つの頂点の座標を指定して作成します。

  • Triangle{ X1, Y1, X2, Y2, X3, Y3 }(時計回り)
  • Triangle{ Point{ X1, Y1 }, Point{ X2, Y2 }, Point{ X3, Y3 } }(時計回り)
  • Triangle{ Vec2{ X1, Y1 }, Vec2{ X2, Y2 }, Vec2{ X3, Y3 } }(時計回り)

Quad | 凸四角形

4 つの頂点の座標を指定して作成します。

  • Quad{ X1, Y1, X2, Y2, X3, Y3, X4, Y4 }(時計回り)
  • Quad{ Point{ X1, Y1 }, Point{ X2, Y2 }, Point{ X3, Y3 }, Point{ X4, Y4 } }(時計回り)
  • Quad{ Vec2{ X1, Y1 }, Vec2{ X2, Y2 }, Vec2{ X3, Y3 }, Vec2{ X4, Y4 } }(時計回り)

RoundRect | 角丸長方形

  • RoundRect{ X, Y, 幅, 高さ, 角の半径 }
  • RoundRect{ Point{ X, Y }, Size{ 幅, 高さ }, 角の半径 }
  • RoundRect{ Vec2{ X, Y }, SizeF{ 幅, 高さ }, 角の半径 }
  • RoundRect{ Rect{ X, Y, 幅, 高さ }, 角の半径 }
  • RoundRect{ RectF{ X, Y, 幅, 高さ }, 角の半径 }

いくつかの図形を描画するサンプルコードを示します。

# include <Siv3D.hpp>

void Main()
{
	while (System::Update())
	{
		// (100, 100) から幅 150, 高さ 100 の長方形を描画する
		Rect{ 100, 100, 150, 100 }.draw();

		// (300, 100) から幅 100, 高さ 50 の長方形を描画する
		Rect{ Point{ 300, 100 }, 100, 50 }.draw(ColorF{ 1.0, 0.0, 0.0 });

		// (500, 150) を中心とする半径 50 の円を描画する
		Circle{ 500, 150, 50 }.draw(ColorF{ 0.0, 1.0, 1.0 });

		// 線分 (100, 300) - (200, 400) を太さ 5 で描画する
		Line{ 100, 300, 200, 400 }.draw(5, ColorF{ 0.0, 0.5, 0.0 });

		// 三角形を描画する
		Triangle{ 300, 300, 400, 400, 200, 500 }
			.draw(ColorF{ 1.0, 0.0, 1.0 });

		// 角丸長方形を描画する
		RoundRect{ 450, 300, 100, 150, 20 }
			.draw(ColorF{ 1.0, 1.0, 0.0 });
	}
}

5.6 図形の枠を描く

図形クラスの次のメンバ関数を使うと、図形の枠を描くことができます。

  • .drawFrame(内側の太さ, 外側の太さ, 色)
  • .drawFrame(太さ, 色)
# include <Siv3D.hpp>

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

	while (System::Update())
	{
		Circle{ 200, 200, 100 }.drawFrame(2, 2, ColorF{ 0.1 });

		Rect{ 400, 200, 200, 200 }.drawFrame(10, ColorF{ 1.0 });
	}
}

5.7 長方形の角を丸める

RectRectF.rounded(角の半径) メンバ関数を使って、RoundRect を作成することができます。

# include <Siv3D.hpp>

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

	Rect rect{ 100, 100, 400, 200 };

	while (System::Update())
	{
		rect.rounded(20).draw(ColorF{ 0.3 });
	}
}

.rounded(左上の角の半径, 右上の角の半径, 右下の角の半径, 左下の角の半径) のように 4 つの角にそれぞれ異なる半径を指定することもできます。この関数の戻り値は Polygon 型になります。

# include <Siv3D.hpp>

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

	Rect rect{ 100, 100, 400, 200 };

	while (System::Update())
	{
		rect.rounded(60, 0, 60, 0).draw(ColorF{ 0.3 });
	}
}

5.8 グラデーションを使う

RectRectF は 2 色のグラデーションを使って描画することができます。

  • .draw(Arg::top = 上の色, Arg::bottom = 下の色) で上から下にグラデーションを描画します。
  • .draw(Arg::left = 左の色, Arg::right = 右の色) で左から右にグラデーションを描画します。
# include <Siv3D.hpp>

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

	while (System::Update())
	{
		Rect{ 100, 100, 400, 200 }
			.draw(Arg::top = ColorF{ 0.6, 0.0, 0.0 }, Arg::bottom = ColorF{ 0.0, 0.0, 0.6 });

		Rect{ 100, 400, 600, 100 }
			.draw(Arg::left = ColorF{ 0.0, 0.6, 0.0 }, Arg::right = ColorF{ 0.0, 0.6, 0.6 });
	}
}

5.9 影を描く

Rect, RectF, RoundRect, Circle には .drawShadow() メンバ関数があり、影を描くことができます。

  • 使い方は .drawShadow(Vec2{ 影のオフセット }, ぼかしの強さ, 影の広がり, 影の色) です。
# include <Siv3D.hpp>

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

	Rect rect{ 100, 100, 400, 200 };

	while (System::Update())
	{
		rect.drawShadow(Vec2{ 3, 3 }, 16, 2);

		rect.draw();
	}
}