Siv3D | 脱出ゲームを作る Day 1
このコースでは、初歩的な C++ の文法と OpenSiv3D の機能を使って、シンプルな脱出ゲームを作ります。
1. 絵文字の表示
画面にアイテムを表示しましょう。
画面に画像を描きたいときは Texture
を作成し、.draw()
または .drawAt()
します。.drawAt()
では、テクスチャの中心をどこに据えるかをシーンの座標で指定します。
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main()
{
const Texture computerTexture{ Emoji{ U"🖥️" } };
const Texture boxTexture{ Emoji{ U"🗃️" } };
const Texture doorTexture{ Emoji{ U"🚪" } };
while (System::Update())
{
computerTexture.drawAt(200, 300);
boxTexture.drawAt(400, 300);
doorTexture.drawAt(600, 300);
}
}
2. 背景の色
背景の色を変えましょう。
背景の色を変えるには Scene::SetBackground()
関数に色を渡します。色の表現には ColorF
を使います。ColorF
では、0.0 - 1.0 の範囲で RGB の各成分を指定します。
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main()
{
Scene::SetBackground(ColorF{ 0.9, 0.85, 0.8 });
const Texture computerTexture{ Emoji{ U"🖥️" } };
const Texture boxTexture{ Emoji{ U"🗃️" } };
const Texture doorTexture{ Emoji{ U"🚪" } };
while (System::Update())
{
computerTexture.drawAt(200, 300);
boxTexture.drawAt(400, 300);
doorTexture.drawAt(600, 300);
}
}
3. アイテムの領域
アイテムの領域を円 (Circle
) で表現して表示しましょう。
ColorF
の 4 番目の引数は不透明度を 0.0-1.0 で示します。0.0 は完全に透明で、0.5 は半分透過、1.0 は透過無しです。この値のことをアルファ値とも呼びます。
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main()
{
Scene::SetBackground(ColorF{ 0.9, 0.85, 0.8 });
const Texture computerTexture{ Emoji{ U"🖥️" } };
const Texture boxTexture{ Emoji{ U"🗃️" } };
const Texture doorTexture{ Emoji{ U"🚪" } };
const Circle computerCircle{ 200, 300, 80 };
const Circle boxCircle{ 400, 300, 80 };
const Circle doorCircle{ 600, 300, 80 };
while (System::Update())
{
computerTexture.drawAt(200, 300);
computerCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
boxTexture.drawAt(400, 300);
boxCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
doorTexture.drawAt(600, 300);
doorCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
}
}
4. マウスカーソルの変更
マウスカーソルがアイテムの領域上にあるときにカーソルのスタイルを手のアイコンに変更するようにしましょう。
Circle
の上にマウスカーソルが重なっているかを .mouseOver()
で調べられます。マウスカーソルを手のアイコンにするには Cursor::RequestStyle()
関数に CursorStyle::Hand
を渡します。
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main()
{
Scene::SetBackground(ColorF{ 0.9, 0.85, 0.8 });
const Texture computerTexture{ Emoji{ U"🖥️" } };
const Texture boxTexture{ Emoji{ U"🗃️" } };
const Texture doorTexture{ Emoji{ U"🚪" } };
const Circle computerCircle{ 200, 300, 80 };
const Circle boxCircle{ 400, 300, 80 };
const Circle doorCircle{ 600, 300, 80 };
while (System::Update())
{
computerTexture.drawAt(200, 300);
computerCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
boxTexture.drawAt(400, 300);
boxCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
doorTexture.drawAt(600, 300);
doorCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
if (computerCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (boxCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (doorCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
}
}
5. メッセージの表示
アイテムをクリックしたときにメッセージを表示しましょう。
Circle
が左クリックされたかを .leftClicked()
で調べられます。Print
にテキストを <<
で送ると、画面の左上にそのテキストが表示され続けます。
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main()
{
Scene::SetBackground(ColorF{ 0.9, 0.85, 0.8 });
const Texture computerTexture{ Emoji{ U"🖥️" } };
const Texture boxTexture{ Emoji{ U"🗃️" } };
const Texture doorTexture{ Emoji{ U"🚪" } };
const Circle computerCircle{ 200, 300, 80 };
const Circle boxCircle{ 400, 300, 80 };
const Circle doorCircle{ 600, 300, 80 };
while (System::Update())
{
computerTexture.drawAt(200, 300);
computerCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
boxTexture.drawAt(400, 300);
boxCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
doorTexture.drawAt(600, 300);
doorCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
if (computerCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (boxCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (doorCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (computerCircle.leftClicked())
{
Print << U"パソコンだ。電源は入らない。";
}
if (boxCircle.leftClicked())
{
Print << U"箱の中に何か入っている。部屋の鍵を見つけた!";
}
if (doorCircle.leftClicked())
{
Print << U"ドアには鍵がかかっている。出られない。";
}
}
}
6. メッセージの消去
新しいアイテムをクリックしたときに、古いメッセージを消去しましょう。
Print
したメッセージを消去するには、ClearPrint()
を使います。
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main()
{
Scene::SetBackground(ColorF{ 0.9, 0.85, 0.8 });
const Texture computerTexture{ Emoji{ U"🖥️" } };
const Texture boxTexture{ Emoji{ U"🗃️" } };
const Texture doorTexture{ Emoji{ U"🚪" } };
const Circle computerCircle{ 200, 300, 80 };
const Circle boxCircle{ 400, 300, 80 };
const Circle doorCircle{ 600, 300, 80 };
while (System::Update())
{
computerTexture.drawAt(200, 300);
computerCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
boxTexture.drawAt(400, 300);
boxCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
doorTexture.drawAt(600, 300);
doorCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
if (computerCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (boxCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (doorCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (computerCircle.leftClicked())
{
ClearPrint();
Print << U"パソコンだ。電源は入らない。";
}
if (boxCircle.leftClicked())
{
ClearPrint();
Print << U"箱の中に何か入っている。部屋の鍵を見つけた!";
}
if (doorCircle.leftClicked())
{
ClearPrint();
Print << U"ドアには鍵がかかっている。出られない。";
}
}
}
7. フラグの管理
状態を表す変数を追加し、イベントを管理できるようにしましょう。
true
または false
を表現できる bool
型の変数を使って、イベントの ON/OFF を管理します。
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
void Main()
{
Scene::SetBackground(ColorF{ 0.9, 0.85, 0.8 });
const Texture computerTexture{ Emoji{ U"🖥️" } };
const Texture boxTexture{ Emoji{ U"🗃️" } };
const Texture doorTexture{ Emoji{ U"🚪" } };
const Circle computerCircle{ 200, 300, 80 };
const Circle boxCircle{ 400, 300, 80 };
const Circle doorCircle{ 600, 300, 80 };
// 箱が開けられたか
bool boxOpened = false;
// プレイヤーが鍵を持っているか
bool playerHasKey = false;
while (System::Update())
{
computerTexture.drawAt(200, 300);
computerCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
boxTexture.drawAt(400, 300);
boxCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
doorTexture.drawAt(600, 300);
doorCircle.draw(ColorF{ 1.0, 0.5, 0.0, 0.2 });
if (computerCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (boxCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (doorCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (computerCircle.leftClicked())
{
ClearPrint();
Print << U"パソコンだ。電源は入らない。";
}
if (boxCircle.leftClicked())
{
ClearPrint();
if (boxOpened)
{
Print << U"箱の中にはもう役に立ちそうなものは入っていない。";
}
else
{
Print << U"箱の中に何か入っている。部屋の鍵を見つけた。";
boxOpened = true;
playerHasKey = true;
}
}
if (doorCircle.leftClicked())
{
ClearPrint();
if (playerHasKey)
{
Print << U"持っている鍵を使ってドアを開くことができた!";
}
else
{
Print << U"ドアには鍵がかかっている。出られない。";
}
}
}
}
▶ Day 2 に続く
Discussion