highscore fixes

This commit is contained in:
2025-12-21 19:45:20 +01:00
parent 0b99911f5d
commit 50c869536d
7 changed files with 155 additions and 29 deletions

View File

@ -172,6 +172,8 @@ struct TetrisApp::Impl {
int hoveredButton = -1; // -1 = none, 0 = play, 1 = level, 2 = settings
bool isNewHighScore = false;
std::string playerName;
std::string player2Name;
int highScoreEntryIndex = 0; // 0 = entering player1, 1 = entering player2
bool helpOverlayPausedGame = false;
SDL_Window* window = nullptr;
@ -866,22 +868,54 @@ void TetrisApp::Impl::runLoop()
}
if (!showHelpOverlay && state == AppState::GameOver && isNewHighScore && e.type == SDL_EVENT_TEXT_INPUT) {
if (playerName.length() < 12) {
playerName += e.text.text;
// Support single-player and coop two-name entry
if (game && game->getMode() == GameMode::Cooperate && coopGame) {
if (highScoreEntryIndex == 0) {
if (playerName.length() < 12) playerName += e.text.text;
} else {
if (player2Name.length() < 12) player2Name += e.text.text;
}
} else {
if (playerName.length() < 12) playerName += e.text.text;
}
}
if (!showHelpOverlay && state == AppState::GameOver && e.type == SDL_EVENT_KEY_DOWN && !e.key.repeat) {
if (isNewHighScore) {
if (e.key.scancode == SDL_SCANCODE_BACKSPACE && !playerName.empty()) {
playerName.pop_back();
} else if (e.key.scancode == SDL_SCANCODE_RETURN || e.key.scancode == SDL_SCANCODE_KP_ENTER) {
if (playerName.empty()) playerName = "PLAYER";
ensureScoresLoaded();
scores.submit(game->score(), game->lines(), game->level(), game->elapsed(), playerName);
Settings::instance().setPlayerName(playerName);
isNewHighScore = false;
SDL_StopTextInput(window);
if (game && game->getMode() == GameMode::Cooperate && coopGame) {
// Two-name entry flow
if (e.key.scancode == SDL_SCANCODE_BACKSPACE) {
if (highScoreEntryIndex == 0 && !playerName.empty()) playerName.pop_back();
else if (highScoreEntryIndex == 1 && !player2Name.empty()) player2Name.pop_back();
} else if (e.key.scancode == SDL_SCANCODE_RETURN || e.key.scancode == SDL_SCANCODE_KP_ENTER) {
if (highScoreEntryIndex == 0) {
if (playerName.empty()) playerName = "P1";
highScoreEntryIndex = 1; // move to second name
} else {
if (player2Name.empty()) player2Name = "P2";
// Submit combined name
std::string combined = playerName + " & " + player2Name;
int leftScore = coopGame->score(CoopGame::PlayerSide::Left);
int rightScore = coopGame->score(CoopGame::PlayerSide::Right);
int combinedScore = leftScore + rightScore;
ensureScoresLoaded();
scores.submit(combinedScore, coopGame->lines(), coopGame->level(), coopGame->elapsed(), combined);
Settings::instance().setPlayerName(playerName);
isNewHighScore = false;
SDL_StopTextInput(window);
}
}
} else {
if (e.key.scancode == SDL_SCANCODE_BACKSPACE && !playerName.empty()) {
playerName.pop_back();
} else if (e.key.scancode == SDL_SCANCODE_RETURN || e.key.scancode == SDL_SCANCODE_KP_ENTER) {
if (playerName.empty()) playerName = "PLAYER";
ensureScoresLoaded();
scores.submit(game->score(), game->lines(), game->level(), game->elapsed(), playerName);
Settings::instance().setPlayerName(playerName);
isNewHighScore = false;
SDL_StopTextInput(window);
}
}
} else {
if (e.key.scancode == SDL_SCANCODE_RETURN || e.key.scancode == SDL_SCANCODE_KP_ENTER || e.key.scancode == SDL_SCANCODE_SPACE) {
@ -1255,6 +1289,21 @@ void TetrisApp::Impl::runLoop()
}
if (coopGame->isGameOver()) {
// Compute combined coop stats for Game Over
int leftScore = coopGame->score(CoopGame::PlayerSide::Left);
int rightScore = coopGame->score(CoopGame::PlayerSide::Right);
int combinedScore = leftScore + rightScore;
if (combinedScore > 0) {
isNewHighScore = true;
playerName.clear();
player2Name.clear();
highScoreEntryIndex = 0;
SDL_StartTextInput(window);
} else {
isNewHighScore = false;
ensureScoresLoaded();
scores.submit(combinedScore, coopGame->lines(), coopGame->level(), coopGame->elapsed());
}
state = AppState::GameOver;
stateMgr->setState(state);
}
@ -1974,13 +2023,29 @@ void TetrisApp::Impl::runLoop()
SDL_RenderFillRect(renderer, &boxRect);
ensureScoresLoaded();
bool realHighScore = scores.isHighScore(game->score());
// Choose display values based on mode (single-player vs coop)
int displayScore = 0;
int displayLines = 0;
int displayLevel = 0;
if (game && game->getMode() == GameMode::Cooperate && coopGame) {
int leftScore = coopGame->score(CoopGame::PlayerSide::Left);
int rightScore = coopGame->score(CoopGame::PlayerSide::Right);
displayScore = leftScore + rightScore;
displayLines = coopGame->lines();
displayLevel = coopGame->level();
} else if (game) {
displayScore = game->score();
displayLines = game->lines();
displayLevel = game->level();
}
bool realHighScore = scores.isHighScore(displayScore);
const char* title = realHighScore ? "NEW HIGH SCORE!" : "GAME OVER";
int tW=0, tH=0; pixelFont.measure(title, 2.0f, tW, tH);
pixelFont.draw(renderer, boxX + (boxW - tW) * 0.5f + contentOffsetX, boxY + 40 + contentOffsetY, title, 2.0f, realHighScore ? SDL_Color{255, 220, 0, 255} : SDL_Color{255, 60, 60, 255});
char scoreStr[64];
snprintf(scoreStr, sizeof(scoreStr), "SCORE: %d", game->score());
snprintf(scoreStr, sizeof(scoreStr), "SCORE: %d", displayScore);
int sW=0, sH=0; pixelFont.measure(scoreStr, 1.2f, sW, sH);
pixelFont.draw(renderer, boxX + (boxW - sW) * 0.5f + contentOffsetX, boxY + 100 + contentOffsetY, scoreStr, 1.2f, {255, 255, 255, 255});