Refactoring game render
This commit is contained in:
@ -189,6 +189,96 @@ static void drawHoldPanel(SDL_Renderer* renderer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw next piece panel (border/texture + preview)
|
||||||
|
static void drawNextPanel(SDL_Renderer* renderer,
|
||||||
|
FontAtlas* pixelFont,
|
||||||
|
SDL_Texture* nextPanelTex,
|
||||||
|
SDL_Texture* blocksTex,
|
||||||
|
Game* game,
|
||||||
|
float nextX,
|
||||||
|
float nextY,
|
||||||
|
float nextW,
|
||||||
|
float nextH,
|
||||||
|
float contentOffsetX,
|
||||||
|
float contentOffsetY,
|
||||||
|
float finalBlockSize) {
|
||||||
|
if (nextPanelTex) {
|
||||||
|
SDL_FRect dst{ nextX - contentOffsetX, nextY - contentOffsetY, nextW, nextH };
|
||||||
|
SDL_SetTextureBlendMode(nextPanelTex, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_RenderTexture(renderer, nextPanelTex, nullptr, &dst);
|
||||||
|
} else {
|
||||||
|
// Draw bordered panel as before
|
||||||
|
SDL_SetRenderDrawColor(renderer, 100, 120, 200, 255);
|
||||||
|
SDL_FRect outer{ nextX - 3 - contentOffsetX, nextY - 3 - contentOffsetY, nextW + 6, nextH + 6 };
|
||||||
|
SDL_RenderFillRect(renderer, &outer);
|
||||||
|
SDL_SetRenderDrawColor(renderer, 30, 35, 50, 255);
|
||||||
|
SDL_FRect inner{ nextX - contentOffsetX, nextY - contentOffsetY, nextW, nextH };
|
||||||
|
SDL_RenderFillRect(renderer, &inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Label and small preview
|
||||||
|
pixelFont->draw(renderer, nextX + 10, nextY - 20, "NEXT", 1.0f, {255, 220, 0, 255});
|
||||||
|
if (game->next().type < PIECE_COUNT) {
|
||||||
|
drawSmallPiece(renderer, blocksTex, static_cast<PieceType>(game->next().type), nextX + 10, nextY + 5, finalBlockSize * 0.6f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw score panel (right side)
|
||||||
|
static void drawScorePanel(SDL_Renderer* renderer,
|
||||||
|
FontAtlas* pixelFont,
|
||||||
|
Game* game,
|
||||||
|
float scoreX,
|
||||||
|
float gridY,
|
||||||
|
float GRID_H,
|
||||||
|
float finalBlockSize) {
|
||||||
|
const float contentTopOffset = 0.0f;
|
||||||
|
const float contentBottomOffset = 290.0f;
|
||||||
|
const float contentPad = 36.0f;
|
||||||
|
float scoreContentH = (contentBottomOffset - contentTopOffset) + contentPad;
|
||||||
|
float baseY = gridY + (GRID_H - scoreContentH) * 0.5f;
|
||||||
|
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 0, "SCORE", 1.0f, {255, 220, 0, 255});
|
||||||
|
char scoreStr[32];
|
||||||
|
snprintf(scoreStr, sizeof(scoreStr), "%d", game->score());
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 25, scoreStr, 0.9f, {255, 255, 255, 255});
|
||||||
|
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 70, "LINES", 1.0f, {255, 220, 0, 255});
|
||||||
|
char linesStr[16];
|
||||||
|
snprintf(linesStr, sizeof(linesStr), "%03d", game->lines());
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 95, linesStr, 0.9f, {255, 255, 255, 255});
|
||||||
|
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 140, "LEVEL", 1.0f, {255, 220, 0, 255});
|
||||||
|
char levelStr[16];
|
||||||
|
snprintf(levelStr, sizeof(levelStr), "%02d", game->level());
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 165, levelStr, 0.9f, {255, 255, 255, 255});
|
||||||
|
|
||||||
|
// Next level progress
|
||||||
|
int startLv = game->startLevelBase();
|
||||||
|
int firstThreshold = (startLv + 1) * 10;
|
||||||
|
int linesDone = game->lines();
|
||||||
|
int nextThreshold = 0;
|
||||||
|
if (linesDone < firstThreshold) {
|
||||||
|
nextThreshold = firstThreshold;
|
||||||
|
} else {
|
||||||
|
int blocksPast = linesDone - firstThreshold;
|
||||||
|
nextThreshold = firstThreshold + ((blocksPast / 10) + 1) * 10;
|
||||||
|
}
|
||||||
|
int linesForNext = std::max(0, nextThreshold - linesDone);
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 200, "NEXT LVL", 1.0f, {255, 220, 0, 255});
|
||||||
|
char nextStr[32];
|
||||||
|
snprintf(nextStr, sizeof(nextStr), "%d LINES", linesForNext);
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 225, nextStr, 0.9f, {80, 255, 120, 255});
|
||||||
|
|
||||||
|
// Time display
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 265, "TIME", 1.0f, {255, 220, 0, 255});
|
||||||
|
int totalSecs = static_cast<int>(game->elapsed());
|
||||||
|
int mins = totalSecs / 60;
|
||||||
|
int secs = totalSecs % 60;
|
||||||
|
char timeStr[16];
|
||||||
|
snprintf(timeStr, sizeof(timeStr), "%02d:%02d", mins, secs);
|
||||||
|
pixelFont->draw(renderer, scoreX, baseY + 290, timeStr, 0.9f, {255, 255, 255, 255});
|
||||||
|
}
|
||||||
|
|
||||||
void GameRenderer::renderPlayingState(
|
void GameRenderer::renderPlayingState(
|
||||||
SDL_Renderer* renderer,
|
SDL_Renderer* renderer,
|
||||||
Game* game,
|
Game* game,
|
||||||
@ -262,18 +352,9 @@ void GameRenderer::renderPlayingState(
|
|||||||
drawRectWithOffset(statsX - 3 - contentOffsetX, statsY - 3 - contentOffsetY, statsW + 6, statsH + 6, {100, 120, 200, 255});
|
drawRectWithOffset(statsX - 3 - contentOffsetX, statsY - 3 - contentOffsetY, statsW + 6, statsH + 6, {100, 120, 200, 255});
|
||||||
drawRectWithOffset(statsX - contentOffsetX, statsY - contentOffsetY, statsW, statsH, {30, 35, 50, 255});
|
drawRectWithOffset(statsX - contentOffsetX, statsY - contentOffsetY, statsW, statsH, {30, 35, 50, 255});
|
||||||
|
|
||||||
// Draw next piece preview panel border
|
// Draw next piece panel
|
||||||
// If a NEXT panel texture was provided, draw it instead of the custom
|
drawNextPanel(renderer, pixelFont, nextPanelTex, blocksTex, game, nextX, nextY, nextW, nextH, contentOffsetX, contentOffsetY, finalBlockSize);
|
||||||
// background/outline. The texture will be scaled to fit the panel area.
|
|
||||||
if (nextPanelTex) {
|
|
||||||
SDL_FRect dst{ nextX - contentOffsetX, nextY - contentOffsetY, nextW, nextH };
|
|
||||||
SDL_SetTextureBlendMode(nextPanelTex, SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_RenderTexture(renderer, nextPanelTex, nullptr, &dst);
|
|
||||||
} else {
|
|
||||||
drawRectWithOffset(nextX - 3 - contentOffsetX, nextY - 3 - contentOffsetY, nextW + 6, nextH + 6, {100, 120, 200, 255});
|
|
||||||
drawRectWithOffset(nextX - contentOffsetX, nextY - contentOffsetY, nextW, nextH, {30, 35, 50, 255});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the game board
|
// Draw the game board
|
||||||
const auto &board = game->boardRef();
|
const auto &board = game->boardRef();
|
||||||
for (int y = 0; y < Game::ROWS; ++y) {
|
for (int y = 0; y < Game::ROWS; ++y) {
|
||||||
@ -429,53 +510,8 @@ void GameRenderer::renderPlayingState(
|
|||||||
yCursor = rowBottom + rowSpacing;
|
yCursor = rowBottom + rowSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw score panel (right side)
|
// Draw score panel
|
||||||
const float contentTopOffset = 0.0f;
|
drawScorePanel(renderer, pixelFont, game, scoreX, gridY, GRID_H, finalBlockSize);
|
||||||
const float contentBottomOffset = 290.0f;
|
|
||||||
const float contentPad = 36.0f;
|
|
||||||
float scoreContentH = (contentBottomOffset - contentTopOffset) + contentPad;
|
|
||||||
float baseY = gridY + (GRID_H - scoreContentH) * 0.5f;
|
|
||||||
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 0, "SCORE", 1.0f, {255, 220, 0, 255});
|
|
||||||
char scoreStr[32];
|
|
||||||
snprintf(scoreStr, sizeof(scoreStr), "%d", game->score());
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 25, scoreStr, 0.9f, {255, 255, 255, 255});
|
|
||||||
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 70, "LINES", 1.0f, {255, 220, 0, 255});
|
|
||||||
char linesStr[16];
|
|
||||||
snprintf(linesStr, sizeof(linesStr), "%03d", game->lines());
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 95, linesStr, 0.9f, {255, 255, 255, 255});
|
|
||||||
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 140, "LEVEL", 1.0f, {255, 220, 0, 255});
|
|
||||||
char levelStr[16];
|
|
||||||
snprintf(levelStr, sizeof(levelStr), "%02d", game->level());
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 165, levelStr, 0.9f, {255, 255, 255, 255});
|
|
||||||
|
|
||||||
// Next level progress
|
|
||||||
int startLv = game->startLevelBase();
|
|
||||||
int firstThreshold = (startLv + 1) * 10;
|
|
||||||
int linesDone = game->lines();
|
|
||||||
int nextThreshold = 0;
|
|
||||||
if (linesDone < firstThreshold) {
|
|
||||||
nextThreshold = firstThreshold;
|
|
||||||
} else {
|
|
||||||
int blocksPast = linesDone - firstThreshold;
|
|
||||||
nextThreshold = firstThreshold + ((blocksPast / 10) + 1) * 10;
|
|
||||||
}
|
|
||||||
int linesForNext = std::max(0, nextThreshold - linesDone);
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 200, "NEXT LVL", 1.0f, {255, 220, 0, 255});
|
|
||||||
char nextStr[32];
|
|
||||||
snprintf(nextStr, sizeof(nextStr), "%d LINES", linesForNext);
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 225, nextStr, 0.9f, {80, 255, 120, 255});
|
|
||||||
|
|
||||||
// Time display
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 265, "TIME", 1.0f, {255, 220, 0, 255});
|
|
||||||
int totalSecs = static_cast<int>(game->elapsed());
|
|
||||||
int mins = totalSecs / 60;
|
|
||||||
int secs = totalSecs % 60;
|
|
||||||
char timeStr[16];
|
|
||||||
snprintf(timeStr, sizeof(timeStr), "%02d:%02d", mins, secs);
|
|
||||||
pixelFont->draw(renderer, scoreX, baseY + 290, timeStr, 0.9f, {255, 255, 255, 255});
|
|
||||||
|
|
||||||
// Gravity HUD
|
// Gravity HUD
|
||||||
char gms[64];
|
char gms[64];
|
||||||
|
|||||||
Reference in New Issue
Block a user