added ghost block
This commit is contained in:
@ -2106,7 +2106,7 @@ void GameRenderer::renderCoopPlayingState(
|
||||
if (t >= 1.0f) sf.active = false;
|
||||
};
|
||||
|
||||
auto drawPiece = [&](const CoopGame::Piece& p, CoopGame::PlayerSide side, const std::pair<float,float>& offsets) {
|
||||
auto drawPiece = [&](const CoopGame::Piece& p, const std::pair<float, float>& offsets, bool isGhost) {
|
||||
for (int cy = 0; cy < 4; ++cy) {
|
||||
for (int cx = 0; cx < 4; ++cx) {
|
||||
if (!CoopGame::cellFilled(p, cx, cy)) continue;
|
||||
@ -2115,7 +2115,17 @@ void GameRenderer::renderCoopPlayingState(
|
||||
if (pyIdx < 0) continue; // don't draw parts above the visible grid
|
||||
float px = gridX + (float)pxIdx * finalBlockSize + offsets.first;
|
||||
float py = gridY + (float)pyIdx * finalBlockSize + offsets.second;
|
||||
drawBlockTexturePublic(renderer, blocksTex, px, py, finalBlockSize, p.type);
|
||||
if (isGhost) {
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 180, 180, 180, 20);
|
||||
SDL_FRect rect = {px + 2.0f, py + 2.0f, finalBlockSize - 4.0f, finalBlockSize - 4.0f};
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
SDL_SetRenderDrawColor(renderer, 180, 180, 180, 30);
|
||||
SDL_FRect border = {px + 1.0f, py + 1.0f, finalBlockSize - 2.0f, finalBlockSize - 2.0f};
|
||||
SDL_RenderRect(renderer, &border);
|
||||
} else {
|
||||
drawBlockTexturePublic(renderer, blocksTex, px, py, finalBlockSize, p.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -2125,14 +2135,46 @@ void GameRenderer::renderCoopPlayingState(
|
||||
drawSpawnFadeIfActive(s_leftSpawnFade);
|
||||
drawSpawnFadeIfActive(s_rightSpawnFade);
|
||||
|
||||
// Draw classic-style ghost pieces (landing position), grid-aligned.
|
||||
// This intentionally does NOT use smoothing offsets.
|
||||
auto computeGhostPiece = [&](CoopGame::PlayerSide side) {
|
||||
CoopGame::Piece ghostPiece = game->current(side);
|
||||
const auto& boardRef = game->boardRef();
|
||||
while (true) {
|
||||
CoopGame::Piece testPiece = ghostPiece;
|
||||
testPiece.y++;
|
||||
bool collision = false;
|
||||
for (int cy = 0; cy < 4; ++cy) {
|
||||
for (int cx = 0; cx < 4; ++cx) {
|
||||
if (!CoopGame::cellFilled(testPiece, cx, cy)) continue;
|
||||
int gx = testPiece.x + cx;
|
||||
int gy = testPiece.y + cy;
|
||||
if (gy >= CoopGame::ROWS || gx < 0 || gx >= CoopGame::COLS ||
|
||||
(gy >= 0 && boardRef[gy * CoopGame::COLS + gx].occupied)) {
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (collision) break;
|
||||
}
|
||||
if (collision) break;
|
||||
ghostPiece = testPiece;
|
||||
}
|
||||
return ghostPiece;
|
||||
};
|
||||
|
||||
const std::pair<float, float> ghostOffsets{0.0f, 0.0f};
|
||||
drawPiece(computeGhostPiece(CoopGame::PlayerSide::Left), ghostOffsets, true);
|
||||
drawPiece(computeGhostPiece(CoopGame::PlayerSide::Right), ghostOffsets, true);
|
||||
|
||||
// If a spawn fade is active for a side and matches the current piece
|
||||
// sequence, only draw the fade visual and skip the regular piece draw
|
||||
// to avoid a double-draw that appears as a jump when falling starts.
|
||||
if (!(s_leftSpawnFade.active && s_leftSpawnFade.seq == game->currentPieceSequence(CoopGame::PlayerSide::Left))) {
|
||||
drawPiece(game->current(CoopGame::PlayerSide::Left), CoopGame::PlayerSide::Left, leftOffsets);
|
||||
drawPiece(game->current(CoopGame::PlayerSide::Left), leftOffsets, false);
|
||||
}
|
||||
if (!(s_rightSpawnFade.active && s_rightSpawnFade.seq == game->currentPieceSequence(CoopGame::PlayerSide::Right))) {
|
||||
drawPiece(game->current(CoopGame::PlayerSide::Right), CoopGame::PlayerSide::Right, rightOffsets);
|
||||
drawPiece(game->current(CoopGame::PlayerSide::Right), rightOffsets, false);
|
||||
}
|
||||
|
||||
// Next panels (two)
|
||||
|
||||
Reference in New Issue
Block a user