fixed gameplay

This commit is contained in:
2025-12-20 15:17:35 +01:00
parent 9a3c1a0688
commit ad014e1de0
10 changed files with 176 additions and 25 deletions

View File

@ -581,7 +581,11 @@ void GameRenderer::renderPlayingState(
float logicalH,
float logicalScale,
float winW,
float winH
float winH,
bool challengeClearFxActive,
const std::vector<int>* challengeClearFxOrder,
double challengeClearFxElapsedMs,
double challengeClearFxDurationMs
) {
if (!game || !pixelFont) return;
@ -997,6 +1001,25 @@ void GameRenderer::renderPlayingState(
}
}
std::array<float, Game::COLS * Game::ROWS> challengeClearMask{};
const bool challengeClearActive = challengeClearFxActive && challengeClearFxOrder && !challengeClearFxOrder->empty() && challengeClearFxDurationMs > 0.0;
if (challengeClearActive) {
const double totalDuration = std::max(50.0, challengeClearFxDurationMs);
const double perCell = totalDuration / static_cast<double>(challengeClearFxOrder->size());
for (size_t i = 0; i < challengeClearFxOrder->size(); ++i) {
int idx = (*challengeClearFxOrder)[i];
if (idx < 0 || idx >= static_cast<int>(challengeClearMask.size())) {
continue;
}
double startMs = perCell * static_cast<double>(i);
double local = (challengeClearFxElapsedMs - startMs) / perCell;
float progress = static_cast<float>(std::clamp(local, 0.0, 1.0));
if (progress > 0.0f) {
challengeClearMask[idx] = progress;
}
}
}
for (int y = 0; y < Game::ROWS; ++y) {
float dropOffset = rowDropOffsets[y];
for (int x = 0; x < Game::COLS; ++x) {
@ -1015,6 +1038,21 @@ void GameRenderer::renderPlayingState(
by += amplitude * 0.75f * std::cos(t * (freq + 1.1f));
}
float clearProgress = challengeClearMask[cellIdx];
float clearAlpha = 1.0f;
float clearScale = 1.0f;
if (clearProgress > 0.0f) {
float eased = smoothstep(clearProgress);
clearAlpha = std::max(0.0f, 1.0f - eased);
clearScale = 1.0f + 0.35f * eased;
float offset = (finalBlockSize - finalBlockSize * clearScale) * 0.5f;
bx += offset;
by += offset;
float jitter = eased * 2.0f;
bx += std::sin(static_cast<float>(cellIdx) * 3.1f) * jitter;
by += std::cos(static_cast<float>(cellIdx) * 2.3f) * jitter * 0.6f;
}
bool isAsteroid = challengeMode && asteroidCells[cellIdx].has_value();
if (isAsteroid) {
const AsteroidCell& cell = *asteroidCells[cellIdx];
@ -1034,15 +1072,25 @@ void GameRenderer::renderPlayingState(
SDL_SetTextureAlphaMod(asteroidsTex, static_cast<Uint8>(std::clamp(spawnAlpha, 0.0f, 1.0f) * 255.0f));
}
float size = finalBlockSize * spawnScale;
float size = finalBlockSize * spawnScale * clearScale;
float offset = (finalBlockSize - size) * 0.5f;
if (asteroidsTex && clearAlpha < 1.0f) {
Uint8 alpha = static_cast<Uint8>(std::clamp(spawnAlpha * clearAlpha, 0.0f, 1.0f) * 255.0f);
SDL_SetTextureAlphaMod(asteroidsTex, alpha);
}
drawAsteroid(renderer, asteroidsTex, bx + offset, by + offset, size, cell);
if (asteroidsTex && spawnAlpha < 1.0f) {
if (asteroidsTex && (spawnAlpha < 1.0f || clearAlpha < 1.0f)) {
SDL_SetTextureAlphaMod(asteroidsTex, 255);
}
} else {
drawBlockTexture(renderer, blocksTex, bx, by, finalBlockSize, v - 1);
if (blocksTex && clearAlpha < 1.0f) {
SDL_SetTextureAlphaMod(blocksTex, static_cast<Uint8>(std::clamp(clearAlpha, 0.0f, 1.0f) * 255.0f));
}
drawBlockTexture(renderer, blocksTex, bx, by, finalBlockSize * clearScale, v - 1);
if (blocksTex && clearAlpha < 1.0f) {
SDL_SetTextureAlphaMod(blocksTex, 255);
}
}
}
}
@ -1075,7 +1123,7 @@ void GameRenderer::renderPlayingState(
}
}
bool allowActivePieceRender = !GameRenderer::isTransportActive();
bool allowActivePieceRender = !GameRenderer::isTransportActive() && !challengeClearActive;
const bool smoothScrollEnabled = Settings::instance().isSmoothScrollEnabled();
float activePiecePixelOffsetX = 0.0f;

View File

@ -1,5 +1,6 @@
#pragma once
#include <SDL3/SDL.h>
#include <vector>
#include "../../gameplay/core/Game.h"
// Forward declarations
@ -31,7 +32,11 @@ public:
float logicalH,
float logicalScale,
float winW,
float winH
float winH,
bool challengeClearFxActive = false,
const std::vector<int>* challengeClearFxOrder = nullptr,
double challengeClearFxElapsedMs = 0.0,
double challengeClearFxDurationMs = 0.0
);
// Render the pause overlay (full screen)