コンテンツにスキップ

3. 配列の発展的な操作

3.1 配列から条件を満たす要素を削除する (1)

  • Array は、.remove_if(チェック関数) を使うことで、チェックに引っかかる要素を配列から削除できます
  • チェック関数の戻り値は bool 型、引数は配列の要素と同じ型にします

# include <Siv3D.hpp>

// 偶数であるかをチェックする関数
bool CheckInt(int32 n)
{
	return (n % 2 == 0);
}

void Main()
{
	Array<int32> v = { 1, 2, 3, 4, 5, 6 };

	Print << v;

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

	Print << v;

	while (System::Update())
	{

	}
}

3.2 配列から条件を満たす要素を削除する (2)

  • Circle の配列から、チェックに引っかかる要素を削除するサンプルです
  • チェック関数の引数は、int32double` などの基本型以外には const 参照を使います

# include <Siv3D.hpp>

// 円の半径が 10 未満であるかをチェックする関数
bool CheckCircle(const Circle& circle) // 引数は const 参照
{
	return (circle.r < 10.0);
}

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

	Array<Circle> circles = { Circle{ 100, 80, 5 }, Circle{ 400, 400, 20 }, Circle{ 600, 200, 15 } };

	Print << circles;

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

	Print << circles;

	while (System::Update())
	{
		for (const auto& circle : circles)
		{
			circle.draw();
		}
	}
}

3.3 円の配列 (1)

  • クリックした場所に円を配置するサンプルです

# include <Siv3D.hpp>

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

	Array<Circle> circles;

	while (System::Update())
	{
		if (MouseL.down())
		{
			circles << Circle{ Cursor::Pos().x, Cursor::Pos().y, Random(10, 30) };
		}

		for (const auto& circle: circles)
		{
			circle.draw();
		}
	}
}

3.4 円の配列 (2)

  • 一定時間ごとに円を配置するサンプルです

# include <Siv3D.hpp>

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

	Array<Circle> circles;

	double accumulatedTime = 0.0;

	while (System::Update())
	{
		accumulatedTime += Scene::DeltaTime();

		// 蓄積時間が一定時間を超えたら
		if (0.5 <= accumulatedTime)
		{
			circles << Circle{ Cursor::Pos().x, Cursor::Pos().y, Random(10, 30) };

			// 蓄積時間からマイナス
			accumulatedTime -= 0.5;
		}

		for (const auto& circle: circles)
		{
			circle.draw();
		}
	}
}

3.5 円の配列 (3)

  • 移動する円をキー入力で発射するサンプルです

# 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 });

	Texture emoji{ U"🤠"_emoji };

	Array<Circle> circles;

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

		// スペースキーを押したら
		if (KeySpace.down())
		{
			// 配列に円を追加
			circles << Circle{ 400, 420, 10 };
		}

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

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

		for (const auto& circle : circles)
		{
			circle.draw(Palette::Gray);
		}

		emoji.drawAt(400, 500);
	}
}