afegides musiques
afegit control de brillo al starfield
This commit is contained in:
4
Makefile
4
Makefile
@@ -318,7 +318,7 @@ endif
|
||||
|
||||
# Backup to remote server
|
||||
backup:
|
||||
@echo "Backing up project to maverick:/home/sergio/git-backup/asteroids..."
|
||||
@echo "Backing up project to maverick:/home/sergio/git-backup/orni..."
|
||||
rsync -a --delete \
|
||||
--exclude='build/' \
|
||||
--exclude='*.o' \
|
||||
@@ -326,7 +326,7 @@ backup:
|
||||
--exclude='orni' \
|
||||
--exclude='orni_debug' \
|
||||
--exclude='*_release/' \
|
||||
$(DIR_ROOT) maverick:/home/sergio/git-backup/asteroids/
|
||||
$(DIR_ROOT) maverick:/home/sergio/git-backup/orni/
|
||||
@echo "Backup completed successfully"
|
||||
|
||||
# Help target
|
||||
|
||||
BIN
data/music/game.ogg
Normal file
BIN
data/music/game.ogg
Normal file
Binary file not shown.
BIN
data/music/title.ogg
Normal file
BIN
data/music/title.ogg
Normal file
Binary file not shown.
@@ -103,9 +103,12 @@ float Starfield::calcular_escala(const Estrella& estrella) const {
|
||||
float Starfield::calcular_brightness(const Estrella& estrella) const {
|
||||
// Interpolació lineal: estrelles properes (vora) més brillants
|
||||
// distancia_centre: 0.0 (centre, llunyanes) → 1.0 (vora, properes)
|
||||
return Defaults::Brightness::STARFIELD_MIN +
|
||||
float brightness_base = Defaults::Brightness::STARFIELD_MIN +
|
||||
(Defaults::Brightness::STARFIELD_MAX - Defaults::Brightness::STARFIELD_MIN) *
|
||||
estrella.distancia_centre;
|
||||
|
||||
// Aplicar multiplicador i limitar a 1.0
|
||||
return std::min(1.0f, brightness_base * multiplicador_brightness_);
|
||||
}
|
||||
|
||||
// Actualitzar posicions de les estrelles
|
||||
@@ -135,6 +138,11 @@ void Starfield::actualitzar(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
// Establir multiplicador de brightness
|
||||
void Starfield::set_brightness(float multiplier) {
|
||||
multiplicador_brightness_ = std::max(0.0f, multiplier); // Evitar valors negatius
|
||||
}
|
||||
|
||||
// Dibuixar totes les estrelles
|
||||
void Starfield::dibuixar() {
|
||||
if (!shape_estrella_->es_valida()) {
|
||||
|
||||
@@ -42,6 +42,7 @@ class Starfield {
|
||||
|
||||
// Setters per ajustar paràmetres en temps real
|
||||
void set_punt_fuga(const Punt& punt) { punt_fuga_ = punt; }
|
||||
void set_brightness(float multiplier);
|
||||
|
||||
private:
|
||||
// Estructura interna per cada estrella
|
||||
@@ -75,6 +76,7 @@ class Starfield {
|
||||
SDL_FRect area_; // Àrea activa
|
||||
float radi_max_; // Distància màxima del centre al límit de pantalla
|
||||
int densitat_; // Nombre total d'estrelles
|
||||
float multiplicador_brightness_{1.0f}; // Multiplicador de brillantor (1.0 = default)
|
||||
};
|
||||
|
||||
} // namespace Graphics
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "core/audio/audio.hpp"
|
||||
#include "core/audio/audio_cache.hpp"
|
||||
#include "core/defaults.hpp"
|
||||
#include "core/rendering/sdl_manager.hpp"
|
||||
#include "game/escenes/escena_joc.hpp"
|
||||
@@ -161,6 +162,13 @@ auto Director::run() -> int {
|
||||
// Inicialitzar sistema d'audio
|
||||
Audio::init();
|
||||
|
||||
// Precachejar música per evitar lag al començar
|
||||
AudioCache::getMusic("title.ogg");
|
||||
if (Options::console) {
|
||||
std::cout << "Música precachejada: "
|
||||
<< AudioCache::getMusicCacheSize() << " fitxers\n";
|
||||
}
|
||||
|
||||
// Bucle principal de gestió d'escenes
|
||||
while (GestorEscenes::actual != GestorEscenes::Escena::EIXIR) {
|
||||
switch (GestorEscenes::actual) {
|
||||
|
||||
@@ -141,6 +141,9 @@ void EscenaJoc::inicialitzar() {
|
||||
for (auto& bala : bales_) {
|
||||
bala.inicialitzar();
|
||||
}
|
||||
|
||||
// Iniciar música de joc (sense stopMusic, ja s'ha parat en destructor de TITOL)
|
||||
Audio::get()->playMusic("game.ogg");
|
||||
}
|
||||
|
||||
void EscenaJoc::actualitzar(float delta_time) {
|
||||
@@ -150,6 +153,8 @@ void EscenaJoc::actualitzar(float delta_time) {
|
||||
game_over_timer_ -= delta_time;
|
||||
|
||||
if (game_over_timer_ <= 0.0f) {
|
||||
// Aturar música de joc abans de tornar al títol
|
||||
Audio::get()->stopMusic();
|
||||
// Auto-transition to title screen
|
||||
GestorEscenes::actual = GestorEscenes::Escena::TITOL;
|
||||
return;
|
||||
|
||||
@@ -200,6 +200,10 @@ void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) {
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(ordre_explosio_.begin(), ordre_explosio_.end(), g);
|
||||
}
|
||||
else if (nou_estat == EstatAnimacio::POST_EXPLOSION)
|
||||
{
|
||||
Audio::get()->playMusic("title.ogg");
|
||||
}
|
||||
|
||||
std::cout << "[EscenaLogo] Canvi a estat: " << static_cast<int>(nou_estat)
|
||||
<< "\n";
|
||||
@@ -288,6 +292,7 @@ void EscenaLogo::actualitzar(float delta_time) {
|
||||
|
||||
case EstatAnimacio::POST_EXPLOSION:
|
||||
if (temps_estat_actual_ >= DURACIO_POST_EXPLOSION) {
|
||||
// Iniciar música de títol abans de la transició
|
||||
GestorEscenes::actual = GestorEscenes::Escena::TITOL;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "../effects/debris_manager.hpp"
|
||||
#include "game/effects/debris_manager.hpp"
|
||||
#include "core/defaults.hpp"
|
||||
#include "core/graphics/shape.hpp"
|
||||
#include "core/rendering/sdl_manager.hpp"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "escena_titol.hpp"
|
||||
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
@@ -15,6 +16,11 @@
|
||||
#include "core/system/global_events.hpp"
|
||||
#include "project.h"
|
||||
|
||||
namespace {
|
||||
// Brightness del starfield (1.0 = default, >1.0 més brillant, <1.0 menys brillant)
|
||||
constexpr float BRIGHTNESS_STARFIELD = 1.2f;
|
||||
} // namespace
|
||||
|
||||
EscenaTitol::EscenaTitol(SDLManager& sdl)
|
||||
: sdl_(sdl),
|
||||
text_(sdl.obte_renderer()),
|
||||
@@ -40,8 +46,21 @@ EscenaTitol::EscenaTitol(SDLManager& sdl)
|
||||
150 // densitat: 150 estrelles (50 per capa)
|
||||
);
|
||||
|
||||
// Configurar brightness del starfield
|
||||
starfield_->set_brightness(BRIGHTNESS_STARFIELD);
|
||||
|
||||
// Inicialitzar lletres del títol "ORNI ATTACK!"
|
||||
inicialitzar_titol();
|
||||
|
||||
// Iniciar música de títol si no està sonant
|
||||
if (Audio::get()->getMusicState() != Audio::MusicState::PLAYING) {
|
||||
Audio::get()->playMusic("title.ogg");
|
||||
}
|
||||
}
|
||||
|
||||
EscenaTitol::~EscenaTitol() {
|
||||
// Aturar música de títol quan es destrueix l'escena
|
||||
Audio::get()->stopMusic();
|
||||
}
|
||||
|
||||
void EscenaTitol::inicialitzar_titol() {
|
||||
@@ -256,9 +275,18 @@ void EscenaTitol::actualitzar(float delta_time) {
|
||||
estat_actual_ = EstatTitol::MAIN;
|
||||
}
|
||||
break;
|
||||
|
||||
case EstatTitol::MAIN:
|
||||
// No hi ha lògica d'actualització en l'estat MAIN
|
||||
break;
|
||||
|
||||
case EstatTitol::TRANSITION:
|
||||
temps_acumulat_ += delta_time;
|
||||
if (temps_acumulat_ >= DURACIO_TRANSITION) {
|
||||
// Transició a JOC (la música ja s'ha parat en el fade)
|
||||
GestorEscenes::actual = GestorEscenes::Escena::JOC;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,8 +301,8 @@ void EscenaTitol::dibuixar() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Estat MAIN: Dibuixar títol i text (sobre el starfield)
|
||||
if (estat_actual_ == EstatTitol::MAIN) {
|
||||
// Estat MAIN i TRANSITION: Dibuixar títol i text (sobre el starfield)
|
||||
if (estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::TRANSITION) {
|
||||
// === Dibuixar lletres del títol "ORNI ATTACK!" ===
|
||||
|
||||
// Dibuixar "ORNI" (línia 1)
|
||||
@@ -303,19 +331,31 @@ void EscenaTitol::dibuixar() {
|
||||
);
|
||||
}
|
||||
|
||||
// === Text "PRESS BUTTON TO PLAY" (a sota del títol) ===
|
||||
// === Text "PRESS BUTTON TO PLAY" ===
|
||||
// En estat MAIN: sempre visible
|
||||
// En estat TRANSITION: parpellejant (blink amb sinusoide)
|
||||
|
||||
const float spacing = 2.0f; // Espai entre caràcters (usat també per copyright)
|
||||
|
||||
bool mostrar_text = true;
|
||||
if (estat_actual_ == EstatTitol::TRANSITION) {
|
||||
// Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0
|
||||
float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0f * 3.14159f; // 2π × freq × temps
|
||||
mostrar_text = (std::sin(fase) > 0.0f);
|
||||
}
|
||||
|
||||
if (mostrar_text) {
|
||||
const std::string main_text = "PRESS BUTTON TO PLAY";
|
||||
const float escala_main = 1.0f;
|
||||
const float spacing = 2.0f;
|
||||
|
||||
float text_width = text_.get_text_width(main_text, escala_main, spacing);
|
||||
|
||||
float x_center = (Defaults::Game::WIDTH - text_width) / 2.0f;
|
||||
// Usar posició dinàmica: ATTACK + altura lletres + separació
|
||||
float altura_attack = lletres_attack_.empty() ? 50.0f : lletres_attack_[0].altura;
|
||||
float y_center = y_attack_dinamica_ + altura_attack + 70.0f; // 70px sota "ATTACK!"
|
||||
float y_center = y_attack_dinamica_ + altura_attack + 70.0f;
|
||||
|
||||
text_.render(main_text, Punt{x_center, y_center}, escala_main, spacing);
|
||||
}
|
||||
|
||||
// === Copyright a la part inferior (centrat horitzontalment) ===
|
||||
// Convert to uppercase since VectorText only supports A-Z
|
||||
@@ -346,9 +386,16 @@ void EscenaTitol::processar_events(const SDL_Event& event) {
|
||||
// Saltar a MAIN
|
||||
estat_actual_ = EstatTitol::MAIN;
|
||||
break;
|
||||
|
||||
case EstatTitol::MAIN:
|
||||
// Anar al joc
|
||||
GestorEscenes::actual = GestorEscenes::Escena::JOC;
|
||||
// Iniciar transició amb fade-out de música
|
||||
estat_actual_ = EstatTitol::TRANSITION;
|
||||
temps_acumulat_ = 0.0f; // Reset del comptador
|
||||
Audio::get()->fadeOutMusic(MUSIC_FADE); // Fade de 300ms
|
||||
break;
|
||||
|
||||
case EstatTitol::TRANSITION:
|
||||
// Ignorar inputs durant la transició
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,15 @@
|
||||
class EscenaTitol {
|
||||
public:
|
||||
explicit EscenaTitol(SDLManager& sdl);
|
||||
~EscenaTitol(); // Destructor per aturar música
|
||||
void executar(); // Bucle principal de l'escena
|
||||
|
||||
private:
|
||||
// Màquina d'estats per la pantalla de títol
|
||||
enum class EstatTitol {
|
||||
INIT, // Pantalla negra inicial (2 segons)
|
||||
MAIN // Pantalla de títol amb text
|
||||
MAIN, // Pantalla de títol amb text
|
||||
TRANSITION // Transició amb fade-out de música i text parpellejant
|
||||
};
|
||||
|
||||
// Estructura per emmagatzemar informació de cada lletra del títol
|
||||
@@ -49,11 +51,14 @@ class EscenaTitol {
|
||||
float y_attack_dinamica_; // Posició Y calculada dinàmicament per "ATTACK!"
|
||||
|
||||
// Constants
|
||||
static constexpr float DURACIO_INIT = 2.0f; // Duració de l'estat INIT (2 segons)
|
||||
static constexpr float DURACIO_INIT = 4.0f; // Duració de l'estat INIT (2 segons)
|
||||
static constexpr float DURACIO_TRANSITION = 1.5f; // Duració de la transició (1.5 segons)
|
||||
static constexpr float ESCALA_TITULO = 0.6f; // Escala per les lletres del títol (50%)
|
||||
static constexpr float ESPAI_ENTRE_LLETRES = 10.0f; // Espai entre lletres
|
||||
static constexpr float Y_ORNI = 150.0f; // Posició Y de "ORNI"
|
||||
static constexpr float SEPARACION_LINEAS = 10.0f; // Separació entre "ORNI" i "ATTACK!" (0.0f = pegades)
|
||||
static constexpr float BLINK_FREQUENCY = 3.0f; // Freqüència de parpelleig (3 Hz)
|
||||
static constexpr int MUSIC_FADE = 1000; // Duracio del fade de la musica del titol al començar a jugar
|
||||
|
||||
// Mètodes privats
|
||||
void actualitzar(float delta_time);
|
||||
|
||||
Reference in New Issue
Block a user