// Starfield3D.h - 3D Parallax Starfield Effect (canonical) #pragma once #include #include #include #include class Starfield3D { public: Starfield3D(); ~Starfield3D() = default; void init(int width, int height, int starCount = 160); void update(float deltaTime); void draw(SDL_Renderer* renderer, float offsetX = 0.0f, float offsetY = 0.0f, float alphaScale = 1.0f, bool grayscale = false); void resize(int width, int height); private: struct Star3D { float x, y, z; float vx, vy, vz; float targetVx, targetVy, targetVz; float changeTimer; bool changing; int type; }; // Helpers used by the implementation void createStarfield(); void updateStar(int index); void setRandomDirection(Star3D& star); float randomFloat(float min, float max); int randomRange(int min, int max); void drawStar(SDL_Renderer* renderer, float x, float y, SDL_Color color, float alphaScale); std::vector stars; int width{0}, height{0}; float centerX{0}, centerY{0}; // Random number generator std::mt19937 rng; // Visual / behavioral constants (tweakable) inline static constexpr float MAX_VELOCITY = 0.5f; inline static constexpr float REVERSE_PROBABILITY = 0.12f; inline static constexpr float STAR_SPEED = 0.6f; inline static constexpr float MAX_DEPTH = 120.0f; inline static constexpr float DIRECTION_CHANGE_PROBABILITY = 0.002f; inline static constexpr float VELOCITY_CHANGE = 0.02f; inline static constexpr float MIN_Z = 0.1f; inline static constexpr float MAX_Z = MAX_DEPTH; inline static constexpr float DEPTH_FACTOR = 320.0f; inline static constexpr int COLOR_COUNT = 5; inline static const std::array STAR_COLORS = { SDL_Color{255,255,255,255}, SDL_Color{200,200,255,255}, SDL_Color{255,220,180,255}, SDL_Color{180,220,255,255}, SDL_Color{255,180,200,255} }; };