add level edge

This commit is contained in:
2025-12-01 11:26:47 -05:00
parent 77cb83cfd5
commit 17663a1f75

View File

@@ -10,6 +10,15 @@
float screen_width = 800; float screen_width = 800;
float screen_height = 600; float screen_height = 600;
float padding = 50;
float level_width = screen_width - padding * 2;
float level_height = screen_height - padding * 2;
float level_left = padding;
float level_top = padding;
float level_right = level_width + padding;
float level_bottom = level_height + padding;
Rectangle walls[] = {}; Rectangle walls[] = {};
Player player; Player player;
@@ -48,11 +57,11 @@ 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->x + delta_x, 0.0f),
screen_width - this->width); level_right - this->width);
const 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),
screen_height - this->height); level_bottom - this->height);
bool collided = false; bool collided = false;
const Rectangle next_position = { const Rectangle next_position = {
@@ -83,24 +92,24 @@ struct EnemySpawner final : Spawner<Enemy, 100> {
void spawn() override { void spawn() override {
const auto num = Rng::generate(); const auto num = Rng::generate();
const auto starting_x = Rng::generate(static_cast<uint32_t>(screen_width)); const auto starting_x = Rng::generate(static_cast<int>(level_left), static_cast<int>(level_right));
const auto starting_y = Rng::generate(static_cast<uint32_t>(screen_height)); const auto starting_y = Rng::generate(static_cast<int>(level_top), static_cast<int>(level_bottom));
for (auto &[center, radius, speed, alive]: this->values) { for (auto &[center, radius, speed, alive]: this->values) {
if (alive) continue; if (alive) continue;
alive = true; alive = true;
radius = enemy_radius; radius = enemy_radius;
if (num < 0.25) { if (num < 0.25) {
center = {.x = starting_x, .y = 0}; center = {.x = starting_x, .y = level_top};
} else if (0.25 <= num && num < 0.5) { } else if (0.25 <= num && num < 0.5) {
center = { center = {
.x = starting_x, .y = (screen_height) .x = starting_x, .y = level_bottom
}; };
} else if (0.5 <= num && num < 0.75) { } else if (0.5 <= num && num < 0.75) {
center = {.x = 0, .y = starting_y}; center = {.x = level_left, .y = starting_y};
} else { } else {
center = { center = {
.x = (screen_width), .y = starting_y .x = level_right, .y = starting_y
}; };
} }
@@ -119,8 +128,8 @@ struct ItemSpawner final : Spawner<Item, 100> {
void spawn() override { void spawn() override {
const auto item_type = static_cast<ItemType>(Rng::generate(ItemType::ITEM_TYPE_COUNT)); const auto item_type = static_cast<ItemType>(Rng::generate(ItemType::ITEM_TYPE_COUNT));
const auto x = Rng::generate(static_cast<uint32_t>(screen_width)); const auto x = Rng::generate(static_cast<int>(level_left), static_cast<int>(level_right));
const auto y = Rng::generate(static_cast<uint32_t>(screen_height)); const auto y = Rng::generate(static_cast<int>(level_top), static_cast<int>(level_bottom));
for (auto &item: this->values) { for (auto &item: this->values) {
if (item.active) continue; if (item.active) continue;
@@ -190,17 +199,17 @@ void update_tears() {
} }
int main() { int main() {
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
InitWindow(800, 600, "Isaac++"); InitWindow(800, 600, "Isaac++");
SetTargetFPS(60); SetTargetFPS(60);
enemy_spawner.start(); enemy_spawner.start();
item_spawner.start(); item_spawner.start();
player.width = 50; player.width = 50;
player.height = 50; player.height = 50;
player.x = screen_width / 2 - player.width / 2; player.x = level_width / 2 - player.width / 2;
player.y = screen_height / 2 - player.height / 2; player.y = level_height / 2 - player.height / 2;
player.lives = 3; player.lives = 3;
player.last_hit = -10; player.last_hit = -10;
@@ -219,6 +228,12 @@ int main() {
if (IsWindowResized()) { if (IsWindowResized()) {
screen_height = static_cast<float>(GetScreenHeight()); screen_height = static_cast<float>(GetScreenHeight());
screen_width = static_cast<float>(GetScreenWidth()); screen_width = static_cast<float>(GetScreenWidth());
level_width = screen_width - padding * 2;
level_height = screen_height - padding * 2;
level_left = padding;
level_top = padding;
level_right = level_width + padding;
level_bottom = level_height + padding;
} }
float delta_x = 0; float delta_x = 0;
@@ -254,7 +269,8 @@ int main() {
update_tears(); update_tears();
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE); 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) { for (const auto wall: walls) {
@@ -272,8 +288,8 @@ int main() {
enemy.center = Vector2MoveTowards(enemy.center, player.center(), enemy.speed); enemy.center = Vector2MoveTowards(enemy.center, player.center(), enemy.speed);
DrawCircleV(enemy.center, enemy.radius, RED); DrawCircleV(enemy.center, enemy.radius, RED);
if (enemy.center.x < 0 || screen_width < enemy.center.x || if (enemy.center.x < level_left || level_right < enemy.center.x ||
enemy.center.y < 0 || screen_height < enemy.center.y) { enemy.center.y < level_top || level_bottom < enemy.center.y) {
enemy.alive = false; enemy.alive = false;
} }
@@ -307,22 +323,30 @@ int main() {
case ITEM_TYPE_COUNT: case ITEM_TYPE_COUNT:
break; break;
} }
if (item_pickup_text_buffer.empty()) {
std::format_to(std::back_inserter(item_pickup_text_buffer), "{:t}!", item.type); std::format_to(std::back_inserter(item_pickup_text_buffer), "{:t}!", item.type);
} else {
std::format_to(std::back_inserter(item_pickup_text_buffer), " {:t}!", item.type);
}
item_last_picked_up = now; item_last_picked_up = now;
item.active = false; item.active = false;
} }
}); });
const int text_left = static_cast<int>(level_left) + 10;
DrawRectangle(level_left, static_cast<int>(level_height) - 110, 200, 110, {130, 130, 130, 100});
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, static_cast<int>(screen_height) - 100, 20, BLACK); DrawText(score_text_buffer.c_str(), text_left, static_cast<int>(level_height) - 100, 20, BLACK);
score_text_buffer.clear(); score_text_buffer.clear();
std::format_to(std::back_inserter(lives_text_buffer), "Lives: {}", player.lives); std::format_to(std::back_inserter(lives_text_buffer), "Lives: {}", player.lives);
DrawText(lives_text_buffer.c_str(), 50, static_cast<int>(screen_height) - 75, 20, BLACK); DrawText(lives_text_buffer.c_str(), text_left, static_cast<int>(level_height) - 75, 20, BLACK);
lives_text_buffer.clear(); lives_text_buffer.clear();
if (now < item_last_picked_up + item_pickup_message_duration && !item_pickup_text_buffer.empty()) { if (now < item_last_picked_up + item_pickup_message_duration && !item_pickup_text_buffer.empty()) {
DrawText(item_pickup_text_buffer.c_str(), 50, static_cast<int>(screen_height) - 50, 20, BLACK); DrawText(item_pickup_text_buffer.c_str(), text_left, static_cast<int>(level_height) - 50, 20, BLACK);
} }
if (item_last_picked_up + item_pickup_message_duration <= now && !item_pickup_text_buffer.empty()) { if (item_last_picked_up + item_pickup_message_duration <= now && !item_pickup_text_buffer.empty()) {