コンテンツにスキップ

3. Main 関数の構成

メインループやその前後に実行される処理の構成について学びます。

3.1 Main 関数の 3 つのパート

Main() 関数は 3 つのパートに分けられます。

パート 説明 やること
メインループの前 プログラムが起動したときにまず実行される部分 画面の設定やテクスチャの作成
メインループの中 毎秒数十回以上繰り返されるループの中の部分 入力処理や描画
メインループの後 プログラムが終了するときに実行される部分 とくになし
# include <Siv3D.hpp>

void Main()
{


	while (System::Update())
	{

	}
}
# include <Siv3D.hpp>

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



	}
}
# include <Siv3D.hpp>

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

	}


}

3.2 メインループの周期

メインループは、プログラムを実行しているモニタ 🖥️ の表示周期(リフレッシュレート)に合わせて繰り返されるループです。一般に毎秒 60 回や 120 回です。

通常の C++ プログラムで for(;;) のようなループを書くと、性能が許す限り 1 秒間に何万回もループしてしまいますが、while (System::Update()) は、System::Update() 関数が内部でモニタの表示タイミングに合わせた待機を行うことで、モニタの表示タイミングに合わせた頻度のループ(1 秒間に数十回~)になるよう制御してくれます。

次のようなコードを実行することで、1 秒間に何回ループが実行されているかをウィンドウのタイトルに表示して確認できます。

# include <Siv3D.hpp>

void Main()
{
	while (System::Update())
	{
		// 1 秒間に何回メインループが実行されているかを取得する
		int32 fps = Profiler::FPS();

		// 1 秒間に何回メインループが実行されているかを、ウィンドウタイトルに表示する
		Window::SetTitle(fps);
	}
}

3.3 メインループの前にやること

プログラムで画像を表示したいとき、「画像を読み込む仕事」は 3 つのパートのうちどこに書くべきでしょうか。

適切な方法は、メインループの前に画像を読み込み、それをメインループの中で描画することです。こうすれば最も少ない仕事量で目的を達成できます。

もしメインループの中に「画像を読み込む仕事」を書いてしまうと、1 秒間に数十回も画像の読み込みの仕事が発生して動作が重くなってしまいます。

万が一、間違ってメインループの中に「画像を読み込む仕事」を書いてしまっても安心してください。毎秒数十回も画像を読み込むような仕事が発生した場合、Siv3D は自動的に問題を検出し、メッセージボックスを表示してプログラムを終了してくれます。

動作が重くなる(Siv3D は警告を出力して自動的にメインループを終了します)

# include <Siv3D.hpp>

void Main()
{
	while (System::Update())
	{
		// 画像ファイルから画像データを読み込んでテクスチャを作成する
		const Texture texture{ U"example/windmill.png" };

		// テクスチャを描画する
		texture.draw();
	}
}

OK

# include <Siv3D.hpp>

void Main()
{
	// 画像ファイルから画像データを読み込んでテクスチャを作成する
	const Texture texture{ U"example/windmill.png" };

	while (System::Update())
	{
		// テクスチャを描画する
		texture.draw();
	}
}

振り返りチェックリスト

  • Main 関数の 3 つのパートを学んだ
  • System::Update() がメインループの頻度を制御していることを学んだ
  • 「画像を読み込む」のような重い仕事はメインループの前に書くことを学んだ
  • 誤ってメインループの中に「画像を読み込む」のような重い仕事を書いてしまった場合、Siv3D が自動的に問題を検出してプログラムを終了してくれることを学んだ