コンテンツにスキップ

第 13 回 | 2025-01-10 🛜 オンデマンド

第 13 回は 🛜 オンデマンド講義

講義ページを自分で読み進め、いつもどおり課題を提出してください。講義のライブ配信や動画はありません。教室は開室しています。講義日に Moodle で質問をすると、翌日までにスピード対応します。

1. 複雑な図形を描く

1.1 線分を描く

Line{ Vec2{ x1, y1 }, Vec2{ x2, y2 } } で線分を作成できます。Line.draw(太さ, 色) で描画できます。

#include <Siv3D.hpp>

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

	while (System::Update())
	{
		// (100, 100) - (600, 200) を結ぶ太さ 2 の線分を描く
		Line{ Vec2{ 100, 100 }, Vec2{ 600, 200 } }.draw(2, ColorF{ 0.3, 0.5, 0.7 });

		// (200, 200) - マウスカーソル を結ぶ太さ 10 の線分を描く
		Line{ Vec2{ 200, 200 }, Cursor::Pos() }.draw(10, ColorF{ 0.3, 0.5, 0.7 });
	}
}

1.2 三角形を描く

Triangle{ Vec2{ x1, y1 }, Vec2{ x2, y2 }, Vec2{ x3, y3 } } に時計回りで座標を指定することで三角形を作成できます。Triangle.draw(色) で描画できます。

#include <Siv3D.hpp>

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

	while (System::Update())
	{
		// (100, 100) - (600, 100) - (200, 500) からなる三角形を描く
		Triangle{ Vec2{ 100, 100 }, Vec2{ 600, 100 }, Vec2{ 200, 500 } }.draw(ColorF{ 0.3, 0.5, 0.7 });
	}
}

1.3 四角形を描く

Quad{ Vec2{ x1, y1 }, Vec2{ x2, y2 }, Vec2{ x3, y3 }, Vec2{ x4, y4 } } に時計回りで座標を指定することで四角形を作成できます。ただし凹の角(180° より大きい角)があってはいけません。長方形を描く場合は RectRectF を使ったほうが便利です。Quad.draw(色) で描画できます。

#include <Siv3D.hpp>

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

	while (System::Update())
	{
		// (100, 100) - (600, 100) - (500, 500) - (200, 400) からなる四角形を描く
		Quad{ Vec2{ 100, 100 }, Vec2{ 600, 100 }, Vec2{ 500, 500 }, Vec2{ 200, 400 } }.draw(ColorF{ 0.3, 0.5, 0.7 });
	}
}

振り返りチェックリスト

  • 座標を指定して線分、三角形、四角形を描画する方法を学んだ

2. 動きをつくる

2.1 絵文字を動かす

メインループのたびに位置をずらすことで移動のモーションをつくれます。

Scene::DeltaTime() は前フレームからの経過時間(秒)を double 型で返します。画面の更新頻度が毎秒 60 フレーム(60 FPS)の場合、1 フレームあたりの時間は約 0.016 秒です。

次のコードでは、毎秒 100 ピクセルの速さで絵文字が右に移動します。

#include <Siv3D.hpp>

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

	const Texture emoji{ U"☃️"_emoji };

	// 絵文字の X 座標
	double x = 100.0;

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

		x += (deltaTime * 100.0);

		emoji.drawAt(x, 300);
	}
}

次のようにコードを書き換えると、絵文字が左右に往復するようになります。

#include <Siv3D.hpp>

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

	const Texture emoji{ U"☃️"_emoji };

	// 絵文字の X 座標
	double x = 100.0;

	// true の場合は右に移動、false の場合は左に移動
	bool toRight = true;

	while (System::Update())
	{
		const double deltaTime = Scene::DeltaTime();
		
		if (toRight)
		{
			x += (deltaTime * 100.0);

			if (750 < x)
			{
				toRight = false;
			}
		}
		else
		{
			x -= (deltaTime * 100.0);

			if (x < 50)
			{
				toRight = true;
			}	
		}

		emoji.drawAt(x, 300);
	}
}

2.2 絵文字を回す

メインループのたびに回転の角度を増やすことで回転のモーションをつくれます。次のコードでは、毎秒 180° 回転する寿司を描画します。

