feat(renderer): polish gameplay visuals — transport, starfield, sparkles, smooth piece motion
Add transport/transfer effect for NEXT → grid with cross-fade and preview swap Integrate in-grid Starfield3D with magnet targeting tied to active piece Spawn ambient sparkles and impact sparks (hard-drop crackle + burst on expiry) Smooth horizontal/fall interpolation for active piece (configurable smooth scroll) Refactor next panel / preview rendering and connector drawing Tweak stats/score panel layout, progress bars and typography for compact view Preserve safe alpha handling and restore renderer blend/scale state after overlays
This commit is contained in:
@ -25,20 +25,13 @@ float fitScale(FontAtlas& font, const char* text, float initialScale, float maxW
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace HelpOverlay {
|
||||
|
||||
void Render(
|
||||
SDL_Renderer* renderer,
|
||||
FontAtlas& font,
|
||||
float logicalWidth,
|
||||
float logicalHeight,
|
||||
float offsetX,
|
||||
float offsetY) {
|
||||
if (!renderer) {
|
||||
return;
|
||||
}
|
||||
void Render(SDL_Renderer* renderer, FontAtlas& font, float logicalWidth, float logicalHeight, float offsetX, float offsetY) {
|
||||
if (!renderer) return;
|
||||
|
||||
const std::array<ShortcutEntry, 5> generalShortcuts{{
|
||||
{"H", "Toggle this help overlay"},
|
||||
@ -58,7 +51,7 @@ void Render(
|
||||
{"DOWN", "Soft drop (faster fall)"},
|
||||
{"SPACE", "Hard drop / instant lock"},
|
||||
{"UP", "Rotate clockwise"},
|
||||
{"X", "Rotate counter-clockwise"},
|
||||
{"X", "Toggle rotation direction used by UP"},
|
||||
{"P", "Pause or resume"},
|
||||
{"ESC", "Open exit confirmation"}
|
||||
}};
|
||||
@ -72,7 +65,8 @@ void Render(
|
||||
drawRect(renderer, boxX - 2.0f, boxY - 2.0f, boxW + 4.0f, boxH + 4.0f, {10, 12, 20, 255});
|
||||
drawRect(renderer, boxX, boxY, boxW, boxH, {18, 22, 35, 240});
|
||||
|
||||
const float titleScale = 1.7f;
|
||||
// Slightly smaller overall title to fit tighter layouts
|
||||
const float titleScale = 1.45f;
|
||||
font.draw(renderer, boxX + 28.0f, boxY + 24.0f, "HELP & SHORTCUTS", titleScale, {255, 220, 0, 255});
|
||||
|
||||
const float contentPadding = 32.0f;
|
||||
@ -83,24 +77,43 @@ void Render(
|
||||
const float footerHeight = 46.0f;
|
||||
const float footerPadding = 18.0f;
|
||||
|
||||
const float sectionTitleScale = 1.1f;
|
||||
const float comboScale = 0.92f;
|
||||
const float descBaseScale = 0.8f;
|
||||
const float comboSpacing = 22.0f;
|
||||
const float sectionSpacing = 14.0f;
|
||||
// Slightly reduced scales for a more compact popup
|
||||
const float sectionTitleScale = 1.0f;
|
||||
const float comboScale = 0.82f;
|
||||
const float descBaseScale = 0.72f;
|
||||
// Increase vertical spacing between combo label and description for readability
|
||||
const float comboSpacing = 28.0f;
|
||||
// Increase spacing between sections and after titles
|
||||
const float sectionSpacing = 22.0f;
|
||||
|
||||
// Helper to draw text with extra letter-spacing (tracking) for section titles
|
||||
auto drawSpaced = [&](float sx, float sy, const char* text, float scale, SDL_Color color, float extraPx) {
|
||||
std::string stext(text);
|
||||
float x = sx;
|
||||
for (size_t i = 0; i < stext.size(); ++i) {
|
||||
std::string ch(1, stext[i]);
|
||||
font.draw(renderer, x, sy, ch.c_str(), scale, color);
|
||||
int cw = 0, chh = 0;
|
||||
font.measure(ch.c_str(), scale, cw, chh);
|
||||
x += static_cast<float>(cw) + extraPx;
|
||||
}
|
||||
};
|
||||
|
||||
auto drawSection = [&](float startX, float& cursorY, const char* title, const auto& entries) {
|
||||
font.draw(renderer, startX, cursorY, title, sectionTitleScale, {180, 200, 255, 255});
|
||||
cursorY += 26.0f;
|
||||
drawSpaced(startX, cursorY, title, sectionTitleScale, {180, 200, 255, 255}, 4.0f);
|
||||
// extra gap after section title
|
||||
cursorY += 34.0f;
|
||||
for (const auto& entry : entries) {
|
||||
font.draw(renderer, startX, cursorY, entry.combo, comboScale, {255, 255, 255, 255});
|
||||
// larger spacing between combo label and description
|
||||
cursorY += comboSpacing;
|
||||
|
||||
float descScale = fitScale(font, entry.description, descBaseScale, columnWidth - 10.0f);
|
||||
font.draw(renderer, startX, cursorY, entry.description, descScale, {200, 210, 230, 255});
|
||||
int descW = 0, descH = 0;
|
||||
font.measure(entry.description, descScale, descW, descH);
|
||||
cursorY += static_cast<float>(descH) + 10.0f;
|
||||
// a bit more space after description row
|
||||
cursorY += static_cast<float>(descH) + 14.0f;
|
||||
}
|
||||
cursorY += sectionSpacing;
|
||||
};
|
||||
@ -121,7 +134,7 @@ void Render(
|
||||
SDL_SetRenderDrawColor(renderer, 90, 110, 170, 255);
|
||||
SDL_RenderRect(renderer, &footerRect);
|
||||
|
||||
const char* closeLabel = "PRESS H TO CLOSE";
|
||||
const char* closeLabel = "PRESS H OR ESC TO CLOSE";
|
||||
float closeScale = fitScale(font, closeLabel, 1.0f, footerRect.w - footerPadding * 2.0f);
|
||||
int closeW = 0, closeH = 0;
|
||||
font.measure(closeLabel, closeScale, closeW, closeH);
|
||||
|
||||
Reference in New Issue
Block a user