diff --git a/assets/images/asteroids_001.png b/assets/images/asteroids_001.png index 9a932e2..3a185f9 100644 Binary files a/assets/images/asteroids_001.png and b/assets/images/asteroids_001.png differ diff --git a/src/app/TetrisApp.cpp b/src/app/TetrisApp.cpp index a82ac30..aacaebb 100644 --- a/src/app/TetrisApp.cpp +++ b/src/app/TetrisApp.cpp @@ -1576,6 +1576,7 @@ void TetrisApp::Impl::runLoop() scorePanelTex, nextPanelTex, holdPanelTex, + false, (float)LOGICAL_W, (float)LOGICAL_H, logicalScale, diff --git a/src/core/application/ApplicationManager.cpp b/src/core/application/ApplicationManager.cpp index fe68192..194b87b 100644 --- a/src/core/application/ApplicationManager.cpp +++ b/src/core/application/ApplicationManager.cpp @@ -1168,6 +1168,7 @@ void ApplicationManager::setupStateHandlers() { m_stateContext.scorePanelTex, m_stateContext.nextPanelTex, m_stateContext.holdPanelTex, + false, LOGICAL_W, LOGICAL_H, logicalScale, diff --git a/src/graphics/renderers/GameRenderer.cpp b/src/graphics/renderers/GameRenderer.cpp index 8799191..5a27baf 100644 --- a/src/graphics/renderers/GameRenderer.cpp +++ b/src/graphics/renderers/GameRenderer.cpp @@ -576,6 +576,7 @@ void GameRenderer::renderPlayingState( SDL_Texture* scorePanelTex, SDL_Texture* nextPanelTex, SDL_Texture* holdPanelTex, + bool countdownActive, float logicalW, float logicalH, float logicalScale, @@ -1017,7 +1018,29 @@ void GameRenderer::renderPlayingState( bool isAsteroid = challengeMode && asteroidCells[cellIdx].has_value(); if (isAsteroid) { const AsteroidCell& cell = *asteroidCells[cellIdx]; - drawAsteroid(renderer, asteroidsTex, bx, by, finalBlockSize, cell); + float spawnScale = 1.0f; + float spawnAlpha = 1.0f; + if (countdownActive) { + // Staggered pop-in while counting: start oversized, fade to 1.0 with ease + const float t = static_cast(SDL_GetTicks() & 2047) * 0.0015f; // ~0..3s loop + float phase = std::fmod(t + (float(cellIdx % 11) * 0.12f), 1.6f); + float pulse = std::clamp(phase / 1.2f, 0.0f, 1.0f); + float eased = smoothstep(pulse); + spawnScale = 1.35f - 0.35f * eased; // big -> normal + spawnAlpha = 0.25f + 0.75f * eased; // fade in + } + + if (asteroidsTex && spawnAlpha < 1.0f) { + SDL_SetTextureAlphaMod(asteroidsTex, static_cast(std::clamp(spawnAlpha, 0.0f, 1.0f) * 255.0f)); + } + + float size = finalBlockSize * spawnScale; + float offset = (finalBlockSize - size) * 0.5f; + drawAsteroid(renderer, asteroidsTex, bx + offset, by + offset, size, cell); + + if (asteroidsTex && spawnAlpha < 1.0f) { + SDL_SetTextureAlphaMod(asteroidsTex, 255); + } } else { drawBlockTexture(renderer, blocksTex, bx, by, finalBlockSize, v - 1); } diff --git a/src/graphics/renderers/GameRenderer.h b/src/graphics/renderers/GameRenderer.h index 39e6a45..4f77b29 100644 --- a/src/graphics/renderers/GameRenderer.h +++ b/src/graphics/renderers/GameRenderer.h @@ -26,6 +26,7 @@ public: SDL_Texture* scorePanelTex, SDL_Texture* nextPanelTex, SDL_Texture* holdPanelTex, + bool countdownActive, float logicalW, float logicalH, float logicalScale, diff --git a/src/states/PlayingState.cpp b/src/states/PlayingState.cpp index 1ff9162..a9bbe14 100644 --- a/src/states/PlayingState.cpp +++ b/src/states/PlayingState.cpp @@ -122,6 +122,16 @@ void PlayingState::handleEvent(const SDL_Event& e) { return; } + // Debug: skip to next challenge level (B) + if (e.key.scancode == SDL_SCANCODE_B && ctx.game && ctx.game->getMode() == GameMode::Challenge) { + ctx.game->beginNextChallengeLevel(); + // Cancel any countdown so play resumes immediately on the new level + if (ctx.gameplayCountdownActive) *ctx.gameplayCountdownActive = false; + if (ctx.menuPlayCountdownArmed) *ctx.menuPlayCountdownArmed = false; + ctx.game->setPaused(false); + return; + } + // Tetris controls (only when not paused) if (!ctx.game->isPaused()) { // Hold / swap current piece (H) @@ -246,6 +256,7 @@ void PlayingState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect l ctx.scorePanelTex, ctx.nextPanelTex, ctx.holdPanelTex, + countdown, 1200.0f, // LOGICAL_W 1000.0f, // LOGICAL_H logicalScale, @@ -335,6 +346,7 @@ void PlayingState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect l ctx.scorePanelTex, ctx.nextPanelTex, ctx.holdPanelTex, + countdown, 1200.0f, 1000.0f, logicalScale,