#include <Siv3D.hpp>

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

	const Texture emoji{ U"🍣"_emoji };

	// 回転角度
	double angle = 0_deg;

	while (System::Update())
	{
		const double deltaTime = Scene::DeltaTime();
		
		// 回転角度を増やす
		angle += (deltaTime * 180_deg);

		// 回転ずし
		emoji.rotated(angle).drawAt(400, 300);

	}
}

2.3 図形を動かす

2.1 と同じ要領で図形の位置をずらすことで移動のモーションをつくれます。

#include <Siv3D.hpp>

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

	double x = 100.0;

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

		x += (deltaTime * 100.0);

		Circle{ x, 200, 80 }.draw();

		// double 型を使う場合, Rect ではなく RectF
		RectF{ x, 400, 100, 80 }.draw();
	}
}

振り返りチェックリスト

  • 変数を使って絵文字や図形の位置を動かす方法を学んだ

3. 図形を変数で扱う

3.1 図形クラスのメンバ変数

Circle は次のようなクラスであり、Circle 型の変数を作ることができます。

struct Circle
{
	double x;
	double y;
	double r;
};

Rect は次のようなクラスであり、Rect 型の変数を作ることができます。

struct Rect
{
	int32 x;
	int32 y;
	int32 w;
	int32 h;
};

RectF は次のようなクラスであり、RectF 型の変数を作ることができます。

struct RectF
{
	double x;
	double y;
	double w;
	double h;
};

#include <Siv3D.hpp>

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

	// Circle 型の変数
	Circle circle{ 400, 300, 100 };

	// RectF 型の変数
	RectF rect{ 400, 300, 300, 200 };

	while (System::Update())
	{
		circle.draw(Palette::White);

		rect.draw(Palette::Seagreen);
	}
}

3.2 図形クラスのメンバ変数の操作

  • 図形クラスのメンバ変数の値を変更するサンプル

#include <Siv3D.hpp>

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

	// Circle 型の変数
	Circle circle{ 400, 300, 100 };

	// RectF 型の変数
	RectF rect{ 400, 300, 300, 200 };

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

		circle.draw(Palette::White);

		// 円の半径を増やす
		circle.r += (deltaTime * 30.0);

		rect.draw(Palette::Seagreen);

		// 長方形の位置を左に移動
		rect.x -= (deltaTime * 30.0);
	}
}

振り返りチェックリスト

  • 図形クラスのメンバ変数を変更する方法を学んだ

4. 文字列のフォーマット

4.1 文字列の中に変数の値をいれる

U"{}"_fmt(x) と書くと、{} には値 x を文字列にしたものが入ります。

例えば U"{} 月 {} 日"_fmt(12, 31)U"12 月 31 日" という文字列になります。

# include <Siv3D.hpp>

void Main()
{
	int32 score = 1234;

	Print << U"スコア: {}"_fmt(score);

	int32 month = 12;

	int32 day = 31;

	Print << U"今日は {} 月 {} 日"_fmt(month, day);

	while (System::Update())
	{

	}
}

4.2 小数点以下の桁数を指定して変換する

double 型の値 x を、小数点以下の桁数を指定して変換する場合、U"{:.2f}"_fmt(x) のように書きます(この場合小数点以下 2 桁)。

小数点以下を表示しない場合は U"{:.0f}"_fmt(x) とします。

# include <Siv3D.hpp>

void Main()
{
	double x = 123.4567;

	Print << x;

	Print << U"{}"_fmt(x);

	// 小数点以下 2 桁
	Print << U"{:.2f}"_fmt(x);

	// 小数点以下 0 桁
	Print << U"{:.0f}"_fmt(x);

	while (System::Update())
	{

	}
}

振り返りチェックリスト

  • _fmt() を使って数値を文字列に変換する方法を学んだ
  • 小数点以下の桁数を指定して数値を文字列に変換する方法を学んだ

5. テキストを表示する

5.1 テキストの自由な表示

Print のような簡易表示ではなく、好きな位置に好きな色でテキストを表示したい場合は、Font クラスを使います。

まず、メインループの前に Font 変数名{ FontMethod::MSDF, 48 }; でフォントを作成します。フォントの作成はコストがかかるため、メインループの前で行います。

作成したフォント font を使って、

  • font(テキスト).draw(サイズ, x, y, color);
  • font(テキスト).draw(サイズ, pos, color);

