From ace2e6acdce6ec5f3a6034b8ee64efdb6102a199 Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Sun, 30 Nov 2025 16:30:47 +0100 Subject: [PATCH] updated stars in game play grid --- src/graphics/effects/Starfield3D.cpp | 31 +++++++++++++++++++++-- src/graphics/effects/Starfield3D.h | 6 +++++ src/graphics/renderers/GameRenderer.cpp | 33 +++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/graphics/effects/Starfield3D.cpp b/src/graphics/effects/Starfield3D.cpp index fa038c4..f452e2d 100644 --- a/src/graphics/effects/Starfield3D.cpp +++ b/src/graphics/effects/Starfield3D.cpp @@ -23,6 +23,22 @@ void Starfield3D::resize(int w, int h) { centerY = height * 0.5f; } +void Starfield3D::setMagnetTarget(float localX, float localY, float strength) { + if (strength <= 0.0f) { + clearMagnetTarget(); + return; + } + magnetActive = true; + magnetStrength = strength; + magnetX = std::clamp(localX, 0.0f, static_cast(width)); + magnetY = std::clamp(localY, 0.0f, static_cast(height)); +} + +void Starfield3D::clearMagnetTarget() { + magnetActive = false; + magnetStrength = 0.0f; +} + float Starfield3D::randomFloat(float min, float max) { std::uniform_real_distribution dist(min, max); return dist(rng); @@ -147,13 +163,24 @@ void Starfield3D::drawStar(SDL_Renderer* renderer, float x, float y, SDL_Color c } void Starfield3D::draw(SDL_Renderer* renderer, float offsetX, float offsetY, float alphaScale, bool grayscale) { + const bool useMagnet = magnetActive && magnetStrength > 0.0f; for (const Star3D& star : stars) { // Calculate perspective projection factor const float k = DEPTH_FACTOR / star.z; // Calculate screen position with perspective - const float px = star.x * k + centerX; - const float py = star.y * k + centerY; + float px = star.x * k + centerX; + float py = star.y * k + centerY; + + if (useMagnet) { + float dx = magnetX - px; + float dy = magnetY - py; + float dist = std::sqrt(dx * dx + dy * dy); + float pull = magnetStrength / (magnetStrength + dist + 1.0f); + pull = std::clamp(pull, 0.0f, 0.35f); + px += dx * pull; + py += dy * pull; + } // Only draw stars that are within the viewport if (px >= 0.0f && px <= static_cast(width) && diff --git a/src/graphics/effects/Starfield3D.h b/src/graphics/effects/Starfield3D.h index 3e03189..40c76dc 100644 --- a/src/graphics/effects/Starfield3D.h +++ b/src/graphics/effects/Starfield3D.h @@ -15,6 +15,8 @@ public: 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); + void setMagnetTarget(float localX, float localY, float strength); + void clearMagnetTarget(); private: struct Star3D { @@ -37,6 +39,10 @@ private: std::vector stars; int width{0}, height{0}; float centerX{0}, centerY{0}; + bool magnetActive{false}; + float magnetX{0.0f}; + float magnetY{0.0f}; + float magnetStrength{0.0f}; // Random number generator std::mt19937 rng; diff --git a/src/graphics/renderers/GameRenderer.cpp b/src/graphics/renderers/GameRenderer.cpp index 6fb9fb5..8ef3cb1 100644 --- a/src/graphics/renderers/GameRenderer.cpp +++ b/src/graphics/renderers/GameRenderer.cpp @@ -265,6 +265,39 @@ void GameRenderer::renderPlayingState( const float deltaSeconds = std::clamp(static_cast(sparkDeltaMs) / 1000.0f, 0.0f, 0.033f); s_inGridStarfield.update(deltaSeconds); + bool appliedMagnet = false; + if (game) { + const Game::Piece& activePiece = game->current(); + const int pieceType = static_cast(activePiece.type); + if (pieceType >= 0 && pieceType < PIECE_COUNT) { + float sumLocalX = 0.0f; + float sumLocalY = 0.0f; + int filledCells = 0; + for (int cy = 0; cy < 4; ++cy) { + for (int cx = 0; cx < 4; ++cx) { + if (!Game::cellFilled(activePiece, cx, cy)) { + continue; + } + sumLocalX += (activePiece.x + cx + 0.5f) * finalBlockSize; + sumLocalY += (activePiece.y + cy + 0.5f) * finalBlockSize; + ++filledCells; + } + } + if (filledCells > 0) { + float magnetLocalX = sumLocalX / static_cast(filledCells); + float magnetLocalY = sumLocalY / static_cast(filledCells); + magnetLocalX = std::clamp(magnetLocalX, 0.0f, GRID_W); + magnetLocalY = std::clamp(magnetLocalY, 0.0f, GRID_H); + const float magnetStrength = finalBlockSize * 2.2f; + s_inGridStarfield.setMagnetTarget(magnetLocalX, magnetLocalY, magnetStrength); + appliedMagnet = true; + } + } + } + if (!appliedMagnet) { + s_inGridStarfield.clearMagnetTarget(); + } + SDL_BlendMode oldBlend = SDL_BLENDMODE_NONE; SDL_GetRenderDrawBlendMode(renderer, &oldBlend); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);