Updated game speed
This commit is contained in:
@ -4,6 +4,32 @@
|
||||
#include "../Font.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
// Local logical canvas size (matches main.cpp). Kept local to avoid changing many files.
|
||||
static constexpr int LOGICAL_W = 1200;
|
||||
static constexpr int LOGICAL_H = 1000;
|
||||
|
||||
extern bool showLevelPopup; // from main
|
||||
extern bool showSettingsPopup; // from main
|
||||
extern bool musicEnabled; // from main
|
||||
extern int hoveredButton; // from main
|
||||
// Call wrappers defined in main.cpp
|
||||
extern void menu_drawFireworks(SDL_Renderer* renderer);
|
||||
extern void menu_updateFireworks(double frameMs);
|
||||
extern double menu_getLogoAnimCounter();
|
||||
extern int menu_getHoveredButton();
|
||||
extern void menu_drawEnhancedButton(SDL_Renderer* renderer, FontAtlas& font, float cx, float cy, float w, float h,
|
||||
const std::string& label, bool isHovered, bool isSelected);
|
||||
|
||||
// Menu button wrapper implemented in main.cpp
|
||||
extern void menu_drawMenuButton(SDL_Renderer* renderer, FontAtlas& font, float cx, float cy, float w, float h,
|
||||
const std::string& label, SDL_Color bgColor, SDL_Color borderColor);
|
||||
|
||||
// wrappers for popups (defined in main.cpp)
|
||||
extern void menu_drawLevelSelectionPopup(SDL_Renderer* renderer, FontAtlas& font, SDL_Texture* bgTex, int selectedLevel);
|
||||
extern void menu_drawSettingsPopup(SDL_Renderer* renderer, FontAtlas& font, bool musicEnabled);
|
||||
|
||||
MenuState::MenuState(StateContext& ctx) : State(ctx) {}
|
||||
|
||||
@ -15,19 +41,125 @@ void MenuState::onExit() {
|
||||
}
|
||||
|
||||
void MenuState::handleEvent(const SDL_Event& e) {
|
||||
// Menu-specific key handling moved from main; main still handles mouse for now
|
||||
if (e.type == SDL_EVENT_KEY_DOWN && !e.key.repeat) {
|
||||
if (ctx.startLevelSelection && *ctx.startLevelSelection >= 0) {
|
||||
// keep simple: allow L/S toggles handled globally in main for now
|
||||
}
|
||||
}
|
||||
// Key-specific handling (allow main to handle global keys)
|
||||
(void)e;
|
||||
}
|
||||
|
||||
void MenuState::update(double frameMs) {
|
||||
// Update logo animation counter and particles similar to main
|
||||
(void)frameMs;
|
||||
}
|
||||
|
||||
void MenuState::render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP) {
|
||||
(void)renderer; (void)logicalScale; (void)logicalVP;
|
||||
// Main still performs actual rendering for now; this placeholder keeps the API.
|
||||
// Compute content offset using the same math as main
|
||||
float winW = float(logicalVP.w);
|
||||
float winH = float(logicalVP.h);
|
||||
float contentScale = logicalScale;
|
||||
float contentW = LOGICAL_W * contentScale;
|
||||
float contentH = LOGICAL_H * contentScale;
|
||||
float contentOffsetX = (winW - contentW) * 0.5f / contentScale;
|
||||
float contentOffsetY = (winH - contentH) * 0.5f / contentScale;
|
||||
|
||||
// Background is drawn by main (stretched to the full window) to avoid double-draw.
|
||||
|
||||
// Draw the animated logo and fireworks using the small logo if available (show whole image)
|
||||
SDL_Texture* logoToUse = ctx.logoSmallTex ? ctx.logoSmallTex : ctx.logoTex;
|
||||
if (logoToUse) {
|
||||
// Use dimensions provided by the shared context when available
|
||||
int texW = (logoToUse == ctx.logoSmallTex && ctx.logoSmallW > 0) ? ctx.logoSmallW : 872;
|
||||
int texH = (logoToUse == ctx.logoSmallTex && ctx.logoSmallH > 0) ? ctx.logoSmallH : 273;
|
||||
float maxW = LOGICAL_W * 0.6f;
|
||||
float scale = std::min(1.0f, maxW / float(texW));
|
||||
float dw = texW * scale;
|
||||
float dh = texH * scale;
|
||||
float logoX = (LOGICAL_W - dw) / 2.f + contentOffsetX;
|
||||
float logoY = LOGICAL_H * 0.05f + contentOffsetY;
|
||||
SDL_FRect dst{logoX, logoY, dw, dh};
|
||||
SDL_RenderTexture(renderer, logoToUse, nullptr, &dst);
|
||||
}
|
||||
|
||||
// Fireworks (draw above high scores / near buttons)
|
||||
menu_drawFireworks(renderer);
|
||||
|
||||
// Score list and top players with a sine-wave vertical animation (use pixelFont for retro look)
|
||||
float topPlayersY = LOGICAL_H * 0.30f + contentOffsetY; // more top padding
|
||||
FontAtlas* useFont = ctx.pixelFont ? ctx.pixelFont : ctx.font;
|
||||
if (useFont) {
|
||||
useFont->draw(renderer, LOGICAL_W * 0.5f - 110 + contentOffsetX, topPlayersY, std::string("TOP PLAYERS"), 1.8f, SDL_Color{255, 220, 0, 255});
|
||||
}
|
||||
|
||||
// High scores table with wave offset
|
||||
float scoresStartY = topPlayersY + 70; // more spacing under title
|
||||
const auto &hs = ctx.scores ? ctx.scores->all() : *(new std::vector<ScoreEntry>());
|
||||
size_t maxDisplay = std::min(hs.size(), size_t(12));
|
||||
|
||||
// Draw table header
|
||||
if (useFont) {
|
||||
float cx = LOGICAL_W * 0.5f + contentOffsetX;
|
||||
float colX[] = { cx - 280, cx - 180, cx - 20, cx + 90, cx + 200, cx + 300 };
|
||||
useFont->draw(renderer, colX[0], scoresStartY - 28, "RANK", 1.1f, SDL_Color{200,200,220,255});
|
||||
useFont->draw(renderer, colX[1], scoresStartY - 28, "PLAYER", 1.1f, SDL_Color{200,200,220,255});
|
||||
useFont->draw(renderer, colX[2], scoresStartY - 28, "SCORE", 1.1f, SDL_Color{200,200,220,255});
|
||||
useFont->draw(renderer, colX[3], scoresStartY - 28, "LINES", 1.1f, SDL_Color{200,200,220,255});
|
||||
useFont->draw(renderer, colX[4], scoresStartY - 28, "LEVEL", 1.1f, SDL_Color{200,200,220,255});
|
||||
useFont->draw(renderer, colX[5], scoresStartY - 28, "TIME", 1.1f, SDL_Color{200,200,220,255});
|
||||
}
|
||||
for (size_t i = 0; i < maxDisplay; ++i)
|
||||
{
|
||||
float baseY = scoresStartY + i * 25;
|
||||
float wave = std::sin((float)menu_getLogoAnimCounter() * 0.006f + i * 0.25f) * 6.0f; // subtle wave
|
||||
float y = baseY + wave;
|
||||
|
||||
// Center columns around mid X, wider
|
||||
float cx = LOGICAL_W * 0.5f + contentOffsetX;
|
||||
float colX[] = { cx - 280, cx - 180, cx - 20, cx + 90, cx + 200, cx + 300 };
|
||||
|
||||
char rankStr[8];
|
||||
std::snprintf(rankStr, sizeof(rankStr), "%zu.", i + 1);
|
||||
if (useFont) useFont->draw(renderer, colX[0], y, rankStr, 1.0f, SDL_Color{220, 220, 230, 255});
|
||||
|
||||
if (useFont) useFont->draw(renderer, colX[1], y, hs[i].name, 1.0f, SDL_Color{220, 220, 230, 255});
|
||||
|
||||
char scoreStr[16]; std::snprintf(scoreStr, sizeof(scoreStr), "%d", hs[i].score);
|
||||
if (useFont) useFont->draw(renderer, colX[2], y, scoreStr, 1.0f, SDL_Color{220, 220, 230, 255});
|
||||
|
||||
char linesStr[8]; std::snprintf(linesStr, sizeof(linesStr), "%d", hs[i].lines);
|
||||
if (useFont) useFont->draw(renderer, colX[3], y, linesStr, 1.0f, SDL_Color{220, 220, 230, 255});
|
||||
|
||||
char levelStr[8]; std::snprintf(levelStr, sizeof(levelStr), "%d", hs[i].level);
|
||||
if (useFont) useFont->draw(renderer, colX[4], y, levelStr, 1.0f, SDL_Color{220, 220, 230, 255});
|
||||
|
||||
char timeStr[16]; int mins = int(hs[i].timeSec) / 60; int secs = int(hs[i].timeSec) % 60;
|
||||
std::snprintf(timeStr, sizeof(timeStr), "%d:%02d", mins, secs);
|
||||
if (useFont) useFont->draw(renderer, colX[5], y, timeStr, 1.0f, SDL_Color{220, 220, 230, 255});
|
||||
}
|
||||
|
||||
// Draw bottom action buttons with responsive sizing (reduced to match main mouse hit-test)
|
||||
bool isSmall = (contentW < 700.0f);
|
||||
float btnW = isSmall ? (LOGICAL_W * 0.4f) : 300.0f;
|
||||
float btnH = isSmall ? 60.0f : 70.0f;
|
||||
float btnX = LOGICAL_W * 0.5f + contentOffsetX;
|
||||
// Move buttons down by 40px to match original layout (user requested 30-50px)
|
||||
const float btnYOffset = 40.0f;
|
||||
float btnY = LOGICAL_H * 0.86f + contentOffsetY + btnYOffset; // align with main's button vertical position
|
||||
|
||||
if (ctx.pixelFont) {
|
||||
char levelBtnText[32];
|
||||
int startLevel = ctx.startLevelSelection ? *ctx.startLevelSelection : 0;
|
||||
std::snprintf(levelBtnText, sizeof(levelBtnText), "LEVEL %d", startLevel);
|
||||
// left = green, right = blue like original
|
||||
menu_drawMenuButton(renderer, *ctx.pixelFont, btnX - btnW * 0.6f, btnY, btnW, btnH, std::string("PLAY"), SDL_Color{60,180,80,255}, SDL_Color{30,120,40,255});
|
||||
menu_drawMenuButton(renderer, *ctx.pixelFont, btnX + btnW * 0.6f, btnY, btnW, btnH, std::string(levelBtnText), SDL_Color{40,140,240,255}, SDL_Color{20,100,200,255});
|
||||
}
|
||||
|
||||
// Popups (level/settings) if requested
|
||||
if (ctx.showLevelPopup && *ctx.showLevelPopup) {
|
||||
// call wrapper which will internally draw on top of current content
|
||||
// prefer pixelFont for retro look
|
||||
FontAtlas* useFont = ctx.pixelFont ? ctx.pixelFont : ctx.font;
|
||||
menu_drawLevelSelectionPopup(renderer, *useFont, ctx.backgroundTex, ctx.startLevelSelection ? *ctx.startLevelSelection : 0);
|
||||
}
|
||||
if (ctx.showSettingsPopup && *ctx.showSettingsPopup) {
|
||||
menu_drawSettingsPopup(renderer, *ctx.font, ctx.musicEnabled ? *ctx.musicEnabled : false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user