のようにして、テキストを、サイズ、位置、色を指定して表示します。color を省略すると白色になります。

font(テキスト) のテキストの部分は、文字列以外の値も記述できます。

# include <Siv3D.hpp>

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

	// フォントの作成
	const Font font{ FontMethod::MSDF, 48 };

	int32 count = 0;

	while (System::Update())
	{
		font(U"C++").draw(50, Vec2{ 100, 100 }, Palette::Black);

		font(U"Siv{}D"_fmt(count)).draw(80, Vec2{ 200, 200 }, ColorF{ 0.2, 0.6, 0.9 });

		font(U"こんにちは").draw(25, Vec2{ 100, 400 }, ColorF{ 0.4 });

		font(count).draw(50, Vec2{ 300, 500 });

		++count;
	}
}
フォントの品質

FontMethod::MSDF 方式でフォントを作成するときの 48 は、フォントデータの詳細度を表しています。この値は実行時性能とのトレードオフです。詳細度を大きくすると、メモリ消費が増加して処理時間が増えます。小さくすると、複雑な字形の文字の描画品質が低下する場合があります。漢字の場合は 48 がバランスの取れた値です。英数字のみの場合は 32 でも十分です。

5.2 太文字のテキスト

太文字のフォントは Font 変数名{ FontMethod::MSDF, 48, Typeface::Bold }; で作成できます。通常のフォントは Typeface::Regular ですが、これは省略できます。

# include <Siv3D.hpp>

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

	// 通常のフォント
	const Font regularFont{ FontMethod::MSDF, 48 }; // Typeface::Regular

	// 太文字のフォント
	const Font boldFont{ FontMethod::MSDF, 48, Typeface::Bold };

	while (System::Update())
	{
		regularFont(U"Hello, Siv3D!").draw(50, Vec2{ 100, 100 }, ColorF{ 0.3 });

		boldFont(U"Hello, Siv3D!").draw(50, Vec2{ 100, 200 }, ColorF{ 0.3 });
	}
}

5.3 テキストの基準位置

中心の座標を指定してテキストを表示するには .drawAt(サイズ, x, y, color); または .drawAt(サイズ, pos, color); を呼びます。中心が (x, y), あるいは pos になるようにテキストが表示されます。

右端の中心の座標を指定してテキストを表示するには .draw(サイズ, Arg::rightCenter(x, y), color); を呼びます。右端の中心が (x, y) になるようにテキストが表示されます。

基準位置は全部で 9 種類用意されています。Arg::rightCenter = Vec2{ x, y }Arg::rightCenter(pos) のように、Vec2 で指定することもできます。

基準位置 説明
Arg::topLeft(x, y) 左上。.draw() と同じ。
Arg::topCenter(x, y) 上中央
Arg::topRight(x, y) 右上
Arg::leftCenter(x, y) 左中央
Arg::center(x, y) 中央。.drawAt() と同じ。
Arg::rightCenter(x, y) 右中央
Arg::bottomLeft(x, y) 左下
Arg::bottomCenter(x, y) 下中央
Arg::bottomRight(x, y) 右下

# include <Siv3D.hpp>

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

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

	while (System::Update())
	{
		font(U"Hello").drawAt(50, Vec2{ 400, 100 }, ColorF{ 0.1 });

		font(U"Siv3D").draw(50, Arg::rightCenter(780, 300), ColorF{ 0.1 });

		font(U"Hello").draw(50, Arg::rightCenter(780, 400), ColorF{ 0.1 });

		font(U"programming").draw(50, Arg::bottomCenter(Cursor::Pos()), ColorF{ 0.1 });
	}
}

振り返りチェックリスト

  • フォントを作成する方法を学んだ
  • フォントの作成はコストがかかるため、メインループの前で行うことを学んだ
  • フォントを使ってテキストを表示する方法を学んだ
  • 太文字のフォントを作成する方法を学んだ
  • テキストの基準位置を変更する方法を学んだ

6. キーボード入力

6.1 キーが押されたかを調べる

if (キー名.down()) で、キーが押されたかを調べることができます。

