Compare commits

..

2 Commits

Author SHA1 Message Date
5abfedb205 add cancel parameter for Spawner::for_each 2025-12-04 10:30:05 -05:00
eec22cd791 give enemies hp 2025-12-02 19:53:44 -05:00
4 changed files with 28 additions and 22 deletions

View File

@@ -90,32 +90,33 @@ struct EnemySpawner final : Spawner<Enemy, 100> {
const auto starting_y = Rng::generate(static_cast<int>(viewport.level_top), const auto starting_y = Rng::generate(static_cast<int>(viewport.level_top),
static_cast<int>(viewport.level_bottom)); static_cast<int>(viewport.level_bottom));
for (auto &[center, radius, speed, alive]: this->values) { for (auto &enemy: this->values) {
if (alive) continue; if (enemy.alive()) continue;
alive = true; enemy.radius = enemy_radius;
radius = enemy_radius; auto hp = Rng::generate(1, 4);
enemy.hp = static_cast<uint32_t>(hp);
if (num < 0.25) { if (num < 0.25) {
center = {.x = starting_x, .y = viewport.level_top}; enemy.center = {.x = starting_x, .y = viewport.level_top};
} else if (0.25 <= num && num < 0.5) { } else if (0.25 <= num && num < 0.5) {
center = { enemy.center = {
.x = starting_x, .y = viewport.level_bottom .x = starting_x, .y = viewport.level_bottom
}; };
} else if (0.5 <= num && num < 0.75) { } else if (0.5 <= num && num < 0.75) {
center = {.x = viewport.level_left, .y = starting_y}; enemy.center = {.x = viewport.level_left, .y = starting_y};
} else { } else {
center = { enemy.center = {
.x = viewport.level_right, .y = starting_y .x = viewport.level_right, .y = starting_y
}; };
} }
speed = Rng::generate(static_cast<uint32_t>(enemy_max_speed)); enemy.speed = Rng::generate(static_cast<uint32_t>(enemy_max_speed));
break; break;
} }
} }
}; };
EnemySpawner enemy_spawner{2}; EnemySpawner enemy_spawner{1};
struct ItemSpawner final : Spawner<Item, 100> { struct ItemSpawner final : Spawner<Item, 100> {
explicit ItemSpawner(const long long rate_secs) : Spawner<Item, 100>(rate_secs) { explicit ItemSpawner(const long long rate_secs) : Spawner<Item, 100>(rate_secs) {
@@ -163,11 +164,11 @@ void update_tears() {
} }
} }
enemy_spawner.for_each([&center, &active](auto &enemy) { enemy_spawner.for_each([&center, &active](auto &enemy, auto& cancel) {
if (enemy.alive && CheckCollisionCircles(center, player.tear_radius, enemy.center, enemy.radius)) { if (enemy.alive() && CheckCollisionCircles(center, player.tear_radius, enemy.center, enemy.radius)) {
active = false; active = false;
enemy.alive = false; if (--enemy.hp == 0) score++;
score++; cancel = true;
} }
}); });
@@ -265,14 +266,16 @@ int main() {
} }
} }
enemy_spawner.for_each([now](Enemy &enemy) { enemy_spawner.for_each([now](Enemy &enemy, auto& cancel) {
if (enemy.alive) { if (enemy.alive()) {
enemy.center = Vector2MoveTowards(enemy.center, player.center(), enemy.speed); enemy.center = Vector2MoveTowards(enemy.center, player.center(), enemy.speed);
DrawCircleV(enemy.center, enemy.radius, RED); const Color enemy_color = enemy.hp == 1 ? PINK : enemy.hp == 2 ? ORANGE : RED;
DrawCircleV(enemy.center, enemy.radius, enemy_color);
if (enemy.center.x < viewport.level_left || viewport.level_right < enemy.center.x || if (enemy.center.x < viewport.level_left || viewport.level_right < enemy.center.x ||
enemy.center.y < viewport.level_top || viewport.level_bottom < enemy.center.y) { enemy.center.y < viewport.level_top || viewport.level_bottom < enemy.center.y) {
enemy.alive = false; // Basically removing the enemy from the pool;
enemy.hp = 0;
} }
if (CheckCollisionCircleRec(enemy.center, enemy.radius, player.rect) && if (CheckCollisionCircleRec(enemy.center, enemy.radius, player.rect) &&
@@ -283,7 +286,7 @@ int main() {
} }
}); });
item_spawner.for_each([&item_pickup_text_buffer, now, &item_last_picked_up](Item &item) { item_spawner.for_each([&item_pickup_text_buffer, now, &item_last_picked_up](Item &item, auto& cancel) {
if (!item.active) return; if (!item.active) return;
DrawCircleV(item.center, item.radius, item.color()); DrawCircleV(item.center, item.radius, item.color());

View File

@@ -13,5 +13,5 @@ float Rng::generate(const uint32_t max) {
} }
float Rng::generate(const int min, const int max) { float Rng::generate(const int min, const int max) {
return generate() * (static_cast<float>(max) - static_cast<float>(min)) + static_cast<float>(min); return generate(max - min) + static_cast<float>(min);
} }

View File

@@ -24,7 +24,9 @@ struct Spawner {
void for_each(F&& func) { void for_each(F&& func) {
std::lock_guard lock{mutex}; std::lock_guard lock{mutex};
for (auto& value : values) { for (auto& value : values) {
func(value); bool cancel = false;
func(value, cancel);
if (cancel) break;;
} }
} }

View File

@@ -49,7 +49,8 @@ struct Enemy {
Vector2 center; Vector2 center;
float radius; float radius;
float speed; float speed;
bool alive; uint32_t hp;
[[nodiscard]] bool alive() const noexcept { return hp != 0; }
}; };
enum ItemType { enum ItemType {