fixed statistics panel
This commit is contained in:
@ -348,14 +348,20 @@ void GameRenderer::renderPlayingState(
|
|||||||
snprintf(countStr, sizeof(countStr), "%d", count);
|
snprintf(countStr, sizeof(countStr), "%d", count);
|
||||||
int countW = 0, countH = 0;
|
int countW = 0, countH = 0;
|
||||||
pixelFont->measure(countStr, 1.0f, countW, countH);
|
pixelFont->measure(countStr, 1.0f, countW, countH);
|
||||||
float countX = previewX + rowWidth - static_cast<float>(countW);
|
// Horizontal shift to push the counts/percent a bit more to the right
|
||||||
|
const float statsNumbersShift = 20.0f;
|
||||||
|
// Small left shift for progress bar so the track aligns better with the design
|
||||||
|
const float statsBarShift = -10.0f;
|
||||||
|
float countX = previewX + rowWidth - static_cast<float>(countW) + statsNumbersShift;
|
||||||
float countY = previewY + 9.0f;
|
float countY = previewY + 9.0f;
|
||||||
|
|
||||||
int perc = (totalBlocks > 0) ? int(std::round(100.0 * double(count) / double(totalBlocks))) : 0;
|
int perc = (totalBlocks > 0) ? int(std::round(100.0 * double(count) / double(totalBlocks))) : 0;
|
||||||
char percStr[16];
|
char percStr[16];
|
||||||
snprintf(percStr, sizeof(percStr), "%d%%", perc);
|
snprintf(percStr, sizeof(percStr), "%d%%", perc);
|
||||||
|
int percW = 0, percH = 0;
|
||||||
|
pixelFont->measure(percStr, 0.8f, percW, percH);
|
||||||
|
|
||||||
float barX = previewX;
|
float barX = previewX + statsBarShift;
|
||||||
float barY = previewY + pieceHeight + 12.0f;
|
float barY = previewY + pieceHeight + 12.0f;
|
||||||
float barH = 6.0f;
|
float barH = 6.0f;
|
||||||
float barW = rowWidth;
|
float barW = rowWidth;
|
||||||
@ -378,7 +384,9 @@ void GameRenderer::renderPlayingState(
|
|||||||
|
|
||||||
drawSmallPiece(renderer, blocksTex, static_cast<PieceType>(i), previewX, previewY, previewSize);
|
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, countX, countY, countStr, 1.0f, {245, 245, 255, 255});
|
||||||
pixelFont->draw(renderer, previewX, percY, percStr, 0.8f, {215, 225, 240, 255});
|
// Draw percent right-aligned near the same right edge as the count
|
||||||
|
float percX = previewX + rowWidth - static_cast<float>(percW) + statsNumbersShift;
|
||||||
|
pixelFont->draw(renderer, percX, percY, percStr, 0.8f, {215, 225, 240, 255});
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(renderer, 110, 120, 140, 200);
|
SDL_SetRenderDrawColor(renderer, 110, 120, 140, 200);
|
||||||
SDL_FRect track{barX, barY, barW, barH};
|
SDL_FRect track{barX, barY, barW, barH};
|
||||||
|
|||||||
@ -616,28 +616,27 @@ void GameRenderer::renderPlayingState(
|
|||||||
GRID_H + blocksPanelPadY * 2.0f
|
GRID_H + blocksPanelPadY * 2.0f
|
||||||
};
|
};
|
||||||
if (statisticsPanelTex) {
|
if (statisticsPanelTex) {
|
||||||
// Use the dedicated statistics panel image for the left panel when available.
|
// Use the dedicated statistics panel image; scale it to fit the panel while
|
||||||
// Preserve aspect ratio by scaling to the panel width and center/crop vertically if needed.
|
// preserving aspect ratio (no crop) so very tall source images don't overflow.
|
||||||
float texWf = 0.0f, texHf = 0.0f;
|
float texWf = 0.0f, texHf = 0.0f;
|
||||||
if (SDL_GetTextureSize(statisticsPanelTex, &texWf, &texHf) == 0) {
|
if (SDL_GetTextureSize(statisticsPanelTex, &texWf, &texHf)) {
|
||||||
|
if (texWf > 0.0f && texHf > 0.0f) {
|
||||||
const float destW = blocksPanelBg.w;
|
const float destW = blocksPanelBg.w;
|
||||||
const float destH = blocksPanelBg.h;
|
const float destH = blocksPanelBg.h;
|
||||||
const float scale = destW / texWf;
|
const float scale = std::min(destW / texWf, destH / texHf);
|
||||||
|
const float scaledW = texWf * scale;
|
||||||
const float scaledH = texHf * scale;
|
const float scaledH = texHf * scale;
|
||||||
|
// Center the scaled texture inside the panel
|
||||||
if (scaledH <= destH) {
|
SDL_FRect dstF{
|
||||||
// Fits vertically: draw full texture centered vertically
|
blocksPanelBg.x + (destW - scaledW) * 0.5f,
|
||||||
SDL_FRect srcF{0.0f, 0.0f, texWf, texHf};
|
blocksPanelBg.y + (destH - scaledH) * 0.5f,
|
||||||
SDL_RenderTexture(renderer, statisticsPanelTex, &srcF, &blocksPanelBg);
|
scaledW,
|
||||||
} else {
|
scaledH
|
||||||
// Texture is taller when scaled to width: crop vertically from texture
|
};
|
||||||
float srcHf = destH / scale;
|
SDL_RenderTexture(renderer, statisticsPanelTex, nullptr, &dstF);
|
||||||
float srcYf = std::max(0.0f, (texHf - srcHf) * 0.5f);
|
|
||||||
SDL_FRect srcF{0.0f, srcYf, texWf, srcHf};
|
|
||||||
SDL_RenderTexture(renderer, statisticsPanelTex, &srcF, &blocksPanelBg);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Fallback: render entire texture if query failed
|
// Fallback: render entire texture stretched to panel
|
||||||
SDL_RenderTexture(renderer, statisticsPanelTex, nullptr, &blocksPanelBg);
|
SDL_RenderTexture(renderer, statisticsPanelTex, nullptr, &blocksPanelBg);
|
||||||
}
|
}
|
||||||
} else if (scorePanelTex) {
|
} else if (scorePanelTex) {
|
||||||
@ -1090,19 +1089,26 @@ void GameRenderer::renderPlayingState(
|
|||||||
const SDL_Color headerColor{255, 220, 0, 255};
|
const SDL_Color headerColor{255, 220, 0, 255};
|
||||||
const SDL_Color textColor{200, 220, 235, 200};
|
const SDL_Color textColor{200, 220, 235, 200};
|
||||||
const SDL_Color mutedColor{150, 180, 200, 180};
|
const SDL_Color mutedColor{150, 180, 200, 180};
|
||||||
pixelFont->draw(renderer, statsX + 12.0f, statsY + 8.0f, "STATISTICS", 0.46f, headerColor);
|
// Small vertical shift to push text further into the statistics panel
|
||||||
|
// Increased from 20 to 80 to move text down by ~60px more (within 50-100px range)
|
||||||
|
const float statsTextShift = 80.0f;
|
||||||
|
pixelFont->draw(renderer, statsX + 12.0f, statsY + 8.0f + statsTextShift, "STATISTICS", 0.70f, headerColor);
|
||||||
|
|
||||||
// Tighter spacing and smaller icons/text for compact analytics console
|
// Tighter spacing and smaller icons/text for compact analytics console
|
||||||
float yCursor = statsY + 34.0f;
|
float yCursor = statsY + 34.0f + statsTextShift;
|
||||||
const float leftPad = 2.0f;
|
const float leftPad = 2.0f;
|
||||||
const float rightPad = 14.0f;
|
const float rightPad = 14.0f;
|
||||||
|
// Horizontal shift to nudge the count/percent group closer to the right edge
|
||||||
|
const float statsNumbersShift = 20.0f;
|
||||||
|
// Horizontal shift to move the progress bar slightly left
|
||||||
|
const float statsBarShift = -10.0f;
|
||||||
// Increase row gap to avoid icon overlap on smaller scales (bumped up)
|
// Increase row gap to avoid icon overlap on smaller scales (bumped up)
|
||||||
const float rowGap = 28.0f;
|
const float rowGap = 28.0f;
|
||||||
const float barHeight = 2.0f;
|
const float barHeight = 2.0f;
|
||||||
|
|
||||||
// Text scales for per-row numbers (slightly larger than before)
|
// Text scales for per-row numbers (slightly larger than before)
|
||||||
const float countScale = 0.45f;
|
const float countScale = 0.60f;
|
||||||
const float percScale = 0.43f;
|
const float percScale = 0.60f;
|
||||||
|
|
||||||
// Determine max percent to highlight top used piece
|
// Determine max percent to highlight top used piece
|
||||||
int maxPerc = 0;
|
int maxPerc = 0;
|
||||||
@ -1157,7 +1163,7 @@ void GameRenderer::renderPlayingState(
|
|||||||
int maxTextH = std::max(countH, percH);
|
int maxTextH = std::max(countH, percH);
|
||||||
float numbersW = numbersPadX * 2.0f + countW + numbersGap + percW;
|
float numbersW = numbersPadX * 2.0f + countW + numbersGap + percW;
|
||||||
float numbersH = numbersPadY * 2.0f + static_cast<float>(maxTextH);
|
float numbersH = numbersPadY * 2.0f + static_cast<float>(maxTextH);
|
||||||
float numbersX = rowRight - numbersW;
|
float numbersX = rowRight - numbersW + statsNumbersShift;
|
||||||
float numbersY = yCursor - (numbersH - static_cast<float>(maxTextH)) * 0.5f;
|
float numbersY = yCursor - (numbersH - static_cast<float>(maxTextH)) * 0.5f;
|
||||||
|
|
||||||
float textY = numbersY + (numbersH - static_cast<float>(maxTextH)) * 0.5f;
|
float textY = numbersY + (numbersH - static_cast<float>(maxTextH)) * 0.5f;
|
||||||
@ -1168,7 +1174,7 @@ void GameRenderer::renderPlayingState(
|
|||||||
pixelFont->draw(renderer, percX, textY, percStr, percScale, mutedColor);
|
pixelFont->draw(renderer, percX, textY, percStr, percScale, mutedColor);
|
||||||
|
|
||||||
// Progress bar anchored to the numbers width
|
// Progress bar anchored to the numbers width
|
||||||
float barX = numbersX;
|
float barX = numbersX + statsBarShift;
|
||||||
float barW = numbersW;
|
float barW = numbersW;
|
||||||
float barY = numbersY + numbersH + 8.0f;
|
float barY = numbersY + numbersH + 8.0f;
|
||||||
|
|
||||||
@ -1196,8 +1202,11 @@ void GameRenderer::renderPlayingState(
|
|||||||
yCursor = barY + barHeight + rowGap + 6.0f;
|
yCursor = barY + barHeight + rowGap + 6.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom summary stats
|
// Bottom summary stats: prefer to place summary right after last row
|
||||||
float summaryY = statsY + statsH - 90.0f; // move summary slightly up
|
// but clamp it so it never goes below the reserved bottom area.
|
||||||
|
float preferredSummaryY = yCursor + 24.0f; // space below last row
|
||||||
|
float maxSummaryY = statsY + statsH - 90.0f; // original lower bound
|
||||||
|
float summaryY = std::min(preferredSummaryY, maxSummaryY);
|
||||||
const SDL_Color summaryValueColor{220, 235, 250, 255};
|
const SDL_Color summaryValueColor{220, 235, 250, 255};
|
||||||
const SDL_Color labelMuted{160, 180, 200, 200};
|
const SDL_Color labelMuted{160, 180, 200, 200};
|
||||||
|
|
||||||
@ -1210,20 +1219,20 @@ void GameRenderer::renderPlayingState(
|
|||||||
const float valueRightPad = 12.0f; // pad from right edge
|
const float valueRightPad = 12.0f; // pad from right edge
|
||||||
|
|
||||||
int valW=0, valH=0;
|
int valW=0, valH=0;
|
||||||
pixelFont->measure(totalStr, 0.41f, valW, valH);
|
pixelFont->measure(totalStr, 0.55f, valW, valH);
|
||||||
float totalX = statsX + statsW - valueRightPad - (float)valW;
|
float totalX = statsX + statsW - valueRightPad - (float)valW;
|
||||||
pixelFont->draw(renderer, labelX, summaryY + 0.0f, "TOTAL PIECES", 0.36f, labelMuted);
|
pixelFont->draw(renderer, labelX, summaryY + 0.0f, "TOTAL PIECES", 0.46f, labelMuted);
|
||||||
pixelFont->draw(renderer, totalX, summaryY + 0.0f, totalStr, 0.41f, summaryValueColor);
|
pixelFont->draw(renderer, totalX, summaryY + 0.0f, totalStr, 0.55f, summaryValueColor);
|
||||||
|
|
||||||
pixelFont->measure(tetrisesStr, 0.41f, valW, valH);
|
pixelFont->measure(tetrisesStr, 0.55f, valW, valH);
|
||||||
float tetrisesX = statsX + statsW - valueRightPad - (float)valW;
|
float tetrisesX = statsX + statsW - valueRightPad - (float)valW;
|
||||||
pixelFont->draw(renderer, labelX, summaryY + 22.0f, "TETRISES MADE", 0.36f, labelMuted);
|
pixelFont->draw(renderer, labelX, summaryY + 22.0f, "TETRISES MADE", 0.46f, labelMuted);
|
||||||
pixelFont->draw(renderer, tetrisesX, summaryY + 22.0f, tetrisesStr, 0.41f, summaryValueColor);
|
pixelFont->draw(renderer, tetrisesX, summaryY + 22.0f, tetrisesStr, 0.55f, summaryValueColor);
|
||||||
|
|
||||||
pixelFont->measure(maxComboStr, 0.41f, valW, valH);
|
pixelFont->measure(maxComboStr, 0.55f, valW, valH);
|
||||||
float comboX = statsX + statsW - valueRightPad - (float)valW;
|
float comboX = statsX + statsW - valueRightPad - (float)valW;
|
||||||
pixelFont->draw(renderer, labelX, summaryY + 44.0f, "MAX COMBO", 0.36f, labelMuted);
|
pixelFont->draw(renderer, labelX, summaryY + 44.0f, "MAX COMBO", 0.46f, labelMuted);
|
||||||
pixelFont->draw(renderer, comboX, summaryY + 44.0f, maxComboStr, 0.41f, summaryValueColor);
|
pixelFont->draw(renderer, comboX, summaryY + 44.0f, maxComboStr, 0.55f, summaryValueColor);
|
||||||
|
|
||||||
// Draw score panel (right side)
|
// Draw score panel (right side)
|
||||||
const float contentTopOffset = 0.0f;
|
const float contentTopOffset = 0.0f;
|
||||||
|
|||||||
Reference in New Issue
Block a user