主なキー名

  • A , B , C , ... は KeyA, KeyB, KeyC , ...
  • 1 , 2 , 3 , ... は Key1, Key2, Key3, ...
  • F1 , F2 , F3 , ... は KeyF1, KeyF2, KeyF3, ...
  • Up , Down , Left , RightKeyUp, KeyDown, KeyLeft, KeyRight
  • SpaceKeySpace
  • EnterKeyEnter
  • BackspaceKeyBackspace
  • Tab キーは KeyTab
  • Esc キーは KeyEscape
  • Page Up , Page DownKeyPageUp, KeyPageDown
  • Del キーは KeyDelete
  • Numpad の Num 0 , Num 1 , Num 2 , ... は KeyNum0, KeyNum1, KeyNum2, ...
  • ShiftKeyShift
  • Left Shift (左シフト), Right Shift (右シフト) は KeyLShift, KeyRShift
  • CtrlKeyControl
  • (macOS) CmdKeyCommand
  • , , . , / キーは KeyComma, KeyPeriod, KeySlash

# include <Siv3D.hpp>

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

	while (System::Update())
	{
		// A キーが押されたら
		if (KeyA.down())
		{
			Print << U"A";
		}

		// スペースキーが押されたら
		if (KeySpace.down())
		{
			Print << U"Space";
		}

		// 1 キーが押されたら
		if (Key1.down())
		{
			Print << U"1";
		}	
	}
}

6.2 キーが押されているかを調べる

if (キー名.pressed()) で、キーが押されているかを調べることができます。.down() は押された瞬間のみ、.pressed() は押されている間ずっと true になります。

# include <Siv3D.hpp>

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

	while (System::Update())
	{
		// A キーが押されていたら
		if (KeyA.pressed())
		{
			Print << U"A";
		}

		// スペースキーが押されていたら
		if (KeySpace.pressed())
		{
			Print << U"Space";
		}

		// 1 キーが押されていたら
		if (Key1.pressed())
		{
			Print << U"1";
		}	
	}
}

6.3 キーで絵文字を動かす

矢印キーを使って絵文字を左右に移動させるには次のようにします。

# include <Siv3D.hpp>

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

	const Texture emoji{ U"☃️"_emoji };

	// 絵文字の X 座標
	double x = 400.0;

	while (System::Update())
	{
		// 前フレームからの経過時間(秒)* 200
		const double move = (Scene::DeltaTime() * 200);

		// ← キーが押されていたら
		if (KeyLeft.pressed())
		{
			x -= move;
		}

		// → キーが押されていたら
		if (KeyRight.pressed())
		{
			x += move;
		}

		emoji.drawAt(x, 300);
	}
}
(チャレンジ)左右だけでなく上下にも移動できるようにしてみよう
# include <Siv3D.hpp>

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

	const Texture emoji{ U"☃️"_emoji };

	// 絵文字の X 座標
	double x = 400.0;

	// 絵文字の Y 座標
	double y = 300.0;

	while (System::Update())
	{
		// 前フレームからの経過時間(秒)* 200
		const double move = (Scene::DeltaTime() * 200);

		// ← キーが押されていたら
		if (KeyLeft.pressed())
		{
			x -= move;
		}

		// → キーが押されていたら
		if (KeyRight.pressed())
		{
			x += move;
		}

		// ↑ キーが押されていたら
		if (KeyUp.pressed())
		{
			y -= move;
		}

		// ↓ キーが押されていたら
		if (KeyDown.pressed())
		{
			y += move;
		}

		emoji.drawAt(x, y);
	}
}

振り返りチェックリスト

  • キーが押されたか調べるには if (キー名.down()) を使うことを学んだ
  • キーが押されているか調べるには if (キー名.pressed()) を使うことを学んだ

7. マウス入力

7.1 マウスのボタンが押されたかを調べる

if (MouseL.down()) でマウスの左ボタンが押されたかを、if (MouseR.down()) でマウスの右ボタンが押されたかを調べることができます。

# include <Siv3D.hpp>

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

	while (System::Update())
	{
		// 左クリックされたら
		if (MouseL.down())
		{
			Print << U"左クリック";
		}

		// 右クリックされたら
		if (MouseR.down())
		{
			Print << U"右クリック";
		}
	}
}

7.2 マウスカーソルの位置を調べる

マウスカーソルの座標を Point 型で得るには Cursor::Pos() を使います。Point 型の値は Vec2 型にも変換できます。

