29. クッキークリッカー¶
チュートリアル 3 ~ 28 の内容を使って、クッキークリッカー風のゲームを作ります。
クッキークリッカーとは
- クッキークリッカーは、クッキーをクリックしてクッキーの数を増やしていくゲームです
- 増やしたクッキーを使って、クッキーを増やすための生産設備を購入できます
-
2013 年にオリジナルのゲームが公開されて人気を博し、その後、様々な派生ゲームが作られています
- Wikipedia: Cookie Clicker
29.1 基本実装¶
- ゲームの進行状況を表すクラス
GameInfo
を用意します- この先、0.1 秒単位でクッキーの枚数を増やす計算ができるよう、
int32
の代わりにdouble
型でクッキーの数を管理します - クッキーの生産設備である「農場」と「工場」の数を、
int32
で表現します
- この先、0.1 秒単位でクッキーの枚数を増やす計算ができるよう、
- ゲーム画面の背景を、画面全体を覆うグラデーションの長方形で描画します
Main
関数が複雑になりすぎないよう、処理は適宜関数に分割していきます
コード
# include <Siv3D.hpp>
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
void Main()
{
// ゲームの進行状況
GameInfo game;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
}
}
29.2 クッキーの描画¶
- クッキーの絵文字からテクスチャを作成し、画面に大きく描画します
- クッキーの大きさにモーションをつけられるよう、クッキーの表示サイズを変数
cookieScale
で管理します - クッキーのクリック判定用の円
cookieCircle
を用意し、クリックされたらクッキーの数を増やします
コード
# include <Siv3D.hpp>
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
void Main()
{
const Texture cookieEmoji{ U"🍪"_emoji };
// クッキーのクリック円
const Circle cookieCircle{ 170, 300, 90 };
// ゲームの進行状況
GameInfo game;
// クッキーの表示サイズ(倍率)
double cookieScale = 1.5;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
// クッキー円が左クリックされたら
if (cookieCircle.leftClicked())
{
game.cookies += 1;
}
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
// クッキーを描画する
cookieEmoji.scaled(cookieScale).drawAt(cookieCircle.center);
}
}
29.3 クッキーの枚数の表示¶
- クッキーの枚数を整数で表示します
コード
# include <Siv3D.hpp>
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
// クッキーの枚数を表示する関数
void DrawCookieCount(const GameInfo& game, const Font& font)
{
// クッキーの数を整数で表示する
font(U"{:.0f}"_fmt(game.cookies)).drawAt(60, Vec2{ 170, 100 });
}
void Main()
{
const Texture cookieEmoji{ U"🍪"_emoji };
const Font font{ FontMethod::MSDF, 48, Typeface::Bold };
// クッキーのクリック円
const Circle cookieCircle{ 170, 300, 90 };
// ゲームの進行状況
GameInfo game;
// クッキーの表示サイズ(倍率)
double cookieScale = 1.5;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
// クッキー円が左クリックされたら
if (cookieCircle.leftClicked())
{
game.cookies += 1;
}
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
// クッキーの数を表示する
DrawCookieCount(game, font);
// クッキーを描画する
cookieEmoji.scaled(cookieScale).drawAt(cookieCircle.center);
}
}
29.4 クリック体験の向上¶
cookieCircle
にマウスカーソルが重なっているとき、マウスカーソルを手の形に変更します- クッキーをクリックしたときに、
cookieScale
を一時的に小さくしますcookieScale
は時間の経過とともに1.5
に戻ります
コード
# include <Siv3D.hpp>
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
// クッキーの枚数を表示する関数
void DrawCookieCount(const GameInfo& game, const Font& font)
{
// クッキーの数を整数で表示する
font(U"{:.0f}"_fmt(game.cookies)).drawAt(60, Vec2{ 170, 100 });
}
void Main()
{
const Texture cookieEmoji{ U"🍪"_emoji };
const Font font{ FontMethod::MSDF, 48, Typeface::Bold };
// クッキーのクリック円
const Circle cookieCircle{ 170, 300, 90 };
// ゲームの進行状況
GameInfo game;
// クッキーの表示サイズ(倍率)
double cookieScale = 1.5;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
const double deltaTime = Scene::DeltaTime();
// クッキー円上にマウスカーソルがあれば
if (cookieCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
// クッキー円が左クリックされたら
if (cookieCircle.leftClicked())
{
cookieScale = 1.3;
game.cookies += 1;
}
// クッキーの表示サイズを回復する
cookieScale = Min((cookieScale + deltaTime), 1.5);
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
// クッキーの数を表示する
DrawCookieCount(game, font);
// クッキーを描画する
cookieEmoji.scaled(cookieScale).drawAt(cookieCircle.center);
}
}
29.5 設備購入ボタンの追加¶
- チュートリアル 28 を参考に、クッキーの生産設備を購入するためのボタンを追加します
- ボタンが押されたら、設備の数を増やします
- 引数
enabled
を使って、「ボタンが押せない」という状態も表現できるようにします
コード
# include <Siv3D.hpp>
// ボタンを描画する関数
bool Button(const Rect& rect, const Texture& texture, const Font& font, const String& name, const String& desc, int32 count, bool enabled)
{
// マウスカーソルがボタンの上にある場合
if (enabled && rect.mouseOver())
{
// マウスカーソルを手の形にする
Cursor::RequestStyle(CursorStyle::Hand);
}
// テキストの色
const ColorF textColor{ 0.4, 0.3, 0.2 };
// ボタンの背景の角丸四角形
const RoundRect roundRect = rect.rounded(6);
// 影と背景を描く
roundRect
.drawShadow(Vec2{ 2, 2 }, 12, 0)
.draw(ColorF{ 0.9, 0.8, 0.6 });
// 枠を描く
rect.stretched(-3).rounded(3)
.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });
// 絵文字を描く
texture.scaled(0.5).drawAt(rect.leftCenter().movedBy(50, 0));
// 設備の名前を描く
font(name).draw(30, rect.pos.movedBy(100, 15), textColor);
// 設備の説明を描く
font(desc).draw(18, rect.pos.movedBy(102, 60), textColor);
// 所有数を描く
font(count).draw(50, Arg::rightCenter = rect.tr().movedBy(-20, 50), textColor);
// 無効の場合は
if (not enabled)
{
// グレーの半透明を重ねる
roundRect.draw(ColorF{ 0.8, 0.6 });
}
// ボタンが押されたら true を返す
return (enabled && rect.leftClicked());
}
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
// クッキーの枚数を表示する関数
void DrawCookieCount(const GameInfo& game, const Font& font)
{
// クッキーの数を整数で表示する
font(U"{:.0f}"_fmt(game.cookies)).drawAt(60, Vec2{ 170, 100 });
}
void Main()
{
const Texture cookieEmoji{ U"🍪"_emoji };
const Texture farmEmoji{ U"🌾"_emoji };
const Texture factoryEmoji{ U"🏭"_emoji };
const Font font{ FontMethod::MSDF, 48, Typeface::Bold };
// クッキーのクリック円
const Circle cookieCircle{ 170, 300, 90 };
// ゲームの進行状況
GameInfo game;
// クッキーの表示サイズ(倍率)
double cookieScale = 1.5;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
const double deltaTime = Scene::DeltaTime();
// クッキー円上にマウスカーソルがあれば
if (cookieCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
// クッキー円が左クリックされたら
if (cookieCircle.leftClicked())
{
cookieScale = 1.3;
game.cookies += 1;
}
// クッキーの表示サイズを回復する
cookieScale = Min((cookieScale + deltaTime), 1.5);
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
// クッキーの数を表示する
DrawCookieCount(game, font);
// クッキーを描画する
cookieEmoji.scaled(cookieScale).drawAt(cookieCircle.center);
// 農場ボタン
if (Button(Rect{ 340, 40, 420, 100 }, farmEmoji, font, U"クッキー農場", U"1 CPS", game.farmCount, true))
{
++game.farmCount;
}
// 工場ボタン
if (Button(Rect{ 340, 160, 420, 100 }, factoryEmoji, font, U"クッキー工場", U"10 CPS", game.factoryCount, false))
{
++game.factoryCount;
}
}
}
29.6 クッキー生産量の計算¶
- 購入した設備の種類と数に応じて、毎秒のクッキー生産量(CPS: Cookies Per Second)を計算し、表示します
- 実際のクッキーの枚数にはまだ反映しません
コード
# include <Siv3D.hpp>
// ボタンを描画する関数
bool Button(const Rect& rect, const Texture& texture, const Font& font, const String& name, const String& desc, int32 count, bool enabled)
{
// マウスカーソルがボタンの上にある場合
if (enabled && rect.mouseOver())
{
// マウスカーソルを手の形にする
Cursor::RequestStyle(CursorStyle::Hand);
}
// テキストの色
const ColorF textColor{ 0.4, 0.3, 0.2 };
// ボタンの背景の角丸四角形
const RoundRect roundRect = rect.rounded(6);
// 影と背景を描く
roundRect
.drawShadow(Vec2{ 2, 2 }, 12, 0)
.draw(ColorF{ 0.9, 0.8, 0.6 });
// 枠を描く
rect.stretched(-3).rounded(3)
.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });
// 絵文字を描く
texture.scaled(0.5).drawAt(rect.leftCenter().movedBy(50, 0));
// 設備の名前を描く
font(name).draw(30, rect.pos.movedBy(100, 15), textColor);
// 設備の説明を描く
font(desc).draw(18, rect.pos.movedBy(102, 60), textColor);
// 所有数を描く
font(count).draw(50, Arg::rightCenter = rect.tr().movedBy(-20, 50), textColor);
// 無効の場合は
if (not enabled)
{
// グレーの半透明を重ねる
roundRect.draw(ColorF{ 0.8, 0.6 });
}
// ボタンが押されたら true を返す
return (enabled && rect.leftClicked());
}
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
// 毎秒のクッキー生産量 (cookies per second)
int32 getCPS() const
{
return (farmCount + factoryCount * 10);
}
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
// クッキーの枚数と CPS を表示する関数
void DrawCookieCount(const GameInfo& game, const Font& font)
{
// クッキーの数を整数で表示する
font(U"{:.0f}"_fmt(game.cookies)).drawAt(60, Vec2{ 170, 100 });
// クッキーの生産量を表示する
font(U"{} CPS"_fmt(game.getCPS())).drawAt(24, Vec2{ 170, 160 });
}
void Main()
{
const Texture cookieEmoji{ U"🍪"_emoji };
const Texture farmEmoji{ U"🌾"_emoji };
const Texture factoryEmoji{ U"🏭"_emoji };
const Font font{ FontMethod::MSDF, 48, Typeface::Bold };
// クッキーのクリック円
const Circle cookieCircle{ 170, 300, 90 };
// ゲームの進行状況
GameInfo game;
// クッキーの表示サイズ(倍率)
double cookieScale = 1.5;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
const double deltaTime = Scene::DeltaTime();
// クッキー円上にマウスカーソルがあれば
if (cookieCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
// クッキー円が左クリックされたら
if (cookieCircle.leftClicked())
{
cookieScale = 1.3;
game.cookies += 1;
}
// クッキーの表示サイズを回復する
cookieScale = Min((cookieScale + deltaTime), 1.5);
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
// クッキーの数と CPS を表示する
DrawCookieCount(game, font);
// クッキーを描画する
cookieEmoji.scaled(cookieScale).drawAt(cookieCircle.center);
// 農場ボタン
if (Button(Rect{ 340, 40, 420, 100 }, farmEmoji, font, U"クッキー農場", U"1 CPS", game.farmCount, true))
{
++game.farmCount;
}
// 工場ボタン
if (Button(Rect{ 340, 160, 420, 100 }, factoryEmoji, font, U"クッキー工場", U"10 CPS", game.factoryCount, false))
{
++game.factoryCount;
}
}
}
29.7 設備購入費用の実装¶
- 農場と工場の購入費用を計算し、表示します
- 購入数に応じて価格が上昇します
- 現在のクッキーの枚数が購入費用を下回っている場合は、ボタンを押せないようにします
- 設備を購入したときに、クッキーの枚数から購入費用を引くようにします
コード
# include <Siv3D.hpp>
// ボタンを描画する関数
bool Button(const Rect& rect, const Texture& texture, const Font& font, const String& name, const String& desc, int32 count, bool enabled)
{
// マウスカーソルがボタンの上にある場合
if (enabled && rect.mouseOver())
{
// マウスカーソルを手の形にする
Cursor::RequestStyle(CursorStyle::Hand);
}
// テキストの色
const ColorF textColor{ 0.4, 0.3, 0.2 };
// ボタンの背景の角丸四角形
const RoundRect roundRect = rect.rounded(6);
// 影と背景を描く
roundRect
.drawShadow(Vec2{ 2, 2 }, 12, 0)
.draw(ColorF{ 0.9, 0.8, 0.6 });
// 枠を描く
rect.stretched(-3).rounded(3)
.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });
// 絵文字を描く
texture.scaled(0.5).drawAt(rect.leftCenter().movedBy(50, 0));
// 設備の名前を描く
font(name).draw(30, rect.pos.movedBy(100, 15), textColor);
// 設備の説明を描く
font(desc).draw(18, rect.pos.movedBy(102, 60), textColor);
// 所有数を描く
font(count).draw(50, Arg::rightCenter = rect.tr().movedBy(-20, 50), textColor);
// 無効の場合は
if (not enabled)
{
// グレーの半透明を重ねる
roundRect.draw(ColorF{ 0.8, 0.6 });
}
// ボタンが押されたら true を返す
return (enabled && rect.leftClicked());
}
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
// 毎秒のクッキー生産量 (cookies per second)
int32 getCPS() const
{
return (farmCount + factoryCount * 10);
}
// 農場の価格
int32 getFarmCost() const
{
return (10 + farmCount * 10);
}
// 工場の価格
int32 getFactoryCost() const
{
return (100 + factoryCount * 100);
}
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
// クッキーの枚数と CPS を表示する関数
void DrawCookieCount(const GameInfo& game, const Font& font)
{
// クッキーの数を整数で表示する
font(U"{:.0f}"_fmt(game.cookies)).drawAt(60, Vec2{ 170, 100 });
// クッキーの生産量を表示する
font(U"{} CPS"_fmt(game.getCPS())).drawAt(24, Vec2{ 170, 160 });
}
void Main()
{
const Texture cookieEmoji{ U"🍪"_emoji };
const Texture farmEmoji{ U"🌾"_emoji };
const Texture factoryEmoji{ U"🏭"_emoji };
const Font font{ FontMethod::MSDF, 48, Typeface::Bold };
// クッキーのクリック円
const Circle cookieCircle{ 170, 300, 90 };
// ゲームの進行状況
GameInfo game;
// クッキーの表示サイズ(倍率)
double cookieScale = 1.5;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
const double deltaTime = Scene::DeltaTime();
// クッキー円上にマウスカーソルがあれば
if (cookieCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
// クッキー円が左クリックされたら
if (cookieCircle.leftClicked())
{
cookieScale = 1.3;
game.cookies += 1;
}
// クッキーの表示サイズを回復する
cookieScale = Min((cookieScale + deltaTime), 1.5);
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
// クッキーの数と CPS を表示する
DrawCookieCount(game, font);
// クッキーを描画する
cookieEmoji.scaled(cookieScale).drawAt(cookieCircle.center);
// 農場ボタン
if (Button(Rect{ 340, 40, 420, 100 }, farmEmoji, font, U"クッキー農場", U"C{} / 1 CPS"_fmt(game.getFarmCost()), game.farmCount, (game.getFarmCost() <= game.cookies)))
{
game.cookies -= game.getFarmCost();
++game.farmCount;
}
// 工場ボタン
if (Button(Rect{ 340, 160, 420, 100 }, factoryEmoji, font, U"クッキー工場", U"C{} / 10 CPS"_fmt(game.getFactoryCost()), game.factoryCount, (game.getFactoryCost() <= game.cookies)))
{
game.cookies -= game.getFactoryCost();
++game.factoryCount;
}
}
}
29.8 【完成】クッキー生産の反映¶
- 購入した設備の数に応じて、0.1 秒ごとにクッキーの枚数を増やします
- 0.1 秒ごとに、CPS × 0.1 のクッキーを追加します
コード
# include <Siv3D.hpp>
// ボタンを描画する関数
bool Button(const Rect& rect, const Texture& texture, const Font& font, const String& name, const String& desc, int32 count, bool enabled)
{
// マウスカーソルがボタンの上にある場合
if (enabled && rect.mouseOver())
{
// マウスカーソルを手の形にする
Cursor::RequestStyle(CursorStyle::Hand);
}
// テキストの色
const ColorF textColor{ 0.4, 0.3, 0.2 };
// ボタンの背景の角丸四角形
const RoundRect roundRect = rect.rounded(6);
// 影と背景を描く
roundRect
.drawShadow(Vec2{ 2, 2 }, 12, 0)
.draw(ColorF{ 0.9, 0.8, 0.6 });
// 枠を描く
rect.stretched(-3).rounded(3)
.drawFrame(2, ColorF{ 0.4, 0.3, 0.2 });
// 絵文字を描く
texture.scaled(0.5).drawAt(rect.leftCenter().movedBy(50, 0));
// 設備の名前を描く
font(name).draw(30, rect.pos.movedBy(100, 15), textColor);
// 設備の説明を描く
font(desc).draw(18, rect.pos.movedBy(102, 60), textColor);
// 所有数を描く
font(count).draw(50, Arg::rightCenter = rect.tr().movedBy(-20, 50), textColor);
// 無効の場合は
if (not enabled)
{
// グレーの半透明を重ねる
roundRect.draw(ColorF{ 0.8, 0.6 });
}
// ボタンが押されたら true を返す
return (enabled && rect.leftClicked());
}
// ゲームの進行状況
struct GameInfo
{
// クッキーの数
double cookies = 0.0;
// 農場の数
int32 farmCount = 0;
// 工場の数
int32 factoryCount = 0;
// 毎秒のクッキー生産量 (cookies per second)
int32 getCPS() const
{
return (farmCount + factoryCount * 10);
}
// 農場の価格
int32 getFarmCost() const
{
return (10 + farmCount * 10);
}
// 工場の価格
int32 getFactoryCost() const
{
return (100 + factoryCount * 100);
}
};
// 背景を描く関数
void DrawBackground()
{
Rect{ 800, 600 }.draw(Arg::top(0.6, 0.5, 0.3), Arg::bottom(0.2, 0.5, 0.3));
}
// クッキーの枚数と CPS を表示する関数
void DrawCookieCount(const GameInfo& game, const Font& font)
{
// クッキーの数を整数で表示する
font(U"{:.0f}"_fmt(game.cookies)).drawAt(60, Vec2{ 170, 100 });
// クッキーの生産量を表示する
font(U"{} CPS"_fmt(game.getCPS())).drawAt(24, Vec2{ 170, 160 });
}
void Main()
{
const Texture cookieEmoji{ U"🍪"_emoji };
const Texture farmEmoji{ U"🌾"_emoji };
const Texture factoryEmoji{ U"🏭"_emoji };
const Font font{ FontMethod::MSDF, 48, Typeface::Bold };
// クッキーのクリック円
const Circle cookieCircle{ 170, 300, 90 };
// ゲームの進行状況
GameInfo game;
// クッキーの表示サイズ(倍率)
double cookieScale = 1.5;
// ゲームの経過時間の蓄積(秒)
double accumulatedTime = 0.0;
while (System::Update())
{
/////////////////////////////////
//
// 更新
//
/////////////////////////////////
const double deltaTime = Scene::DeltaTime();
// ゲームの経過時間を加算する
accumulatedTime += deltaTime;
// 0.1 秒以上蓄積していたら
if (0.1 <= accumulatedTime)
{
// 0.1 秒分のクッキー生産を加算する
game.cookies += (game.getCPS() * 0.1);
accumulatedTime -= 0.1;
}
// クッキー円上にマウスカーソルがあれば
if (cookieCircle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
// クッキー円が左クリックされたら
if (cookieCircle.leftClicked())
{
cookieScale = 1.3;
game.cookies += 1;
}
// クッキーの表示サイズを回復する
cookieScale = Min((cookieScale + deltaTime), 1.5);
/////////////////////////////////
//
// 描画
//
/////////////////////////////////
// 背景を描く
DrawBackground();
// クッキーの数と CPS を表示する
DrawCookieCount(game, font);
// クッキーを描画する
cookieEmoji.scaled(cookieScale).drawAt(cookieCircle.center);
// 農場ボタン
if (Button(Rect{ 340, 40, 420, 100 }, farmEmoji, font, U"クッキー農場", U"C{} / 1 CPS"_fmt(game.getFarmCost()), game.farmCount, (game.getFarmCost() <= game.cookies)))
{
game.cookies -= game.getFarmCost();
++game.farmCount;
}
// 工場ボタン
if (Button(Rect{ 340, 160, 420, 100 }, factoryEmoji, font, U"クッキー工場", U"C{} / 10 CPS"_fmt(game.getFactoryCost()), game.factoryCount, (game.getFactoryCost() <= game.cookies)))
{
game.cookies -= game.getFactoryCost();
++game.factoryCount;
}
}
}