From 294e93534455035abdd1bc97e564ed8c8a962248 Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Mon, 1 Dec 2025 21:01:53 +0100 Subject: [PATCH] stars directions --- src/graphics/effects/SpaceWarp.cpp | 89 ++++++++++++++++++++++++++++-- src/graphics/effects/SpaceWarp.h | 29 ++++++++++ src/main.cpp | 38 +++++++++++++ 3 files changed, 151 insertions(+), 5 deletions(-) diff --git a/src/graphics/effects/SpaceWarp.cpp b/src/graphics/effects/SpaceWarp.cpp index 4acf0ed..ad5ff28 100644 --- a/src/graphics/effects/SpaceWarp.cpp +++ b/src/graphics/effects/SpaceWarp.cpp @@ -11,6 +11,7 @@ constexpr float MIN_ASPECT = 0.001f; SpaceWarp::SpaceWarp() { std::random_device rd; rng.seed(rd()); + setFlightMode(SpaceWarpFlightMode::Forward); } void SpaceWarp::init(int w, int h, int starCount) { @@ -34,6 +35,53 @@ void SpaceWarp::setSettings(const SpaceWarpSettings& newSettings) { warpFactor = std::max(width, height) * settings.warpFactorScale; } +void SpaceWarp::setFlightMode(SpaceWarpFlightMode mode) { + flightMode = mode; + autoPilotEnabled = false; + switch (mode) { + case SpaceWarpFlightMode::Forward: + motion = {1.0f, 0.0f, 0.0f}; + break; + case SpaceWarpFlightMode::BankLeft: + motion = {1.05f, -0.85f, 0.0f}; + break; + case SpaceWarpFlightMode::BankRight: + motion = {1.05f, 0.85f, 0.0f}; + break; + case SpaceWarpFlightMode::Reverse: + motion = {-0.6f, 0.0f, 0.0f}; + break; + case SpaceWarpFlightMode::Custom: + default: + break; + } +} + +void SpaceWarp::setFlightMotion(const SpaceWarpFlightMotion& newMotion) { + motion = newMotion; + flightMode = SpaceWarpFlightMode::Custom; + autoPilotEnabled = false; +} + +void SpaceWarp::setAutoPilotEnabled(bool enabled) { + autoPilotEnabled = enabled; + if (enabled) { + flightMode = SpaceWarpFlightMode::Custom; + motionTarget = motion; + autoTimer = 0.0f; + } +} + +void SpaceWarp::scheduleNewAutoTarget() { + motionTarget.forwardScale = randomRange(0.82f, 1.28f); + if (randomRange(0.0f, 1.0f) < 0.12f) { + motionTarget.forwardScale = -randomRange(0.35f, 0.85f); + } + motionTarget.lateralSpeed = randomRange(-1.35f, 1.35f); + motionTarget.verticalSpeed = randomRange(-0.75f, 0.75f); + autoTimer = randomRange(autoMinInterval, autoMaxInterval); +} + float SpaceWarp::randomRange(float min, float max) { std::uniform_real_distribution dist(min, max); return dist(rng); @@ -79,12 +127,43 @@ void SpaceWarp::update(float deltaSeconds) { return; } - for (auto& star : stars) { - star.z -= star.speed * deltaSeconds; - if (star.z <= minDepth) { - respawn(star, true); - continue; + if (autoPilotEnabled) { + autoTimer -= deltaSeconds; + if (autoTimer <= 0.0f) { + scheduleNewAutoTarget(); } + auto follow = std::clamp(deltaSeconds * 0.45f, 0.0f, 1.0f); + motion.forwardScale = std::lerp(motion.forwardScale, motionTarget.forwardScale, follow); + motion.lateralSpeed = std::lerp(motion.lateralSpeed, motionTarget.lateralSpeed, follow); + motion.verticalSpeed = std::lerp(motion.verticalSpeed, motionTarget.verticalSpeed, follow); + } + + const float forwardScale = (std::abs(motion.forwardScale) < 0.01f) + ? (motion.forwardScale >= 0.0f ? 0.01f : -0.01f) + : motion.forwardScale; + const bool movingBackward = forwardScale < 0.0f; + const float lateralSpeed = motion.lateralSpeed; + const float verticalSpeed = motion.verticalSpeed; + + for (auto& star : stars) { + star.z -= star.speed * deltaSeconds * forwardScale; + if (!movingBackward) { + if (star.z <= minDepth) { + respawn(star, true); + continue; + } + } else { + if (star.z >= maxDepth) { + respawn(star, true); + star.z = minDepth + randomRange(0.25f, 24.0f); + continue; + } + } + + float closeness = 1.0f - std::clamp(star.z / maxDepth, 0.0f, 1.0f); + float driftScale = (0.35f + closeness * 1.25f); + star.x += lateralSpeed * deltaSeconds * driftScale; + star.y += verticalSpeed * deltaSeconds * driftScale; float sx = 0.0f; float sy = 0.0f; diff --git a/src/graphics/effects/SpaceWarp.h b/src/graphics/effects/SpaceWarp.h index 1a51d9c..82d58a2 100644 --- a/src/graphics/effects/SpaceWarp.h +++ b/src/graphics/effects/SpaceWarp.h @@ -25,6 +25,20 @@ struct SpaceWarpSettings { float maxTrailLength = 36.0f; // clamp length of each streak in pixels }; +struct SpaceWarpFlightMotion { + float forwardScale = 1.0f; // multiplier applied to each star's forward velocity (negative = backwards) + float lateralSpeed = 0.0f; // normalized horizontal drift speed (left/right) + float verticalSpeed = 0.0f; // normalized vertical drift speed (up/down) +}; + +enum class SpaceWarpFlightMode { + Forward = 0, + BankLeft, + BankRight, + Reverse, + Custom +}; + class SpaceWarp { public: SpaceWarp(); @@ -34,6 +48,12 @@ public: void draw(SDL_Renderer* renderer, float alphaScale = 1.0f); void setSettings(const SpaceWarpSettings& newSettings); const SpaceWarpSettings& getSettings() const { return settings; } + void setFlightMode(SpaceWarpFlightMode mode); + SpaceWarpFlightMode getFlightMode() const { return flightMode; } + void setFlightMotion(const SpaceWarpFlightMotion& motion); // overrides mode with Custom + const SpaceWarpFlightMotion& getFlightMotion() const { return motion; } + void setAutoPilotEnabled(bool enabled); + bool isAutoPilotEnabled() const { return autoPilotEnabled; } private: struct WarpStar { @@ -63,7 +83,16 @@ private: float warpFactor = 520.0f; SpaceWarpSettings settings{}; + SpaceWarpFlightMotion motion{}; + SpaceWarpFlightMode flightMode = SpaceWarpFlightMode::Forward; + bool autoPilotEnabled = false; + float autoTimer = 0.0f; + float autoMinInterval = 3.5f; + float autoMaxInterval = 7.5f; + SpaceWarpFlightMotion motionTarget{}; float minDepth = 2.0f; float maxDepth = 320.0f; + + void scheduleNewAutoTarget(); }; diff --git a/src/main.cpp b/src/main.cpp index f1ff782..8a487dd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -781,6 +781,10 @@ int main(int, char **) starfield3D.init(LOGICAL_W, LOGICAL_H, 200); SpaceWarp spaceWarp; spaceWarp.init(LOGICAL_W, LOGICAL_H, 420); + SpaceWarpFlightMode warpFlightMode = SpaceWarpFlightMode::Forward; + spaceWarp.setFlightMode(warpFlightMode); + bool warpAutoPilotEnabled = true; + spaceWarp.setAutoPilotEnabled(true); // Initialize line clearing effects LineEffect lineEffect; @@ -1194,6 +1198,40 @@ int main(int, char **) SDL_SetWindowFullscreen(window, isFullscreen ? SDL_WINDOW_FULLSCREEN : 0); Settings::instance().setFullscreen(isFullscreen); } + if (e.key.scancode == SDL_SCANCODE_F5) + { + warpAutoPilotEnabled = false; + warpFlightMode = SpaceWarpFlightMode::Forward; + spaceWarp.setFlightMode(warpFlightMode); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Space warp mode: forward"); + } + if (e.key.scancode == SDL_SCANCODE_F6) + { + warpAutoPilotEnabled = false; + warpFlightMode = SpaceWarpFlightMode::BankLeft; + spaceWarp.setFlightMode(warpFlightMode); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Space warp mode: bank left"); + } + if (e.key.scancode == SDL_SCANCODE_F7) + { + warpAutoPilotEnabled = false; + warpFlightMode = SpaceWarpFlightMode::BankRight; + spaceWarp.setFlightMode(warpFlightMode); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Space warp mode: bank right"); + } + if (e.key.scancode == SDL_SCANCODE_F8) + { + warpAutoPilotEnabled = false; + warpFlightMode = SpaceWarpFlightMode::Reverse; + spaceWarp.setFlightMode(warpFlightMode); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Space warp mode: reverse"); + } + if (e.key.scancode == SDL_SCANCODE_F9) + { + warpAutoPilotEnabled = true; + spaceWarp.setAutoPilotEnabled(true); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Space warp autopilot engaged"); + } } // Text input for high score