efecte maquina d'escriure per als textos d'entrada de fase

This commit is contained in:
2025-12-09 19:38:29 +01:00
parent 94a7a38cdd
commit 64ab08973c
5 changed files with 96 additions and 13 deletions

View File

@@ -368,7 +368,7 @@ void EscenaJoc::dibuixar() {
gestor_puntuacio_.dibuixar();
// [EXISTING] Draw intro message and score
dibuixar_missatge_stage(StageSystem::Constants::MISSATGE_LEVEL_START);
dibuixar_missatge_stage(stage_manager_->get_missatge_level_start());
dibuixar_marcador();
break;
@@ -689,16 +689,67 @@ void EscenaJoc::detectar_col·lisio_nau_enemics() {
// [NEW] Stage system helper methods
void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
constexpr float escala = 1.0f;
constexpr float escala_base = 1.0f;
constexpr float spacing = 2.0f;
float text_width = text_.get_text_width(missatge, escala, spacing);
float text_height = text_.get_text_height(escala);
constexpr float max_width_ratio = 0.9f; // 90% del ancho disponible
const SDL_FRect& play_area = Defaults::Zones::PLAYAREA;
float x = play_area.x + (play_area.w - text_width) / 2.0f;
const float max_width = play_area.w * max_width_ratio; // 558px
// ========== TYPEWRITER EFFECT (PARAMETRIZED) ==========
// Get state-specific timing configuration
float total_time;
float typing_ratio;
if (stage_manager_->get_estat() == StageSystem::EstatStage::LEVEL_START) {
total_time = Defaults::Game::LEVEL_START_DURATION;
typing_ratio = Defaults::Game::LEVEL_START_TYPING_RATIO;
} else { // LEVEL_COMPLETED
total_time = Defaults::Game::LEVEL_COMPLETED_DURATION;
typing_ratio = Defaults::Game::LEVEL_COMPLETED_TYPING_RATIO;
}
// Calculate progress from timer (0.0 at start → 1.0 at end)
float remaining_time = stage_manager_->get_timer_transicio();
float progress = 1.0f - (remaining_time / total_time);
// Determine how many characters to show
size_t visible_chars;
if (typing_ratio > 0.0f && progress < typing_ratio) {
// Typewriter phase: show partial text
float typing_progress = progress / typing_ratio; // Normalize to 0.0-1.0
visible_chars = static_cast<size_t>(missatge.length() * typing_progress);
if (visible_chars == 0 && progress > 0.0f) {
visible_chars = 1; // Show at least 1 character after first frame
}
} else {
// Display phase: show complete text
// (Either after typing phase, or immediately if typing_ratio == 0.0)
visible_chars = missatge.length();
}
// Create partial message (substring for typewriter)
std::string partial_message = missatge.substr(0, visible_chars);
// ===================================================
// Calculate text width at base scale (using FULL message for position calculation)
float text_width_at_base = text_.get_text_width(missatge, escala_base, spacing);
// Auto-scale if text exceeds max width
float escala = (text_width_at_base <= max_width)
? escala_base
: max_width / text_width_at_base;
// Recalculate dimensions with final scale (using FULL message for centering)
float full_text_width = text_.get_text_width(missatge, escala, spacing);
float text_height = text_.get_text_height(escala);
// Calculate position as if FULL text was there (for fixed position typewriter)
float x = play_area.x + (play_area.w - full_text_width) / 2.0f;
float y = play_area.y + (play_area.h * 0.25f) - (text_height / 2.0f);
Punt pos = {static_cast<float>(x), static_cast<float>(y)};
text_.render(missatge, pos, escala, spacing);
// Render only the partial message (typewriter effect)
Punt pos = {x, y};
text_.render(partial_message, pos, escala, spacing);
}