new background image
This commit is contained in:
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user