fix sidebar statistics
This commit is contained in:
@ -152,13 +152,13 @@ void GameRenderer::renderPlayingState(
|
||||
const float NEXT_PIECE_HEIGHT = 120.0f;
|
||||
const float BOTTOM_MARGIN = 60.0f;
|
||||
|
||||
// Calculate layout dimensions
|
||||
float yCursor = statsY + 44.0f;
|
||||
const float availableWidth = logicalW - (MIN_MARGIN * 2) - (PANEL_WIDTH * 2) - (PANEL_SPACING * 2);
|
||||
const float availableHeight = logicalH - TOP_MARGIN - BOTTOM_MARGIN - NEXT_PIECE_HEIGHT;
|
||||
|
||||
const float maxBlockSizeW = availableWidth / Game::COLS;
|
||||
const float maxBlockSizeH = availableHeight / Game::ROWS;
|
||||
const float BLOCK_SIZE = std::min(maxBlockSizeW, maxBlockSizeH);
|
||||
float previewY = rowTop - 4.0f;
|
||||
const float finalBlockSize = std::max(20.0f, std::min(BLOCK_SIZE, 40.0f));
|
||||
|
||||
const float GRID_W = Game::COLS * finalBlockSize;
|
||||
@ -172,17 +172,17 @@ void GameRenderer::renderPlayingState(
|
||||
|
||||
const float totalLayoutWidth = PANEL_WIDTH + PANEL_SPACING + GRID_W + PANEL_SPACING + PANEL_WIDTH;
|
||||
const float layoutStartX = (logicalW - totalLayoutWidth) * 0.5f;
|
||||
|
||||
float barY = previewY + previewSize + 10.0f;
|
||||
const float statsX = layoutStartX + contentOffsetX;
|
||||
const float gridX = layoutStartX + PANEL_WIDTH + PANEL_SPACING + contentOffsetX;
|
||||
const float scoreX = layoutStartX + PANEL_WIDTH + PANEL_SPACING + GRID_W + PANEL_SPACING + contentOffsetX;
|
||||
const float gridY = contentStartY + NEXT_PIECE_HEIGHT + contentOffsetY;
|
||||
|
||||
const float statsY = gridY;
|
||||
const float statsW = PANEL_WIDTH;
|
||||
const float statsH = GRID_H;
|
||||
|
||||
// Next piece preview position
|
||||
float rowBottom = percY + 14.0f;
|
||||
SDL_FRect rowBg{
|
||||
previewX - 10.0f,
|
||||
rowTop - 8.0f,
|
||||
rowWidth + 20.0f,
|
||||
rowBottom - rowTop
|
||||
};
|
||||
const float nextW = finalBlockSize * 4 + 20;
|
||||
const float nextH = finalBlockSize * 2 + 20;
|
||||
const float nextX = gridX + (GRID_W - nextW) * 0.5f;
|
||||
@ -283,7 +283,7 @@ void GameRenderer::renderPlayingState(
|
||||
if (lineEffect && lineEffect->isActive()) {
|
||||
lineEffect->render(renderer, static_cast<int>(gridX), static_cast<int>(gridY), static_cast<int>(finalBlockSize));
|
||||
}
|
||||
|
||||
float yCursor = statsY + 44.0f;
|
||||
// Draw next piece preview
|
||||
pixelFont->draw(renderer, nextX + 10, nextY - 20, "NEXT", 1.0f, {255, 220, 0, 255});
|
||||
if (game->next().type < PIECE_COUNT) {
|
||||
@ -294,66 +294,82 @@ void GameRenderer::renderPlayingState(
|
||||
pixelFont->draw(renderer, statsX + 10, statsY + 10, "BLOCKS", 1.0f, {255, 220, 0, 255});
|
||||
|
||||
const auto& blockCounts = game->getBlockCounts();
|
||||
int totalBlocks = 0;
|
||||
float previewY = rowTop - 4.0f;
|
||||
for (int i = 0; i < PIECE_COUNT; ++i) totalBlocks += blockCounts[i];
|
||||
|
||||
const char* pieceNames[] = {"I", "O", "T", "S", "Z", "J", "L"};
|
||||
float yCursor = statsY + 52;
|
||||
const float rowPadding = 18.0f;
|
||||
const float rowWidth = statsW - rowPadding * 2.0f;
|
||||
const float rowSpacing = 12.0f;
|
||||
float yCursor = statsY + 44.0f;
|
||||
|
||||
for (int i = 0; i < PIECE_COUNT; ++i) {
|
||||
float py = yCursor;
|
||||
float rowTop = yCursor;
|
||||
float previewSize = finalBlockSize * 0.52f;
|
||||
float previewX = statsX + rowPadding;
|
||||
float previewY = rowTop - 14.0f;
|
||||
|
||||
// Draw small piece icon
|
||||
float previewSize = finalBlockSize * 0.55f;
|
||||
drawSmallPiece(renderer, blocksTex, static_cast<PieceType>(i), statsX + 18, py, previewSize);
|
||||
|
||||
// Compute preview height
|
||||
// Determine actual piece height so bars never overlap blocks
|
||||
Game::Piece previewPiece{};
|
||||
previewPiece.type = static_cast<PieceType>(i);
|
||||
previewPiece.rot = 0;
|
||||
previewPiece.x = 0;
|
||||
previewPiece.y = 0;
|
||||
int maxCy = -1;
|
||||
Game::Piece prev;
|
||||
prev.type = static_cast<PieceType>(i);
|
||||
prev.rot = 0;
|
||||
prev.x = 0;
|
||||
prev.y = 0;
|
||||
for (int cy = 0; cy < 4; ++cy) {
|
||||
for (int cx = 0; cx < 4; ++cx) {
|
||||
if (Game::cellFilled(prev, cx, cy)) maxCy = std::max(maxCy, cy);
|
||||
if (Game::cellFilled(previewPiece, cx, cy)) {
|
||||
maxCy = std::max(maxCy, cy);
|
||||
}
|
||||
}
|
||||
int tilesHigh = (maxCy >= 0 ? maxCy + 1 : 1);
|
||||
float previewHeight = tilesHigh * previewSize;
|
||||
}
|
||||
float pieceHeight = (maxCy >= 0 ? maxCy + 1.0f : 1.0f) * previewSize;
|
||||
|
||||
// Count display
|
||||
int count = blockCounts[i];
|
||||
char countStr[16];
|
||||
snprintf(countStr, sizeof(countStr), "%d", count);
|
||||
pixelFont->draw(renderer, statsX + statsW - 20, py + 6, countStr, 1.1f, {240, 240, 245, 255});
|
||||
int countW = 0, countH = 0;
|
||||
pixelFont->measure(countStr, 1.0f, countW, countH);
|
||||
float countX = previewX + rowWidth - static_cast<float>(countW);
|
||||
float countY = previewY + 9.0f;
|
||||
|
||||
// Percentage bar
|
||||
int perc = (totalBlocks > 0) ? int(std::round(100.0 * double(count) / double(totalBlocks))) : 0;
|
||||
char percStr[16];
|
||||
snprintf(percStr, sizeof(percStr), "%d%%", perc);
|
||||
|
||||
float barX = statsX + 12;
|
||||
float barY = py + previewHeight + 18.0f;
|
||||
float barW = statsW - 24;
|
||||
float barH = 6;
|
||||
float barX = previewX;
|
||||
float barY = previewY + pieceHeight + 12.0f;
|
||||
float barH = 6.0f;
|
||||
float barW = rowWidth;
|
||||
float percY = barY + barH + 8.0f;
|
||||
float fillW = barW * (perc / 100.0f);
|
||||
fillW = std::clamp(fillW, 0.0f, barW);
|
||||
|
||||
pixelFont->draw(renderer, barX, barY - 16, percStr, 0.8f, {230, 230, 235, 255});
|
||||
float cardTop = rowTop - 14.0f;
|
||||
float rowBottom = percY + 16.0f;
|
||||
SDL_FRect rowBg{
|
||||
previewX - 12.0f,
|
||||
cardTop,
|
||||
rowWidth + 24.0f,
|
||||
rowBottom - cardTop
|
||||
};
|
||||
SDL_SetRenderDrawColor(renderer, 18, 26, 40, 200);
|
||||
SDL_RenderFillRect(renderer, &rowBg);
|
||||
SDL_SetRenderDrawColor(renderer, 70, 100, 150, 210);
|
||||
SDL_RenderRect(renderer, &rowBg);
|
||||
|
||||
// Progress bar
|
||||
SDL_SetRenderDrawColor(renderer, 170, 170, 175, 200);
|
||||
drawSmallPiece(renderer, blocksTex, static_cast<PieceType>(i), previewX, previewY, previewSize);
|
||||
pixelFont->draw(renderer, countX, countY, countStr, 1.0f, {245, 245, 255, 255});
|
||||
pixelFont->draw(renderer, previewX, percY, percStr, 0.8f, {215, 225, 240, 255});
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 110, 120, 140, 200);
|
||||
SDL_FRect track{barX, barY, barW, barH};
|
||||
SDL_RenderFillRect(renderer, &track);
|
||||
|
||||
SDL_Color pc = COLORS[i + 1];
|
||||
SDL_SetRenderDrawColor(renderer, pc.r, pc.g, pc.b, 230);
|
||||
float fillW = barW * (perc / 100.0f);
|
||||
if (fillW < 0) fillW = 0;
|
||||
if (fillW > barW) fillW = barW;
|
||||
SDL_SetRenderDrawColor(renderer, pc.r, pc.g, pc.b, 255);
|
||||
SDL_FRect fill{barX, barY, fillW, barH};
|
||||
SDL_RenderFillRect(renderer, &fill);
|
||||
|
||||
yCursor = barY + barH + 18.0f;
|
||||
yCursor = rowBottom + rowSpacing;
|
||||
}
|
||||
|
||||
// Draw score panel (right side)
|
||||
@ -419,12 +435,26 @@ void GameRenderer::renderPlayingState(
|
||||
|
||||
// Pause overlay (suppressed when requested, e.g., countdown)
|
||||
if (!suppressPauseVisuals && game->isPaused() && !showExitConfirmPopup) {
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
for (int i = -4; i <= 4; ++i) {
|
||||
float spread = static_cast<float>(std::abs(i));
|
||||
Uint8 alpha = Uint8(std::max(8.f, 32.f - spread * 4.f));
|
||||
SDL_SetRenderDrawColor(renderer, 24, 32, 48, alpha);
|
||||
SDL_FRect blurRect{
|
||||
gridX - spread * 2.0f,
|
||||
gridY - spread * 1.5f,
|
||||
GRID_W + spread * 4.0f,
|
||||
GRID_H + spread * 3.0f
|
||||
};
|
||||
SDL_RenderFillRect(renderer, &blurRect);
|
||||
}
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 180);
|
||||
SDL_FRect pauseOverlay{0, 0, logicalW, logicalH};
|
||||
SDL_RenderFillRect(renderer, &pauseOverlay);
|
||||
|
||||
pixelFont->draw(renderer, logicalW * 0.5f - 80, logicalH * 0.5f - 20, "PAUSED", 2.0f, {255, 255, 255, 255});
|
||||
pixelFont->draw(renderer, logicalW * 0.5f - 120, logicalH * 0.5f + 30, "Press P to resume", 0.8f, {200, 200, 220, 255});
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
if (showExitConfirmPopup) {
|
||||
|
||||
@ -296,63 +296,75 @@ void GameRenderer::renderPlayingState(
|
||||
int totalBlocks = 0;
|
||||
for (int i = 0; i < PIECE_COUNT; ++i) totalBlocks += blockCounts[i];
|
||||
|
||||
const char* pieceNames[] = {"I", "O", "T", "S", "Z", "J", "L"};
|
||||
float yCursor = statsY + 52;
|
||||
const float rowPadding = 18.0f;
|
||||
const float rowWidth = statsW - rowPadding * 2.0f;
|
||||
const float rowSpacing = 12.0f;
|
||||
float yCursor = statsY + 44.0f;
|
||||
|
||||
for (int i = 0; i < PIECE_COUNT; ++i) {
|
||||
float py = yCursor;
|
||||
float rowTop = yCursor;
|
||||
float previewSize = finalBlockSize * 0.52f;
|
||||
float previewX = statsX + rowPadding;
|
||||
float previewY = rowTop - 14.0f;
|
||||
|
||||
// Draw small piece icon
|
||||
float previewSize = finalBlockSize * 0.55f;
|
||||
drawSmallPiece(renderer, blocksTex, static_cast<PieceType>(i), statsX + 18, py, previewSize);
|
||||
|
||||
// Compute preview height
|
||||
// Determine actual preview height to keep bars below the blocks
|
||||
Game::Piece previewPiece{};
|
||||
previewPiece.type = static_cast<PieceType>(i);
|
||||
int maxCy = -1;
|
||||
Game::Piece prev;
|
||||
prev.type = static_cast<PieceType>(i);
|
||||
prev.rot = 0;
|
||||
prev.x = 0;
|
||||
prev.y = 0;
|
||||
for (int cy = 0; cy < 4; ++cy) {
|
||||
for (int cx = 0; cx < 4; ++cx) {
|
||||
if (Game::cellFilled(prev, cx, cy)) maxCy = std::max(maxCy, cy);
|
||||
if (Game::cellFilled(previewPiece, cx, cy)) {
|
||||
maxCy = std::max(maxCy, cy);
|
||||
}
|
||||
}
|
||||
int tilesHigh = (maxCy >= 0 ? maxCy + 1 : 1);
|
||||
float previewHeight = tilesHigh * previewSize;
|
||||
}
|
||||
float pieceHeight = (maxCy >= 0 ? maxCy + 1.0f : 1.0f) * previewSize;
|
||||
|
||||
// Count display
|
||||
int count = blockCounts[i];
|
||||
char countStr[16];
|
||||
snprintf(countStr, sizeof(countStr), "%d", count);
|
||||
pixelFont->draw(renderer, statsX + statsW - 20, py + 6, countStr, 1.1f, {240, 240, 245, 255});
|
||||
int countW = 0, countH = 0;
|
||||
pixelFont->measure(countStr, 1.0f, countW, countH);
|
||||
float countX = previewX + rowWidth - static_cast<float>(countW);
|
||||
float countY = previewY + 9.0f;
|
||||
|
||||
// Percentage bar
|
||||
int perc = (totalBlocks > 0) ? int(std::round(100.0 * double(count) / double(totalBlocks))) : 0;
|
||||
char percStr[16];
|
||||
snprintf(percStr, sizeof(percStr), "%d%%", perc);
|
||||
|
||||
float barX = statsX + 12;
|
||||
float barY = py + previewHeight + 18.0f;
|
||||
float barW = statsW - 24;
|
||||
float barH = 6;
|
||||
float barX = previewX;
|
||||
float barY = previewY + pieceHeight + 12.0f;
|
||||
float barH = 6.0f;
|
||||
float barW = rowWidth;
|
||||
float percY = barY + barH + 8.0f;
|
||||
|
||||
pixelFont->draw(renderer, barX, barY - 16, percStr, 0.8f, {230, 230, 235, 255});
|
||||
float rowBottom = percY + 16.0f;
|
||||
SDL_FRect rowBg{
|
||||
previewX - 12.0f,
|
||||
rowTop - 14.0f,
|
||||
rowWidth + 24.0f,
|
||||
rowBottom - (rowTop - 14.0f)
|
||||
};
|
||||
SDL_SetRenderDrawColor(renderer, 18, 26, 40, 200);
|
||||
SDL_RenderFillRect(renderer, &rowBg);
|
||||
SDL_SetRenderDrawColor(renderer, 70, 100, 150, 210);
|
||||
SDL_RenderRect(renderer, &rowBg);
|
||||
|
||||
// Progress bar
|
||||
SDL_SetRenderDrawColor(renderer, 170, 170, 175, 200);
|
||||
drawSmallPiece(renderer, blocksTex, static_cast<PieceType>(i), previewX, previewY, previewSize);
|
||||
pixelFont->draw(renderer, countX, countY, countStr, 1.0f, {245, 245, 255, 255});
|
||||
pixelFont->draw(renderer, previewX, percY, percStr, 0.8f, {215, 225, 240, 255});
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 110, 120, 140, 200);
|
||||
SDL_FRect track{barX, barY, barW, barH};
|
||||
SDL_RenderFillRect(renderer, &track);
|
||||
|
||||
SDL_Color pc = COLORS[i + 1];
|
||||
SDL_SetRenderDrawColor(renderer, pc.r, pc.g, pc.b, 230);
|
||||
SDL_SetRenderDrawColor(renderer, pc.r, pc.g, pc.b, 255);
|
||||
float fillW = barW * (perc / 100.0f);
|
||||
if (fillW < 0) fillW = 0;
|
||||
if (fillW > barW) fillW = barW;
|
||||
fillW = std::clamp(fillW, 0.0f, barW);
|
||||
SDL_FRect fill{barX, barY, fillW, barH};
|
||||
SDL_RenderFillRect(renderer, &fill);
|
||||
|
||||
yCursor = barY + barH + 18.0f;
|
||||
yCursor = rowBottom + rowSpacing;
|
||||
}
|
||||
|
||||
// Draw score panel (right side)
|
||||
@ -418,12 +430,27 @@ void GameRenderer::renderPlayingState(
|
||||
|
||||
// Pause overlay (skip when visuals are suppressed, e.g., countdown)
|
||||
if (!suppressPauseVisuals && game->isPaused() && !showExitConfirmPopup) {
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
for (int i = -4; i <= 4; ++i) {
|
||||
float spread = static_cast<float>(std::abs(i));
|
||||
Uint8 alpha = Uint8(std::max(8.f, 32.f - spread * 4.f));
|
||||
SDL_SetRenderDrawColor(renderer, 24, 32, 48, alpha);
|
||||
SDL_FRect blurRect{
|
||||
gridX - spread * 2.0f,
|
||||
gridY - spread * 1.5f,
|
||||
GRID_W + spread * 4.0f,
|
||||
GRID_H + spread * 3.0f
|
||||
};
|
||||
SDL_RenderFillRect(renderer, &blurRect);
|
||||
}
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 180);
|
||||
SDL_FRect pauseOverlay{0, 0, logicalW, logicalH};
|
||||
SDL_RenderFillRect(renderer, &pauseOverlay);
|
||||
|
||||
pixelFont->draw(renderer, logicalW * 0.5f - 80, logicalH * 0.5f - 20, "PAUSED", 2.0f, {255, 255, 255, 255});
|
||||
pixelFont->draw(renderer, logicalW * 0.5f - 120, logicalH * 0.5f + 30, "Press P to resume", 0.8f, {200, 200, 220, 255});
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
// Exit confirmation popup styled like other retro panels
|
||||
|
||||
Reference in New Issue
Block a user