떨어진 음식 모으기 게임 만들기 Day 2
9. 음식 이동
음식을 떨어뜨려라.
음식의 이동량은 게이머의 이동량과 마찬가지로 속도와 프레임 시간을 바탕으로 계산된다.
또 프로그램을 더 잘 예측하기 위해 주 순환 중 3개 영역을'플레이어의 이동','음식의 이동','그림'으로 나눠 각각
{ }
범위로 둘러쌌다.이렇게 하면 다른 부분에서 견본const double move
등 국부 변수를 사용하여 변수의 범위를 유한한 양호한 상태에 있게 할 수 있다.(변수 하나를 어디서나 사용할 수 있으면 프로그램의 변경과 유지보수가 번거로워진다.){
// セクション A
{
int32 a = 10; // この変数が使えるのは現在のスコープ { } 内のみ
}
// セクション B
{
// ここで a は使えない
}
// セクション C
{
int32 a = 30; // ここで別の変数 a を作れる
}
}
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 食べ物クラス
struct Food
{
Vec2 pos;
};
void Main()
{
// プレイヤーのテクスチャ
const Texture playerTexture{ Emoji{ U"😋" } };
// 食べ物のテクスチャ
const Texture foodTexture{ Emoji{ U"🍰" } };
// プレイヤーが毎秒何ピクセルの速さで移動するか
double playerSpeed = 300.0;
// 食べ物が毎秒何ピクセルの速さで落下するか
double foodSpeed = 200.0;
// プレイヤーの位置
Vec2 playerPos{ 400, 500 };
// 食べ物
Array<Food> foods;
foods << Food{ .pos = Vec2{ 300, 100 } };
foods << Food{ .pos = Vec2{ 500, 200 } };
foods << Food{ .pos = Vec2{ 700, 300 } };
while (System::Update())
{
// プレイヤーの移動
{
if (KeyLeft.pressed()) // 左矢印キーが押されていたら
{
playerPos.x -= (playerSpeed * Scene::DeltaTime());
}
else if (KeyRight.pressed()) // 右矢印キーが押されていたら
{
playerPos.x += (playerSpeed * Scene::DeltaTime());
}
// playerPos.x を 50 以上、750 以下に収める
playerPos.x = Clamp(playerPos.x, 50.0, 750.0);
}
// 食べ物の移動
{
const double move = (foodSpeed * Scene::DeltaTime());
for (auto& food : foods)
{
food.pos.y += move;
}
}
// 描画
{
// 空を描く(グラデーション)
Rect{ 0, 0, 800, 520 }
.draw(Arg::top = ColorF{ 0.1, 0.3, 0.6 }, Arg::bottom = ColorF{ 0.3, 0.7, 1.0 });
// 地面を描く
Rect{ 0, 520, 800, 80 }.draw(ColorF{ 0.2, 0.6, 0.3 });
// プレイヤーを描く
playerTexture.drawAt(playerPos);
for (const auto& food : foods)
{
// 食べ物を描く(サイズは 0.5 倍)
foodTexture.scaled(0.5).drawAt(food.pos);
}
}
}
}
10. 바닥에 떨어진 음식 제거
앞으로 음식을 늘리려면 음식이 계속 떨어지면 처리 원가가 끊임없이 증가한다.이동이나 드로잉이 발생하지 않도록 바닥에 떨어진 음식을 배열에서 삭제합니다.
Array
의 구성원 변수.remove_if(pred)
는 수조에서 조건pred
을 충족시키는 요소를 삭제한다.음식이 땅에 떨어졌는지 판단하는 함수CheckFood()
를 만들어 건네주기remove_if()
.또한 게임 변수의 상태를 쉽게 이해하기 위해'디버깅 디스플레이'구역에 음식의 개수를 표시할 수 있다.
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 食べ物クラス
struct Food
{
Vec2 pos;
};
// 食べ物を消す条件を記述した関数
bool CheckFood(const Food& food)
{
// 食べ物の Y 座標が 600 より大きいか
return (600 < food.pos.y);
}
void Main()
{
// プレイヤーのテクスチャ
const Texture playerTexture{ Emoji{ U"😋" } };
// 食べ物のテクスチャ
const Texture foodTexture{ Emoji{ U"🍰" } };
// プレイヤーが毎秒何ピクセルの速さで移動するか
double playerSpeed = 300.0;
// 食べ物が毎秒何ピクセルの速さで落下するか
double foodSpeed = 200.0;
// プレイヤーの位置
Vec2 playerPos{ 400, 500 };
// 食べ物
Array<Food> foods;
foods << Food{ .pos = Vec2{ 300, 100 } };
foods << Food{ .pos = Vec2{ 500, 200 } };
foods << Food{ .pos = Vec2{ 700, 300 } };
while (System::Update())
{
// デバッグ表示
{
ClearPrint();
Print << U"食べ物の個数: " << foods.size();
}
// プレイヤーの移動
{
if (KeyLeft.pressed()) // 左矢印キーが押されていたら
{
playerPos.x -= (playerSpeed * Scene::DeltaTime());
}
else if (KeyRight.pressed()) // 右矢印キーが押されていたら
{
playerPos.x += (playerSpeed * Scene::DeltaTime());
}
// playerPos.x を 50 以上、750 以下に収める
playerPos.x = Clamp(playerPos.x, 50.0, 750.0);
}
// 食べ物の移動
{
const double move = (foodSpeed * Scene::DeltaTime());
for (auto& food : foods)
{
food.pos.y += move;
}
}
// 地面に落ちた食べ物の消去
{
// 条件を満たす要素を配列から削除
foods.remove_if(CheckFood);
}
// 描画
{
// 空を描く(グラデーション)
Rect{ 0, 0, 800, 520 }
.draw(Arg::top = ColorF{ 0.1, 0.3, 0.6 }, Arg::bottom = ColorF{ 0.3, 0.7, 1.0 });
// 地面を描く
Rect{ 0, 520, 800, 80 }.draw(ColorF{ 0.2, 0.6, 0.3 });
// プレイヤーを描く
playerTexture.drawAt(playerPos);
for (const auto& food : foods)
{
// 食べ物を描く(サイズは 0.5 倍)
foodTexture.scaled(0.5).drawAt(food.pos);
}
}
}
}
11. 바닥에 떨어진 음식을 제거한다(고무로 개량한다)
만약 C++의 문법인'등자식'을 사용한다면
CheckFood()
함수는 remove_if()
에서 λ식으로 기술할 수 있고 프로그램은 짧아질 것이다.# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 食べ物クラス
struct Food
{
Vec2 pos;
};
void Main()
{
// プレイヤーのテクスチャ
const Texture playerTexture{ Emoji{ U"😋" } };
// 食べ物のテクスチャ
const Texture foodTexture{ Emoji{ U"🍰" } };
// プレイヤーが毎秒何ピクセルの速さで移動するか
double playerSpeed = 300.0;
// 食べ物が毎秒何ピクセルの速さで落下するか
double foodSpeed = 200.0;
// プレイヤーの位置
Vec2 playerPos{ 400, 500 };
// 食べ物
Array<Food> foods;
foods << Food{ .pos = Vec2{ 300, 100 } };
foods << Food{ .pos = Vec2{ 500, 200 } };
foods << Food{ .pos = Vec2{ 700, 300 } };
while (System::Update())
{
// デバッグ表示
{
ClearPrint();
Print << U"食べ物の個数: " << foods.size();
}
// プレイヤーの移動
{
if (KeyLeft.pressed()) // 左矢印キーが押されていたら
{
playerPos.x -= (playerSpeed * Scene::DeltaTime());
}
else if (KeyRight.pressed()) // 右矢印キーが押されていたら
{
playerPos.x += (playerSpeed * Scene::DeltaTime());
}
// playerPos.x を 50 以上、750 以下に収める
playerPos.x = Clamp(playerPos.x, 50.0, 750.0);
}
// 食べ物の移動
{
const double move = (foodSpeed * Scene::DeltaTime());
for (auto& food : foods)
{
food.pos.y += move;
}
}
// 地面に落ちた食べ物の消去
{
// 条件を満たす要素を配列から削除(ラムダ式で記述)
foods.remove_if([](const Food& food){ return (600 < food.pos.y); });
}
// 描画
{
// 空を描く(グラデーション)
Rect{ 0, 0, 800, 520 }
.draw(Arg::top = ColorF{ 0.1, 0.3, 0.6 }, Arg::bottom = ColorF{ 0.3, 0.7, 1.0 });
// 地面を描く
Rect{ 0, 520, 800, 80 }.draw(ColorF{ 0.2, 0.6, 0.3 });
// プレイヤーを描く
playerTexture.drawAt(playerPos);
for (const auto& food : foods)
{
// 食べ物を描く(サイズは 0.5 倍)
foodTexture.scaled(0.5).drawAt(food.pos);
}
}
}
}
12. 음식이 나온다
시간이 지나면 음식이 나온다.
음식이 몇 초 간격으로 나타났다는 변수
foodSpawnTime
를 나타내고, 지난번 음식이 나온 후 몇 초 경과한 변수timeAccumulator
를 추가로 나타내며,'음식이 나타났다'는 부분에서 일정 시간 간격으로 무작위 장소에서 음식이 생성된다.Random(min, max)
는 되돌아오는 min
이상max
이하의 무작위 함수다.# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 食べ物クラス
struct Food
{
Vec2 pos;
};
void Main()
{
// プレイヤーのテクスチャ
const Texture playerTexture{ Emoji{ U"😋" } };
// 食べ物のテクスチャ
const Texture foodTexture{ Emoji{ U"🍰" } };
// プレイヤーが毎秒何ピクセルの速さで移動するか
double playerSpeed = 300.0;
// 食べ物が毎秒何ピクセルの速さで落下するか
double foodSpeed = 200.0;
// 何秒ごとに食べ物が出現するか
double foodSpawnTime = 1.0;
// 前回の食べ物の出現から何秒経過したか
double timeAccumulator = 0.0;
// プレイヤーの位置
Vec2 playerPos{ 400, 500 };
// 食べ物
Array<Food> foods;
foods << Food{ .pos = Vec2{ 300, 100 } };
foods << Food{ .pos = Vec2{ 500, 200 } };
foods << Food{ .pos = Vec2{ 700, 300 } };
while (System::Update())
{
// デバッグ表示
{
ClearPrint();
Print << U"食べ物の個数: " << foods.size();
Print << U"timeAccumulator: " << timeAccumulator;
}
// プレイヤーの移動
{
if (KeyLeft.pressed()) // 左矢印キーが押されていたら
{
playerPos.x -= (playerSpeed * Scene::DeltaTime());
}
else if (KeyRight.pressed()) // 右矢印キーが押されていたら
{
playerPos.x += (playerSpeed * Scene::DeltaTime());
}
// playerPos.x を 50 以上、750 以下に収める
playerPos.x = Clamp(playerPos.x, 50.0, 750.0);
}
// 食べ物の出現
{
// 経過時間の蓄積
timeAccumulator += Scene::DeltaTime();
// 食べ物の出現時間よりも長く経過していた場合
while (foodSpawnTime <= timeAccumulator)
{
// 食べ物をランダムな場所に出現させる
foods << Food{ .pos = Vec2{ Random(50.0, 750.0), -50 } };
// 経過時間を減らす
timeAccumulator -= foodSpawnTime;
}
}
// 食べ物の移動
{
const double move = (foodSpeed * Scene::DeltaTime());
for (auto& food : foods)
{
food.pos.y += move;
}
}
// 地面に落ちた食べ物の消去
{
// 条件を満たす要素を配列から削除(ラムダ式で記述)
foods.remove_if([](const Food& food) { return (600 < food.pos.y); });
}
// 描画
{
// 空を描く(グラデーション)
Rect{ 0, 0, 800, 520 }
.draw(Arg::top = ColorF{ 0.1, 0.3, 0.6 }, Arg::bottom = ColorF{ 0.3, 0.7, 1.0 });
// 地面を描く
Rect{ 0, 520, 800, 80 }.draw(ColorF{ 0.2, 0.6, 0.3 });
// プレイヤーを描く
playerTexture.drawAt(playerPos);
for (const auto& food : foods)
{
// 食べ物を描く(サイズは 0.5 倍)
foodTexture.scaled(0.5).drawAt(food.pos);
}
}
}
}
13. 유저가 음식 획득
유저가 음식에 접촉했을 때, 음식을 제거하세요.
구분자를 사용하면 요소에 접근하고 삭제할 수 있습니다.다음 주기를 생성합니다.
for (auto it = foods.begin(); it != foods.end();)
{
if (...) // 要素を削除する場合
{
it = foods.erase(it); // 要素を削除して次の要素へ
}
else // 要素を削除しない場合
{
++it; // 次の要素へ
}
}
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 食べ物クラス
struct Food
{
Vec2 pos;
};
void Main()
{
// プレイヤーのテクスチャ
const Texture playerTexture{ Emoji{ U"😋" } };
// 食べ物のテクスチャ
const Texture foodTexture{ Emoji{ U"🍰" } };
// プレイヤーが毎秒何ピクセルの速さで移動するか
double playerSpeed = 300.0;
// 食べ物が毎秒何ピクセルの速さで落下するか
double foodSpeed = 200.0;
// 何秒ごとに食べ物が出現するか
double foodSpawnTime = 1.0;
// 前回の食べ物の出現から何秒経過したか
double timeAccumulator = 0.0;
// プレイヤーの位置
Vec2 playerPos{ 400, 500 };
// 食べ物
Array<Food> foods;
foods << Food{ .pos = Vec2{ 300, 100 } };
foods << Food{ .pos = Vec2{ 500, 200 } };
foods << Food{ .pos = Vec2{ 700, 300 } };
while (System::Update())
{
// デバッグ表示
{
ClearPrint();
Print << U"食べ物の個数: " << foods.size();
Print << U"timeAccumulator: " << timeAccumulator;
}
// プレイヤーの移動
{
if (KeyLeft.pressed()) // 左矢印キーが押されていたら
{
playerPos.x -= (playerSpeed * Scene::DeltaTime());
}
else if (KeyRight.pressed()) // 右矢印キーが押されていたら
{
playerPos.x += (playerSpeed * Scene::DeltaTime());
}
// playerPos.x を 50 以上、750 以下に収める
playerPos.x = Clamp(playerPos.x, 50.0, 750.0);
}
// 食べ物の出現
{
// 経過時間の蓄積
timeAccumulator += Scene::DeltaTime();
// 食べ物の出現時間よりも長く経過していた場合
while (foodSpawnTime <= timeAccumulator)
{
// 食べ物をランダムな場所に出現させる
foods << Food{ .pos = Vec2{ Random(50.0, 750.0), -50 } };
// 経過時間を減らす
timeAccumulator -= foodSpawnTime;
}
}
// 食べ物の移動
{
const double move = (foodSpeed * Scene::DeltaTime());
for (auto& food : foods)
{
food.pos.y += move;
}
}
// 地面に落ちた食べ物の消去
{
// 条件を満たす要素を配列から削除(ラムダ式で記述)
foods.remove_if([](const Food& food) { return (600 < food.pos.y); });
}
// プレイヤーによる食べ物の獲得
{
// プレイヤーのあたり判定円
const Circle playerCircle{ playerPos, 60 };
// イテレータで全ての食べ物をたどる
for (auto it = foods.begin(); it != foods.end();)
{
// 食べ物のあたり判定円
const Circle foodCircle{ it->pos, 30 };
if (playerCircle.intersects(foodCircle)) // 交差していたら
{
it = foods.erase(it); // 要素を削除して次の要素へ
}
else
{
++it; // 次の要素へ
}
}
}
// 描画
{
// 空を描く(グラデーション)
Rect{ 0, 0, 800, 520 }
.draw(Arg::top = ColorF{ 0.1, 0.3, 0.6 }, Arg::bottom = ColorF{ 0.3, 0.7, 1.0 });
// 地面を描く
Rect{ 0, 520, 800, 80 }.draw(ColorF{ 0.2, 0.6, 0.3 });
// プレイヤーを描く
playerTexture.drawAt(playerPos);
for (const auto& food : foods)
{
// 食べ物を描く(サイズは 0.5 倍)
foodTexture.scaled(0.5).drawAt(food.pos);
}
}
// あたり判定円のデバッグ表示
{
// プレイヤーのあたり判定円
Circle{ playerPos, 60 }.draw(ColorF{ 1.0, 1.0, 1.0, 0.5 });
for (const auto& food : foods)
{
// 食べ物のあたり判定円
Circle{ food.pos, 30 }.draw(ColorF{ 1.0, 1.0, 1.0, 0.5 });
}
}
}
}
14. 음식의 변화 증가
떨어진 음식의 변화를 증가시키다.
NumFoods
의 상수에 따라 음식의 종류를 결정한다.그리고 Food
류에 음식의 종류를 나타내는 구성원 변수type
를 첨가하여 0
~(NumFood - 1)
범위의 값을 설정한다.이 값을 색인으로 사용하기 위해 음식 무늬의 배열std::array<Texture, NumFoods>
을 준비했다.# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 食べ物の種類
constexpr size_t NumFoods = 3;
// 食べ物クラス
struct Food
{
Vec2 pos;
size_t type = 0; // 0: 🍬, 1: 🍩, 2: 🍰
};
void Main()
{
// プレイヤーのテクスチャ
const Texture playerTexture{ Emoji{ U"😋" } };
// 食べ物のテクスチャ
const std::array<Texture, NumFoods> foodTextures =
{
Texture{ Emoji{ U"🍬" }},
Texture{ Emoji{ U"🍩" }},
Texture{ Emoji{ U"🍰" }},
};
// プレイヤーが毎秒何ピクセルの速さで移動するか
double playerSpeed = 300.0;
// 食べ物が毎秒何ピクセルの速さで落下するか
double foodSpeed = 200.0;
// 何秒ごとに食べ物が出現するか
double foodSpawnTime = 1.0;
// 前回の食べ物の出現から何秒経過したか
double timeAccumulator = 0.0;
// プレイヤーの位置
Vec2 playerPos{ 400, 500 };
// 食べ物
Array<Food> foods;
foods << Food{ .pos = Vec2{ 300, 100 }, .type = 2 };
foods << Food{ .pos = Vec2{ 500, 200 }, .type = 1 };
foods << Food{ .pos = Vec2{ 700, 300 }, .type = 0 };
while (System::Update())
{
// デバッグ表示
{
ClearPrint();
Print << U"食べ物の個数: " << foods.size();
Print << U"timeAccumulator: " << timeAccumulator;
}
// プレイヤーの移動
{
if (KeyLeft.pressed()) // 左矢印キーが押されていたら
{
playerPos.x -= (playerSpeed * Scene::DeltaTime());
}
else if (KeyRight.pressed()) // 右矢印キーが押されていたら
{
playerPos.x += (playerSpeed * Scene::DeltaTime());
}
// playerPos.x を 50 以上、750 以下に収める
playerPos.x = Clamp(playerPos.x, 50.0, 750.0);
}
// 食べ物の出現
{
// 経過時間の蓄積
timeAccumulator += Scene::DeltaTime();
// 食べ物の出現時間よりも長く経過していた場合
while (foodSpawnTime <= timeAccumulator)
{
// 食べ物をランダムな場所に出現させる
foods << Food{ .pos = Vec2{ Random(50.0, 750.0), -50 },
.type = Random<size_t>(0, NumFoods - 1) };
// 経過時間を減らす
timeAccumulator -= foodSpawnTime;
}
}
// 食べ物の移動
{
const double move = (foodSpeed * Scene::DeltaTime());
for (auto& food : foods)
{
food.pos.y += move;
}
}
// 地面に落ちた食べ物の消去
{
// 条件を満たす要素を配列から削除(ラムダ式で記述)
foods.remove_if([](const Food& food) { return (600 < food.pos.y); });
}
// プレイヤーによる食べ物の獲得
{
// プレイヤーのあたり判定円
const Circle playerCircle{ playerPos, 60 };
// イテレータで全ての食べ物をたどる
for (auto it = foods.begin(); it != foods.end();)
{
// 食べ物のあたり判定円
const Circle foodCircle{ it->pos, 30 };
if (playerCircle.intersects(foodCircle)) // 交差していたら
{
it = foods.erase(it); // 要素を削除して次の要素へ
}
else
{
++it; // 次の要素へ
}
}
}
// 描画
{
// 空を描く(グラデーション)
Rect{ 0, 0, 800, 520 }
.draw(Arg::top = ColorF{ 0.1, 0.3, 0.6 }, Arg::bottom = ColorF{ 0.3, 0.7, 1.0 });
// 地面を描く
Rect{ 0, 520, 800, 80 }.draw(ColorF{ 0.2, 0.6, 0.3 });
// プレイヤーを描く
playerTexture.drawAt(playerPos);
for (const auto& food : foods)
{
// 食べ物を描く(サイズは 0.5 倍)
foodTextures[food.type].scaled(0.5).drawAt(food.pos);
}
}
}
}
15. 음식에 대한 평점
점수를 도입하면 음식에 따라 점수가 달라진다.
Food
의type
를 인덱스로 접근할 수 있는 득점 배열std::array<int32, NumFoods>
을 준비한다.# include <Siv3D.hpp> // OpenSiv3D v0.4.3
// 食べ物の種類
constexpr size_t NumFoods = 3;
// 食べ物クラス
struct Food
{
Vec2 pos;
size_t type = 0; // 0: 🍬, 1: 🍩, 2: 🍰
};
void Main()
{
// プレイヤーのテクスチャ
const Texture playerTexture{ Emoji{ U"😋" } };
// 食べ物のテクスチャ
const std::array<Texture, NumFoods> foodTextures =
{
Texture{ Emoji{ U"🍬" }},
Texture{ Emoji{ U"🍩" }},
Texture{ Emoji{ U"🍰" }},
};
// 食べ物の獲得スコア
const std::array<int32, NumFoods> foodScores =
{
10, 20, 100
};
// プレイヤーが毎秒何ピクセルの速さで移動するか
double playerSpeed = 300.0;
// 食べ物が毎秒何ピクセルの速さで落下するか
double foodSpeed = 200.0;
// 何秒ごとに食べ物が出現するか
double foodSpawnTime = 1.0;
// 前回の食べ物の出現から何秒経過したか
double timeAccumulator = 0.0;
// プレイヤーの位置
Vec2 playerPos{ 400, 500 };
// スコア
int32 score = 0;
// 食べ物
Array<Food> foods;
foods << Food{ .pos = Vec2{ 300, 100 }, .type = 2 };
foods << Food{ .pos = Vec2{ 500, 200 }, .type = 1 };
foods << Food{ .pos = Vec2{ 700, 300 }, .type = 0 };
while (System::Update())
{
// デバッグ表示
{
ClearPrint();
Print << U"食べ物の個数: " << foods.size();
Print << U"timeAccumulator: " << timeAccumulator;
Print << U"スコア: " << score;
}
// プレイヤーの移動
{
if (KeyLeft.pressed()) // 左矢印キーが押されていたら
{
playerPos.x -= (playerSpeed * Scene::DeltaTime());
}
else if (KeyRight.pressed()) // 右矢印キーが押されていたら
{
playerPos.x += (playerSpeed * Scene::DeltaTime());
}
// playerPos.x を 50 以上、750 以下に収める
playerPos.x = Clamp(playerPos.x, 50.0, 750.0);
}
// 食べ物の出現
{
// 経過時間の蓄積
timeAccumulator += Scene::DeltaTime();
// 食べ物の出現時間よりも長く経過していた場合
while (foodSpawnTime <= timeAccumulator)
{
// 食べ物をランダムな場所に出現させる
foods << Food{ .pos = Vec2{ Random(50.0, 750.0), -50 },
.type = Random<size_t>(0, NumFoods - 1) };
// 経過時間を減らす
timeAccumulator -= foodSpawnTime;
}
}
// 食べ物の移動
{
const double move = (foodSpeed * Scene::DeltaTime());
for (auto& food : foods)
{
food.pos.y += move;
}
}
// 地面に落ちた食べ物の消去
{
// 条件を満たす要素を配列から削除(ラムダ式で記述)
foods.remove_if([](const Food& food) { return (600 < food.pos.y); });
}
// プレイヤーによる食べ物の獲得
{
// プレイヤーのあたり判定円
const Circle playerCircle{ playerPos, 60 };
// イテレータで全ての食べ物をたどる
for (auto it = foods.begin(); it != foods.end();)
{
// 食べ物のあたり判定円
const Circle foodCircle{ it->pos, 30 };
if (playerCircle.intersects(foodCircle)) // 交差していたら
{
score += foodScores[it->type]; // スコアを加算(要素を削除する前に it を使うこと!)
it = foods.erase(it); // 要素を削除して次の要素へ
}
else
{
++it; // 次の要素へ
}
}
}
// 描画
{
// 空を描く(グラデーション)
Rect{ 0, 0, 800, 520 }
.draw(Arg::top = ColorF{ 0.1, 0.3, 0.6 }, Arg::bottom = ColorF{ 0.3, 0.7, 1.0 });
// 地面を描く
Rect{ 0, 520, 800, 80 }.draw(ColorF{ 0.2, 0.6, 0.3 });
// プレイヤーを描く
playerTexture.drawAt(playerPos);
for (const auto& food : foods)
{
// 食べ物を描く(サイズは 0.5 倍)
foodTextures[food.type].scaled(0.5).drawAt(food.pos);
}
}
}
}
▶ 이어서 Day 3 (준비 중)
Reference
이 문제에 관하여(떨어진 음식 모으기 게임 만들기 Day 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/reputeless/articles/course-catch-the-food-2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)