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

4
rng.h
View File

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

10
types.h
View File

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