stars directions

This commit is contained in:
2025-12-01 21:01:53 +01:00
parent 383b2e48ec
commit 294e935344
3 changed files with 151 additions and 5 deletions

View File

@ -11,6 +11,7 @@ constexpr float MIN_ASPECT = 0.001f;
SpaceWarp::SpaceWarp() { SpaceWarp::SpaceWarp() {
std::random_device rd; std::random_device rd;
rng.seed(rd()); rng.seed(rd());
setFlightMode(SpaceWarpFlightMode::Forward);
} }
void SpaceWarp::init(int w, int h, int starCount) { 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; 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) { float SpaceWarp::randomRange(float min, float max) {
std::uniform_real_distribution<float> dist(min, max); std::uniform_real_distribution<float> dist(min, max);
return dist(rng); return dist(rng);
@ -79,12 +127,43 @@ void SpaceWarp::update(float deltaSeconds) {
return; return;
} }
for (auto& star : stars) { if (autoPilotEnabled) {
star.z -= star.speed * deltaSeconds; autoTimer -= deltaSeconds;
if (star.z <= minDepth) { if (autoTimer <= 0.0f) {
respawn(star, true); scheduleNewAutoTarget();
continue;
} }
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 sx = 0.0f;
float sy = 0.0f; float sy = 0.0f;

View File

@ -25,6 +25,20 @@ struct SpaceWarpSettings {
float maxTrailLength = 36.0f; // clamp length of each streak in pixels 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 { class SpaceWarp {
public: public:
SpaceWarp(); SpaceWarp();
@ -34,6 +48,12 @@ public:
void draw(SDL_Renderer* renderer, float alphaScale = 1.0f); void draw(SDL_Renderer* renderer, float alphaScale = 1.0f);
void setSettings(const SpaceWarpSettings& newSettings); void setSettings(const SpaceWarpSettings& newSettings);
const SpaceWarpSettings& getSettings() const { return settings; } 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: private:
struct WarpStar { struct WarpStar {
@ -63,7 +83,16 @@ private:
float warpFactor = 520.0f; float warpFactor = 520.0f;
SpaceWarpSettings settings{}; 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 minDepth = 2.0f;
float maxDepth = 320.0f; float maxDepth = 320.0f;
void scheduleNewAutoTarget();
}; };

View File

@ -781,6 +781,10 @@ int main(int, char **)
starfield3D.init(LOGICAL_W, LOGICAL_H, 200); starfield3D.init(LOGICAL_W, LOGICAL_H, 200);
SpaceWarp spaceWarp; SpaceWarp spaceWarp;
spaceWarp.init(LOGICAL_W, LOGICAL_H, 420); spaceWarp.init(LOGICAL_W, LOGICAL_H, 420);
SpaceWarpFlightMode warpFlightMode = SpaceWarpFlightMode::Forward;
spaceWarp.setFlightMode(warpFlightMode);
bool warpAutoPilotEnabled = true;
spaceWarp.setAutoPilotEnabled(true);
// Initialize line clearing effects // Initialize line clearing effects
LineEffect lineEffect; LineEffect lineEffect;
@ -1194,6 +1198,40 @@ int main(int, char **)
SDL_SetWindowFullscreen(window, isFullscreen ? SDL_WINDOW_FULLSCREEN : 0); SDL_SetWindowFullscreen(window, isFullscreen ? SDL_WINDOW_FULLSCREEN : 0);
Settings::instance().setFullscreen(isFullscreen); 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 // Text input for high score