# include <Siv3D.hpp>

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

	const Texture emoji{ U"☃️"_emoji };

	// 絵文字の座標
	Vec2 pos{ 400, 300 };

	while (System::Update())
	{
		// 左クリックされたら
		if (MouseL.down())
		{
			// 現在のマウスカーソルの座標を代入
			pos = Cursor::Pos();
		}

		emoji.drawAt(pos);
	}
}

X 座標、Y 座標をそれぞれ Cursor::Pos().xCursor::Pos().y で得ることもできます。前述のプログラムと次のプログラムは同じ動作をします。

# include <Siv3D.hpp>

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

	const Texture emoji{ U"☃️"_emoji };

	// 絵文字の X 座標
	double x = 400;

	// 絵文字の Y 座標
	double y = 300;

	while (System::Update())
	{
		// 左クリックされたら
		if (MouseL.down())
		{
			// 現在のマウスカーソルの X 座標を代入
			x = Cursor::Pos().x;

			// 現在のマウスカーソルの Y 座標を代入
			y = Cursor::Pos().y;
		}

		emoji.drawAt(x, y);
	}
}

7.3 図形をクリックしたかを調べる

CircleRect, RectF.leftClicked() で、その図形が左クリックされたかを bool 型で返します。

# include <Siv3D.hpp>

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

	const Circle circle{ 200, 200, 50 };

	const Rect rect{ 400, 400, 200, 40 };

	while (System::Update())
	{
		// 円を左クリックしたら
		if (circle.leftClicked())
		{
			Print << U"円をクリック";
		}

		// 長方形を左クリックしたら
		if (rect.leftClicked())
		{
			Print << U"長方形をクリック";
		}

		circle.draw(Palette::Orange);

		rect.draw();
	}
}

7.4 図形の上にマウスカーソルがあるかを調べる

CircleRect, RectF.mouseOver() は、マウスカーソルがその図形の上にあるかを bool 型で返します。

# include <Siv3D.hpp>

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

	const Circle circle{ 200, 200, 50 };

	const Rect rect{ 400, 400, 200, 40 };

	while (System::Update())
	{
		ClearPrint();

		// 円の上にマウスカーソルがあれば
		if (circle.mouseOver())
		{
			Print << U"円の上にある";
		}

		// 長方形の上にマウスカーソルがあれば
		if (rect.mouseOver())
		{
			Print << U"長方形の上にある";
		}

		circle.draw(Palette::Orange);

		rect.draw();
	}
}

7.5 マウスカーソルを手の形にする

Cursor::RequestStyle(CursorStyle::Hand); を呼ぶと、そのフレームはマウスカーソルが手の形のアイコンで表示されます。

# include <Siv3D.hpp>

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

	const Circle circle{ 200, 200, 50 };

	while (System::Update())
	{
		// 円の上にマウスカーソルがあれば
		if (circle.mouseOver())
		{
			// マウスカーソルを手のアイコンにする
			Cursor::RequestStyle(CursorStyle::Hand);
		}

		circle.draw(Palette::Orange);
	}
}

7.6 絵文字をクリックしたかを調べる

絵文字(テクスチャ)には .leftClicked().mouseOver() などの便利な機能が無いため、近い大きさの円で近似して判定します。

# include <Siv3D.hpp>

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

	const Texture emoji{ U"🍪"_emoji };

	const Circle circle{ 200, 200, 60 };

	while (System::Update())
	{
		// 円の上にマウスカーソルがあれば
		if (circle.mouseOver())
		{
			// マウスカーソルを手のアイコンにする
			Cursor::RequestStyle(CursorStyle::Hand);
		}

		// 円を左クリックしたら
		if (circle.leftClicked())
		{
			Print << U"クッキーをクリック";
		}

		// 円は描かない
		//circle.draw();

        // circle.center は Vec2{ circle.x, circle.y } と同じ
		emoji.drawAt(circle.center, Palette::Orange);
	}
}

