diff --git a/main.cpp b/main.cpp index b280cf1..20363f9 100644 --- a/main.cpp +++ b/main.cpp @@ -7,8 +7,8 @@ #include "types.h" -auto screen_width = 800; -auto screen_height = 600; +float screen_width = 800; +float screen_height = 600; Rectangle walls[] = { // {.x = 100, .y = 100, .width = 5, .height = 100} }; @@ -25,26 +25,43 @@ float tear_radius = 10.0f; double last_fired = 0; double fire_rate = .5; -std::random_device dev; -std::mt19937 rng(dev()); - std::mutex enemy_mutex; float enemy_max_speed = 2.0; float enemy_radius = 25.0; Enemy enemies[100] = {}; +struct Rng { + static std::random_device dev; + static std::mt19937 rng; + + static float generate() { + return static_cast(rng()) / static_cast(std::mt19937::max()); + } + + static float generate(const uint32_t max) { + return generate() * static_cast(max); + } + + static float generate(const int min, const int max) { + return generate() * (static_cast(max) - static_cast(min)) + static_cast(min); + } +}; + +std::random_device Rng::dev{}; +std::mt19937 Rng::rng{dev()}; + Vector2 Player::center() const noexcept { return {.x = this->x + this->width / 2, .y = this->y + this->height / 2}; } void Player::move(const float delta_x, const float delta_y) { - auto x = std::min( + const auto x = std::min( std::max(this->x + delta_x, 0.0f), - static_cast(screen_width) - this->width); + screen_width - this->width); - auto y = std::min( + const auto y = std::min( std::max(this->y + delta_y, 0.0f), - static_cast(screen_height) - this->height); + screen_height - this->height); bool collided = false; const Rectangle next_position = { @@ -88,29 +105,35 @@ struct EnemySpawner { if (!paused.load()) { std::lock_guard lock(enemy_mutex); - const auto num = static_cast(rng()) / static_cast(std::mt19937::max()); - const auto dir = static_cast(rng()) / static_cast(std::mt19937::max()); + + const auto num = Rng::generate(); + const auto starting_x = Rng::generate(static_cast(screen_width)); + const auto starting_y = Rng::generate(static_cast(screen_height)); for (auto &[center, radius, moving, alive]: enemies) { if (alive) continue; alive = true; radius = enemy_radius; + const float normalized_dir = Rng::generate(-1, 1); if (num < 0.25) { - center = {.x = static_cast(screen_width) / 2, .y = 0}; - moving = {.x = (dir - 1) * 2, .y = 1}; + center = {.x = starting_x, .y = 0}; + moving = {.x = normalized_dir, .y = 1}; } else if (0.25 <= num && num < 0.5) { - center = {.x = static_cast(screen_width) / 2, .y = static_cast(screen_height)}; - moving = {.x = (dir - 1) * 2, .y = -1}; + center = { + .x = starting_x, .y = (screen_height) + }; + moving = {.x = normalized_dir, .y = -1}; } else if (0.5 <= num && num < 0.75) { - center = {.x = 0, .y = static_cast(screen_height) / 2}; - moving = {.x = 1, .y = (dir - 1) * 2}; + center = {.x = 0, .y = starting_y}; + moving = {.x = 1, .y = normalized_dir}; } else { - center = {.x = static_cast(screen_width), .y = static_cast(screen_height) / 2}; - moving = {.x = -1, .y = (dir - 1) * 2}; + center = { + .x = (screen_width), .y = starting_y + }; + moving = {.x = -1, .y = normalized_dir}; } - const auto speed_ratio = static_cast(rng()) / static_cast(std::mt19937::max()); - const auto speed = speed_ratio * enemy_max_speed; + const auto speed = Rng::generate(static_cast(enemy_max_speed)); moving = Vector2Scale(moving, speed); break; @@ -153,7 +176,7 @@ void update_tears() { } } - for (auto& enemy: enemies) { + for (auto &enemy: enemies) { if (CheckCollisionCircles(center, tear_radius, enemy.center, enemy.radius)) { active = false; enemy.alive = false; @@ -189,10 +212,11 @@ int main() { EnemySpawner spawner{3}; spawner.start(); - player.x = 10; - player.y = 10; + player.width = 50; player.height = 50; + player.x = screen_width / 2 - player.width / 2; + player.y = screen_height / 2 - player.height / 2; std::string score_text_buffer{64}; score_text_buffer.reserve(64); @@ -200,8 +224,8 @@ int main() { while (!WindowShouldClose()) { if (IsWindowResized()) { - screen_height = GetScreenHeight(); - screen_width = GetScreenWidth(); + screen_height = static_cast(GetScreenHeight()); + screen_width = static_cast(GetScreenWidth()); } float delta_x = 0; @@ -249,15 +273,23 @@ int main() { } } - for (auto& enemy: enemies) { - if (enemy.alive) { - enemy.center = Vector2Add(enemy.center, enemy.moving); - DrawCircleV(enemy.center, enemy.radius, RED); + { + std::lock_guard enemy_guard{enemy_mutex}; + for (auto &[center, radius, moving, alive]: enemies) { + if (alive) { + center = Vector2Add(center, moving); + DrawCircleV(center, radius, RED); + + if (center.x < 0 || screen_width < center.x || + center.y < 0 || screen_height < center.y) { + alive = false; + } + } } } std::format_to(std::back_inserter(score_text_buffer), "Score: {}", score); - DrawText(score_text_buffer.c_str(), 50, screen_height - 100, 20, BLACK); + DrawText(score_text_buffer.c_str(), 50, static_cast(screen_height) - 100, 20, BLACK); score_text_buffer.clear(); EndDrawing();