refactor tear properties into Player

This commit is contained in:
2025-12-01 12:41:07 -05:00
parent ee5cb71560
commit 6a6249798e
3 changed files with 50 additions and 53 deletions

View File

@@ -24,14 +24,20 @@ Rectangle walls[] = {};
float player_width = 50; float player_width = 50;
Player player = { Player player = {
{ .rect = {
.x = level_width / 2 - player_width / 2, .x = level_width / 2 - player_width / 2,
.y = level_height / 2 - player_width / 2, .y = level_height / 2 - player_width / 2,
.width = player_width, .width = player_width,
.height = player_width, .height = player_width,
}, },
3, .lives = 3,
-10, .last_hit = -10,
.tear_speed = 10,
.tear_range = 300,
.tear_radius = 10.0f,
.last_fired = 0,
.fire_rate = .5,
}; };
auto player_speed = 5.0f; auto player_speed = 5.0f;
auto player_invulnerability = 1.0f; auto player_invulnerability = 1.0f;
@@ -39,26 +45,14 @@ auto player_invulnerability = 1.0f;
uint32_t score; uint32_t score;
std::array<Tear, 100> tears; std::array<Tear, 100> tears;
float tear_speed = 10;
float tear_range = 300;
float tear_radius = 10.0f;
double last_fired = 0;
double fire_rate = .5;
float enemy_max_speed = 3.0; float enemy_max_speed = 3.0;
float enemy_radius = 25.0; float enemy_radius = 25.0;
float item_radius = 10.0; float item_radius = 10.0;
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->rect.x + this->rect.width / 2, .y = this->rect.y + this->rect.height / 2};
}
Rectangle Player::rect() const noexcept {
return {.x = x, .y = y, .width = width, .height = height};
} }
bool Player::is_invulnerable(const double now) const noexcept { bool Player::is_invulnerable(const double now) const noexcept {
@@ -67,19 +61,19 @@ bool Player::is_invulnerable(const double now) const noexcept {
void Player::move(const float delta_x, const float delta_y) { void Player::move(const float delta_x, const float delta_y) {
const auto x = std::min( const auto x = std::min(
std::max(this->x + delta_x, 0.0f), std::max(this->rect.x + delta_x, 0.0f),
level_right - this->width); level_right - this->rect.width);
const auto y = std::min( const auto y = std::min(
std::max(this->y + delta_y, 0.0f), std::max(this->rect.y + delta_y, 0.0f),
level_bottom - this->height); level_bottom - this->rect.height);
bool collided = false; bool collided = false;
const Rectangle next_position = { const Rectangle next_position = {
.x = x, .x = x,
.y = y, .y = y,
.width = this->width, .width = this->rect.width,
.height = this->height .height = this->rect.height
}; };
for (const auto wall: walls) { for (const auto wall: walls) {
@@ -91,8 +85,8 @@ void Player::move(const float delta_x, const float delta_y) {
if (collided) { if (collided) {
} else { } else {
this->x = x; this->rect.x = x;
this->y = y; this->rect.y = y;
} }
} }
@@ -173,14 +167,14 @@ void update_tears() {
for (auto &[center, direction, active, starting_center]: tears) { for (auto &[center, direction, active, starting_center]: tears) {
if (active) { if (active) {
for (const auto wall: walls) { for (const auto wall: walls) {
if (CheckCollisionCircleRec(center, tear_radius, wall)) { if (CheckCollisionCircleRec(center, player.tear_radius, wall)) {
active = false; active = false;
break; break;
} }
} }
enemy_spawner.for_each([&center, &active](auto &enemy) { enemy_spawner.for_each([&center, &active](auto &enemy) {
if (enemy.alive && CheckCollisionCircles(center, 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; enemy.alive = false;
score++; score++;
@@ -189,20 +183,20 @@ void update_tears() {
switch (direction) { switch (direction) {
case UP: case UP:
center.y -= tear_speed; center.y -= player.tear_speed;
break; break;
case DOWN: case DOWN:
center.y += tear_speed; center.y += player.tear_speed;
break; break;
case LEFT: case LEFT:
center.x -= tear_speed; center.x -= player.tear_speed;
break; break;
case RIGHT: case RIGHT:
center.x += tear_speed; center.x += player.tear_speed;
break; break;
} }
if (tear_range < Vector2Distance(center, starting_center)) { if (player.tear_range < Vector2Distance(center, starting_center)) {
active = false; active = false;
} }
} }
@@ -240,14 +234,13 @@ int main() {
level_bottom = level_height + padding; level_bottom = level_height + padding;
} }
float delta_x = 0;
float delta_y = 0;
if (IsKeyDown(KEY_W)) delta_y -= player_speed; Vector2 delta{};
if (IsKeyDown(KEY_S)) delta_y += player_speed; if (IsKeyDown(KEY_W)) delta.y -= player_speed;
if (IsKeyDown(KEY_A)) delta_x -= player_speed; if (IsKeyDown(KEY_S)) delta.y += player_speed;
if (IsKeyDown(KEY_D)) delta_x += player_speed; if (IsKeyDown(KEY_A)) delta.x -= player_speed;
player.move(delta_x, delta_y); if (IsKeyDown(KEY_D)) delta.x += player_speed;
player.move(delta.x, delta.y);
std::optional<Direction> tear_direction; std::optional<Direction> tear_direction;
@@ -265,8 +258,8 @@ int main() {
} }
const auto now = GetTime(); const auto now = GetTime();
if (last_fired + fire_rate < now && tear_direction.has_value()) { if (player.last_fired + player.fire_rate < now && tear_direction.has_value()) {
last_fired = now; player.last_fired = now;
spawn_tear(player.center(), tear_direction.value()); spawn_tear(player.center(), tear_direction.value());
} }
@@ -275,7 +268,7 @@ int main() {
BeginDrawing(); BeginDrawing();
ClearBackground(GRAY); ClearBackground(GRAY);
DrawRectangle(50, 50, static_cast<int>(level_width), static_cast<int>(level_height), RAYWHITE); DrawRectangle(50, 50, static_cast<int>(level_width), static_cast<int>(level_height), RAYWHITE);
DrawRectangleRec(player.rect(), player.is_invulnerable(now) ? GOLD : BLUE); DrawRectangleRec(player.rect, player.is_invulnerable(now) ? GOLD : BLUE);
for (const auto wall: walls) { for (const auto wall: walls) {
DrawRectangleRec(wall, GREEN); DrawRectangleRec(wall, GREEN);
@@ -283,7 +276,7 @@ int main() {
for (const auto tear: tears) { for (const auto tear: tears) {
if (tear.active) { if (tear.active) {
DrawCircleV(tear.center, tear_radius, SKYBLUE); DrawCircleV(tear.center, player.tear_radius, SKYBLUE);
} }
} }
@@ -297,7 +290,7 @@ int main() {
enemy.alive = false; enemy.alive = false;
} }
if (CheckCollisionCircleRec(enemy.center, enemy.radius, player.rect()) && if (CheckCollisionCircleRec(enemy.center, enemy.radius, player.rect) &&
player.last_hit + player_invulnerability < now) { player.last_hit + player_invulnerability < now) {
player.lives--; player.lives--;
player.last_hit = now; player.last_hit = now;
@@ -310,19 +303,19 @@ int main() {
DrawCircleV(item.center, item.radius, item.color()); DrawCircleV(item.center, item.radius, item.color());
if (CheckCollisionCircleRec(item.center, item.radius, player.rect())) { if (CheckCollisionCircleRec(item.center, item.radius, player.rect)) {
switch (item.type) { switch (item.type) {
case TEARS_UP: case TEARS_UP:
fire_rate = std::max(fire_rate - 0.1, 0.1); player.fire_rate = std::max(player.fire_rate - 0.1, 0.1);
break; break;
case TEARS_DOWN: case TEARS_DOWN:
fire_rate += 0.1; player.fire_rate += 0.1;
break; break;
case RANGE_UP: case RANGE_UP:
tear_range += 100.0f; player.tear_range += 100.0f;
break; break;
case RANGE_DOWN: case RANGE_DOWN:
tear_range = std::max(tear_range - 100.0f, 100.0f); player.tear_range = std::max(player.tear_range - 100.0f, 100.0f);
break; break;
case ITEM_TYPE_COUNT: case ITEM_TYPE_COUNT:
break; break;

4
rng.h
View File

@@ -6,8 +6,8 @@
#include <random> #include <random>
struct Rng { struct Rng {
static std::random_device dev; inline static std::random_device dev;
static std::mt19937 rng; inline static std::mt19937 rng{dev()};
static float generate(); static float generate();

10
types.h
View File

@@ -8,14 +8,18 @@
#include "raylib.h" #include "raylib.h"
struct Player : Rectangle { struct Player {
Rectangle rect;
uint8_t lives; uint8_t lives;
double last_hit; double last_hit;
float tear_speed;
float tear_range;
float tear_radius;
double last_fired;
double fire_rate;
[[nodiscard]] Vector2 center() const noexcept; [[nodiscard]] Vector2 center() const noexcept;
[[nodiscard]] Rectangle rect() const noexcept;
[[nodiscard]] bool is_invulnerable(double now) const noexcept; [[nodiscard]] bool is_invulnerable(double now) const noexcept;
void move(float delta_x, float delta_y); void move(float delta_x, float delta_y);