From ab22d4c34fd6bfa4dfcfb3640f6ec3b05f2cda2c Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Sun, 21 Dec 2025 17:04:46 +0100 Subject: [PATCH] hard drop shake effect added --- src/graphics/renderers/GameRenderer.cpp | 45 +++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/graphics/renderers/GameRenderer.cpp b/src/graphics/renderers/GameRenderer.cpp index 3b55de9..20e6cad 100644 --- a/src/graphics/renderers/GameRenderer.cpp +++ b/src/graphics/renderers/GameRenderer.cpp @@ -1983,6 +1983,39 @@ void GameRenderer::renderCoopPlayingState( } SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + // Hard-drop impact shake (match classic feel) + float impactStrength = 0.0f; + float impactEased = 0.0f; + std::array impactMask{}; + std::array impactWeight{}; + if (game->hasHardDropShake()) { + impactStrength = static_cast(game->hardDropShakeStrength()); + impactStrength = std::clamp(impactStrength, 0.0f, 1.0f); + impactEased = impactStrength * impactStrength; + const auto& impactCells = game->getHardDropCells(); + const auto& boardRef = game->boardRef(); + for (const auto& cell : impactCells) { + if (cell.x < 0 || cell.x >= CoopGame::COLS || cell.y < 0 || cell.y >= CoopGame::ROWS) { + continue; + } + int idx = cell.y * CoopGame::COLS + cell.x; + impactMask[idx] = 1; + impactWeight[idx] = 1.0f; + + int depth = 0; + for (int ny = cell.y + 1; ny < CoopGame::ROWS && depth < 4; ++ny) { + if (!boardRef[ny * CoopGame::COLS + cell.x].occupied) { + break; + } + ++depth; + int nidx = ny * CoopGame::COLS + cell.x; + impactMask[nidx] = 1; + float weight = std::max(0.15f, 1.0f - depth * 0.35f); + impactWeight[nidx] = std::max(impactWeight[nidx], weight); + } + } + } + // Draw settled blocks const auto& board = game->boardRef(); for (int y = 0; y < CoopGame::ROWS; ++y) { @@ -1992,6 +2025,18 @@ void GameRenderer::renderCoopPlayingState( if (!cell.occupied || cell.value <= 0) continue; float px = gridX + x * finalBlockSize; float py = gridY + y * finalBlockSize + dropOffset; + + const int cellIdx = y * CoopGame::COLS + x; + float weight = impactWeight[cellIdx]; + if (impactStrength > 0.0f && weight > 0.0f && impactMask[cellIdx]) { + float cellSeed = static_cast((x * 37 + y * 61) % 113); + float t = static_cast(nowTicks % 10000) * 0.018f + cellSeed; + float amplitude = 6.0f * impactEased * weight; + float freq = 2.0f + weight * 1.3f; + px += amplitude * std::sin(t * freq); + py += amplitude * 0.75f * std::cos(t * (freq + 1.1f)); + } + drawBlockTexturePublic(renderer, blocksTex, px, py, finalBlockSize, cell.value - 1); } }