added clear line effect

This commit is contained in:
2025-12-21 16:25:09 +01:00
parent 4efb60bb5b
commit cf3e897752
3 changed files with 34 additions and 7 deletions

View File

@ -1926,12 +1926,18 @@ void GameRenderer::renderCoopPlayingState(
// Handle line clearing effects (defer to LineEffect like single-player)
if (game->hasCompletedLines() && lineEffect && !lineEffect->isActive()) {
auto completedLines = game->getCompletedLines();
lineEffect->startLineClear(completedLines, static_cast<int>(gridX), static_cast<int>(gridY), static_cast<int>(finalBlockSize));
lineEffect->startLineClear(completedLines, static_cast<int>(gridX), static_cast<int>(gridY), static_cast<int>(finalBlockSize), CoopGame::COLS);
if (completedLines.size() == 4) {
AppFireworks::spawn(gridX + GRID_W * 0.5f, gridY + GRID_H * 0.5f);
}
}
// Precompute row drop offsets (line collapse effect)
std::array<float, CoopGame::ROWS> rowDropOffsets{};
for (int y = 0; y < CoopGame::ROWS; ++y) {
rowDropOffsets[y] = (lineEffect ? lineEffect->getRowDropOffset(y) : 0.0f);
}
// Grid backdrop and border
drawRectWithOffset(gridX - 3 - contentOffsetX, gridY - 3 - contentOffsetY, GRID_W + 6, GRID_H + 6, {100, 120, 200, 255});
drawRectWithOffset(gridX - contentOffsetX, gridY - contentOffsetY, GRID_W, GRID_H, {20, 25, 35, 255});
@ -1980,11 +1986,12 @@ void GameRenderer::renderCoopPlayingState(
// Draw settled blocks
const auto& board = game->boardRef();
for (int y = 0; y < CoopGame::ROWS; ++y) {
float dropOffset = rowDropOffsets[y];
for (int x = 0; x < CoopGame::COLS; ++x) {
const auto& cell = board[y * CoopGame::COLS + x];
if (!cell.occupied || cell.value <= 0) continue;
float px = gridX + x * finalBlockSize;
float py = gridY + y * finalBlockSize;
float py = gridY + y * finalBlockSize + dropOffset;
drawBlockTexturePublic(renderer, blocksTex, px, py, finalBlockSize, cell.value - 1);
}
}
@ -2012,7 +2019,20 @@ void GameRenderer::renderCoopPlayingState(
sf.tileSize = finalBlockSize;
// Target to first visible row (row 0)
sf.targetX = gridX + static_cast<float>(sf.piece.x) * finalBlockSize;
sf.targetY = gridY + 0.0f * finalBlockSize;
// IMPORTANT: In classic mode, pieces can spawn with their first filled
// cell not at cy=0 within the 4x4. To avoid appearing one row too low
// (and then jumping up), align the topmost filled cell to row 0.
int minCy = 4;
for (int cy = 0; cy < 4; ++cy) {
for (int cx = 0; cx < 4; ++cx) {
if (!CoopGame::cellFilled(sf.piece, cx, cy)) continue;
minCy = std::min(minCy, cy);
}
}
if (minCy == 4) {
minCy = 0;
}
sf.targetY = gridY - static_cast<float>(minCy) * finalBlockSize;
} else {
// Reuse exact horizontal smoothing from single-player
constexpr float HORIZONTAL_SMOOTH_MS = 55.0f;
@ -2177,6 +2197,11 @@ void GameRenderer::renderCoopPlayingState(
drawPiece(game->current(CoopGame::PlayerSide::Right), rightOffsets, false);
}
// Draw line clearing effects above pieces (matches single-player)
if (lineEffect && lineEffect->isActive()) {
lineEffect->render(renderer, blocksTex, static_cast<int>(gridX), static_cast<int>(gridY), static_cast<int>(finalBlockSize));
}
// Next panels (two)
const float nextPanelPad = 12.0f;
const float nextPanelW = (GRID_W * 0.5f) - finalBlockSize * 1.5f;