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