new background image

This commit is contained in:
2025-12-18 07:20:20 +01:00
parent 0ab7121c5b
commit 989b98002c
11 changed files with 233 additions and 27 deletions

View File

@ -107,8 +107,22 @@ void SpaceWarp::spawnComet() {
float normalizedAspect = std::max(aspect, MIN_ASPECT);
float xRange = settings.baseSpawnRange * 1.2f * (aspect >= 1.0f ? aspect : 1.0f);
float yRange = settings.baseSpawnRange * 1.2f * (aspect >= 1.0f ? 1.0f : (1.0f / normalizedAspect));
comet.x = randomRange(-xRange, xRange);
comet.y = randomRange(-yRange, yRange);
// Avoid spawning comets exactly on (or extremely near) the view axis,
// which can project to a nearly static bright dot.
const float axisMinFrac = 0.06f;
bool axisOk = false;
for (int attempt = 0; attempt < 10 && !axisOk; ++attempt) {
comet.x = randomRange(-xRange, xRange);
comet.y = randomRange(-yRange, yRange);
float nx = comet.x / std::max(xRange, 0.0001f);
float ny = comet.y / std::max(yRange, 0.0001f);
axisOk = (nx * nx + ny * ny) >= (axisMinFrac * axisMinFrac);
}
if (!axisOk) {
float ang = randomRange(0.0f, 6.28318530718f);
comet.x = std::cos(ang) * xRange * axisMinFrac;
comet.y = std::sin(ang) * yRange * axisMinFrac;
}
comet.z = randomRange(minDepth + 4.0f, maxDepth);
float baseSpeed = randomRange(settings.minSpeed, settings.maxSpeed);
float multiplier = randomRange(settings.cometSpeedMultiplierMin, settings.cometSpeedMultiplierMax);
@ -154,9 +168,24 @@ void SpaceWarp::respawn(WarpStar& star, bool randomDepth) {
float normalizedAspect = std::max(aspect, MIN_ASPECT);
float xRange = settings.baseSpawnRange * (aspect >= 1.0f ? aspect : 1.0f);
float yRange = settings.baseSpawnRange * (aspect >= 1.0f ? 1.0f : (1.0f / normalizedAspect));
star.x = randomRange(-xRange, xRange);
star.y = randomRange(-yRange, yRange);
star.z = randomDepth ? randomRange(minDepth, maxDepth) : maxDepth;
// Avoid axis-aligned stars (x≈0,y≈0) which can project to a static, bright center dot.
const float axisMinFrac = 0.06f;
bool axisOk = false;
for (int attempt = 0; attempt < 10 && !axisOk; ++attempt) {
star.x = randomRange(-xRange, xRange);
star.y = randomRange(-yRange, yRange);
float nx = star.x / std::max(xRange, 0.0001f);
float ny = star.y / std::max(yRange, 0.0001f);
axisOk = (nx * nx + ny * ny) >= (axisMinFrac * axisMinFrac);
}
if (!axisOk) {
float ang = randomRange(0.0f, 6.28318530718f);
star.x = std::cos(ang) * xRange * axisMinFrac;
star.y = std::sin(ang) * yRange * axisMinFrac;
}
// Keep z slightly above minDepth so projection never starts from the exact singular plane.
star.z = randomDepth ? randomRange(minDepth + 0.25f, maxDepth) : maxDepth;
star.speed = randomRange(settings.minSpeed, settings.maxSpeed);
star.shade = randomRange(settings.minShade, settings.maxShade);
static constexpr Uint8 GRAY_SHADES[] = {160, 180, 200, 220, 240};
@ -253,6 +282,13 @@ void SpaceWarp::update(float deltaSeconds) {
continue;
}
// If a star projects to (near) the visual center, it can appear perfectly static
// during straight-line flight. Replace it to avoid the "big static star" artifact.
if (std::abs(sx - centerX) < 1.25f && std::abs(sy - centerY) < 1.25f) {
respawn(star, true);
continue;
}
star.prevScreenX = star.screenX;
star.prevScreenY = star.screenY;
star.screenX = sx;

View File

@ -68,9 +68,24 @@ void Starfield3D::setRandomDirection(Star3D& star) {
void Starfield3D::updateStar(int index) {
Star3D& star = stars[index];
star.x = randomFloat(-25.0f, 25.0f);
star.y = randomFloat(-25.0f, 25.0f);
// Avoid spawning stars on (or very near) the view axis. A star with x≈0 and y≈0
// projects to the exact center, and when it happens to be bright it looks like a
// static "big" star.
constexpr float SPAWN_RANGE = 25.0f;
constexpr float MIN_AXIS_RADIUS = 2.5f; // in star-space units
for (int attempt = 0; attempt < 8; ++attempt) {
star.x = randomFloat(-SPAWN_RANGE, SPAWN_RANGE);
star.y = randomFloat(-SPAWN_RANGE, SPAWN_RANGE);
if ((star.x * star.x + star.y * star.y) >= (MIN_AXIS_RADIUS * MIN_AXIS_RADIUS)) {
break;
}
}
// If we somehow still ended up too close, push it out deterministically.
if ((star.x * star.x + star.y * star.y) < (MIN_AXIS_RADIUS * MIN_AXIS_RADIUS)) {
star.x = (star.x < 0.0f ? -1.0f : 1.0f) * MIN_AXIS_RADIUS;
star.y = (star.y < 0.0f ? -1.0f : 1.0f) * MIN_AXIS_RADIUS;
}
star.z = randomFloat(1.0f, MAX_DEPTH);
// Give stars initial velocities in all possible directions
@ -91,6 +106,15 @@ void Starfield3D::updateStar(int index) {
star.vz = -STAR_SPEED * randomFloat(0.8f, 1.2f);
}
}
// Ensure newly spawned stars have some lateral drift so they don't appear to
// "stick" near the center line.
if (std::abs(star.vx) < 0.02f && std::abs(star.vy) < 0.02f) {
const float sx = (star.x < 0.0f ? -1.0f : 1.0f);
const float sy = (star.y < 0.0f ? -1.0f : 1.0f);
star.vx = sx * randomFloat(0.04f, 0.14f);
star.vy = sy * randomFloat(0.04f, 0.14f);
}
star.targetVx = star.vx;
star.targetVy = star.vy;