コンテンツにスキップ

4. 図形同士の交差を調べる

4.1 図形同士の交差

  • 図形 A と 図形 B が重なっているかは if (A.intersects(B)) で調べられます

# include <Siv3D.hpp>

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

	Font font{ FontMethod::MSDF, 48 };

	Circle enemyCircle{ 400, 200, 100 };

	while (System::Update())
	{
		Circle bulletCircle{ Cursor::Pos().x, Cursor::Pos().y, 20 };

		enemyCircle.draw();

		bulletCircle.draw(Palette::Gray);

		// もし 2 つの Circle が交差している場合
		if (enemyCircle.intersects(bulletCircle))
		{
			font(U"交差").draw(30, 20, 20, Palette::Black);
		}
	}
}

4.2 複数の図形との交差判定 (1)

  • 複数の図形と交差判定をするサンプルです

# include <Siv3D.hpp>

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

	Font font{ FontMethod::MSDF, 48 };

	Array<Circle> enemyCircles = {
		Circle{ 200, 200, 60 },
		Circle{ 400, 200, 60 },
		Circle{ 600, 200, 60 },
	};

	while (System::Update())
	{
		Circle bulletCircle{ Cursor::Pos().x, Cursor::Pos().y, 20 };

		// 各 enemyCircle について
		for (auto& enemyCircle : enemyCircles)
		{
			// もし 2 つの Circle が交差している場合
			if (enemyCircle.intersects(bulletCircle))
			{
				font(U"交差").draw(30, 20, 20, Palette::Black);
			}
		}

		for (const auto& enemyCircle : enemyCircles)
		{
			enemyCircle.draw();
		}

		bulletCircle.draw(Palette::Gray);
	}
}

4.3 複数の図形との交差判定 (2)

  • 複数の図形と交差判定をし、交差した円を削除するサンプルです
  • 交差した円の Y 座標を -999 に変更することで、その後のチェックに引っかかるようにし、配列から削除します

# include <Siv3D.hpp>

// 円の Y 座標が 100 未満であるかをチェックする関数
bool CheckCircle(const Circle& circle)
{
	return (circle.y < 100.0);
}

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

	Font font{ FontMethod::MSDF, 48 };

	Array<Circle> enemyCircles = {
		Circle{ 200, 200, 60 },
		Circle{ 400, 200, 60 },
		Circle{ 600, 200, 60 },
	};

	while (System::Update())
	{
		Circle bulletCircle{ Cursor::Pos().x, Cursor::Pos().y, 20 };

		// 各 enemyCircle について
		for (auto& enemyCircle : enemyCircles)
		{
			// もし 2 つの Circle が交差している場合
			if (enemyCircle.intersects(bulletCircle))
			{
				// その enemyCircle の Y 座標を -999 に変更する
				enemyCircle.y = -999;
			}
		}

		// チェックに引っかかる要素を配列から削除する
		enemyCircles.remove_if(CheckCircle);

		for (const auto& enemyCircle : enemyCircles)
		{
			enemyCircle.draw();
		}

		bulletCircle.draw(Palette::Gray);

		font(U"enemyCircles: ", enemyCircles).draw(15, 20, 20, Palette::Black);
	}
}

4.4 複数の図形との交差判定 (3)

  • 複数の図形と交差判定をし、交差した円の双方を削除するサンプルです
  • 交差した円の Y 座標をそれぞれ -999, -9999 に変更することで、その後のチェックに引っかかるようにし、配列から削除します
  • それぞれの Y 座標に差があるのは、変更先 (-999)で再び交差判定が発生しないようにするためです

# include <Siv3D.hpp>

// 円の Y 座標が 100 未満であるかをチェックする関数
bool CheckCircle(const Circle& circle)
{
	return (circle.y < 100.0);
}

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

	Font font{ FontMethod::MSDF, 48 };

	Array<Circle> enemyCircles = {
		Circle{ 200, 200, 60 },
		Circle{ 400, 200, 60 },
		Circle{ 600, 200, 60 },
	};

	Array<Circle> bulletCircles;

	while (System::Update())
	{
		double deltaTime = Scene::DeltaTime();

		if (MouseL.down())
		{
			bulletCircles << Circle{ Cursor::Pos().x, Cursor::Pos().y, 10 };
		}

		// 各 enemyCircle について
		for (auto& enemyCircle : enemyCircles)
		{
			// 各 bulletCircle について
			for (auto& bulletCircle : bulletCircles)
			{
				// もし 2 つの Circle が交差している場合
				if (enemyCircle.intersects(bulletCircle))
				{
					// enemyCircle の Y 座標を -999 に変更する
					enemyCircle.y = -999;

					// bulletCircle の Y 座標を -9999 に変更する
					bulletCircle.y = -9999;
				}
			}
		}

		// すべての bulletCircle を上方向に移動させる
		for (auto& bulletCircle : bulletCircles)
		{
			bulletCircle.y -= (deltaTime * 200.0);
		}

		// チェックに引っかかる要素を配列から削除する
		enemyCircles.remove_if(CheckCircle);

		// チェックに引っかかる要素を配列から削除する
		bulletCircles.remove_if(CheckCircle);

		for (const auto& enemyCircle : enemyCircles)
		{
			enemyCircle.draw();
		}

		for (const auto& bulletCircle : bulletCircles)
		{
			bulletCircle.draw(Palette::Gray);
		}

		font(U"enemyCircles: ", enemyCircles).draw(15, 20, 20, Palette::Black);
		font(U"bulletCircles: ", bulletCircles).draw(15, 20, 50, Palette::Black);
	}
}