// // Created by Grant Horner on 11/30/25. // #pragma once #include #include "raylib.h" struct Player { Rectangle rect; uint8_t lives; float speed; float invulnerability_secs; double last_hit; float tear_speed; float tear_range; float tear_radius; double last_fired; double fire_rate; [[nodiscard]] Vector2 center() const noexcept; [[nodiscard]] bool is_invulnerable(double now) const noexcept; void move(Vector2 delta); }; enum Direction { UP, DOWN, LEFT, RIGHT }; struct Tear { Tear() noexcept = default; Tear(const Vector2 center, const Direction direction) noexcept : center(center), direction(direction), active(true), starting_center(center) { }; Vector2 center; Direction direction; bool active; Vector2 starting_center; }; struct Enemy { Vector2 center; float radius; float speed; bool alive; }; enum ItemType { TEARS_UP, TEARS_DOWN, RANGE_UP, RANGE_DOWN, ITEM_TYPE_COUNT }; template <> struct std::formatter : std::formatter { bool title_case = false; constexpr auto parse(std::format_parse_context& ctx) { auto it = ctx.begin(); if (it == ctx.end()) return it; if (*it == 't') { title_case = true; ++it; } return it; } auto format(const ItemType& item_type, std::format_context& ctx) const { std::string_view item_type_str; switch (item_type) { case TEARS_UP: item_type_str = title_case ? "Tears Up" : "TEARS_UP"; break; case TEARS_DOWN: item_type_str = title_case ? "Tears Down" : "TEARS_DOWN"; break; case RANGE_UP: item_type_str = title_case ? "Range Up" : "RANGE_UP"; break; case RANGE_DOWN: item_type_str = title_case ? "Range Down" : "RANGE_DOWN"; break; case ITEM_TYPE_COUNT: item_type_str = title_case ? "Item Type Count" : "ITEM_TYPE_COUNT"; break; } return std::formatter::format(item_type_str, ctx);; } }; struct Item { Vector2 center; float radius; ItemType type; bool active; [[nodiscard]] Color color() const noexcept { switch (type) { case TEARS_UP: return BLUE; case TEARS_DOWN: return GREEN; case RANGE_UP: return RED; case RANGE_DOWN: return ORANGE; case ITEM_TYPE_COUNT: assert(0 && "ITEM_TYPE_COUNT should not be instantiated."); } assert(0 && "Unreachable."); } };