振り返りチェックリスト

  • MouseL, MouseR.down() で、左クリック、右クリックされたかを調べることを学んだ
  • Cursor::Pos() で、マウスカーソルの位置を得ることを学んだ
  • CircleRect, RectF.leftClicked() で、その図形が左クリックされたかを判定できることを学んだ
  • CircleRect, RectF.mouseOver() で、マウスカーソルがその図形の上にあるかを判定できることを学んだ
  • Cursor::RequestStyle(CursorStyle::Hand); で、マウスカーソルを手の形にできることを学んだ
  • 絵文字(テクスチャ)には .leftClicked().mouseOver() が無いため、代わりに近い大きさの円を使って判定するテクニックを学んだ

8. 乱数

8.1 乱数を生成する

Random(a, b) は a 以上 b 以下の数を返します。ただし a < b である必要があります。

  • 例: Random(0, 100), Random(0.8, 1.2)

#include <Siv3D.hpp>

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

	while (System::Update())
	{
		// 左クリックされたら
		if (MouseL.down())
		{
            // 0 以上 2 以下のランダムな整数を作る
			int32 n = Random(0, 2);

			if (n == 0)
			{
				Print << U"大吉";
			}
			else if (n == 1)
			{
				Print << U"小吉";
			}
			else
			{
				Print << U"凶";
			}
		}		
	}
}

8.2 ランダムな場所に移動する

画面を左クリックするたびに絵文字がランダムな場所に移動するサンプルです。

#include <Siv3D.hpp>

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

	const Texture emoji{ U"☃️"_emoji };

	double x = 400.0;

	double y = 300.0;

	while (System::Update())
	{
		// 左クリックされたら
		if (MouseL.down())
		{
			// ランダムな X 座標を代入
			x = Random(50, 750);

			// ランダムな Y 座標を代入
			y = Random(50, 550);
		}

		emoji.drawAt(x, y);
	}
}

振り返りチェックリスト

  • Random(a, b) は a 以上 b 以下の数を返すことを学んだ

9. 簡単なアプリやゲームを作る

9.1 カウンター

絵文字をクリックするとカウントが増えるアプリです。

#include <Siv3D.hpp>

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

	const Texture emoji{ U"🛎️"_emoji };

	// フォントを作成する
	const Font font{ FontMethod::MSDF, 48 };

    // 押した回数
	int32 count = 0;

	while (System::Update())
	{
		if (Circle{ 500, 300, 70 }.leftClicked())
		{
			++count;
		}

		font(U"{} 回"_fmt(count)).draw(50, 200, 300, Palette::Black);

		Circle{ 500, 300, 70 }.draw(ColorF{ 1.0, 1.0, 1.0, 0.5 });

		emoji.drawAt(500, 300);
	}
}

9.2 クッキークリッカー

クッキーをたくさんクリックするゲームです。

#include <Siv3D.hpp>

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

	const Texture emoji{ U"🍪"_emoji };

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

	// スコア
	int32 score = 0;

    // クッキーの X 座標
	double cookieX = 400;

    // クッキーの Y 座標
	double cookieY = 300;

	while (System::Update())
	{
		if (Circle{ cookieX, cookieY, 70 }.leftClicked())
		{
			score += 100;
			cookieX = Random(50, 750);
			cookieY = Random(50, 550);
		}

		emoji.drawAt(cookieX, cookieY);

		font(U"スコア: {}"_fmt(score)).draw(50, 50, 50, Palette::Black);
	}
}

最終課題・前半

📝 提出課題

「9.2 クッキークリッカー」のプログラムを自由にアレンジして発展させた Siv3D プログラムを作成し、コードまたは コードの共有 URL(Wandbox)を提出してください。

発展させるアイデアの例

  • 背景に色や模様を付ける(前回の提出課題を取り込む)
  • クリック対象を増やす(新しい絵文字と、その絵文字の座標用の変数を追加する)
  • クリックしてはいけないものを登場させる(クリックするとスコアが減る)
  • クリック対象を動かす
  • UI のデザインを変える
  • 時間制限を付ける
    • int32 time = 1200; を毎フレーム --time で減らしていく

🍎 絵文字を含むコードは Wandbox を使う 🚙

Moodle の仕様により、コード記入欄に絵文字が含まれると提出がエラーになることがあります。その場合は Wandbox でコードを書いて、コードの共有 URL(Wandbox) で提出してください。

Wandbox は Siv3D に対応していないため、Wandbox 上では Siv3D のプログラムはコンパイルエラーになりますが、気にする必要はありません。