Compare commits

..

3 Commits

Author SHA1 Message Date
5cb67b41d1 treballant en la intro 2025-07-14 19:43:07 +02:00
bfd3943bba Intro: les tarjetes ara tenen sombra
Intro: colors configurables a param
2025-07-14 19:20:28 +02:00
d35032a42a new: es pot definir el color de fonfo del titol
fix: el color de fondo de la intro ara ja canvia be cap al color de fondo del titol (abans soles sabia canviar cap al blanc)
2025-07-14 18:11:02 +02:00
11 changed files with 162 additions and 64 deletions

View File

@@ -40,6 +40,7 @@ title.press_start_position 170 # Posición Y del texto "Press Start"
title.title_duration 800 # Duración de la pantalla de título (frames)
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
title.title_c_c_position 80 # Posición Y del título principal
title.bg_color 808080 # Color de fondo en la sección titulo
## --- BACKGROUND ---
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
@@ -75,8 +76,10 @@ service_menu.bg_color 003000F5 # Color de fondo del menú de servicio (
service_menu.drop_shadow false # ¿El menú de servicio tiene sombra?
## --- INTRO ---
intro.bg_color 543149 # Color de fondo de la intro
intro.bg_color 00FFFF # Color de fondo de la intro
intro.card_color CBDBFC # Color de las tarjetas en la intro
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
intro.text_distance_from_bottom 48 # Posicion del texto
## --- DEBUG ---
debug.color 00FFFF # Color para elementos de depuración

View File

@@ -40,6 +40,7 @@ title.press_start_position 180 # Posición Y del texto "Press Start"
title.title_duration 800 # Duración de la pantalla de título (frames)
title.arcade_edition_position 123 # Posición Y del subtítulo "Arcade Edition"
title.title_c_c_position 80 # Posición Y del título principal
title.bg_color 808080 # Color de fondo en la sección titulo
## --- BACKGROUND ---
background.attenuate_color FFFFFF00 # Color de atenuación del fondo (RGBA hexadecimal)
@@ -75,8 +76,10 @@ service_menu.bg_color 000F00F5 # Color de fondo del menú de servicio (
service_menu.drop_shadow false # ¿El menú de servicio tiene sombra?
## --- INTRO ---
intro.bg_color 543149 # Color de fondo de la intro
intro.bg_color 00FFFF # Color de fondo de la intro
intro.card_color CBDBFC # Color de las tarjetas en la intro
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
intro.text_distance_from_bottom 48 # Posicion del texto
## --- DEBUG ---
debug.color 00FFFF # Color para elementos de depuración

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -49,7 +49,7 @@ Director::Director(int argc, const char *argv[])
Section::name = Section::Name::GAME;
Section::options = Section::Options::GAME_PLAY_1P;
#elif DEBUG
Section::name = Section::Name::TITLE;
Section::name = Section::Name::INTRO;
Section::options = Section::Options::GAME_PLAY_1P;
#else // NORMAL GAME
Section::name = Section::Name::LOGO;
@@ -402,6 +402,7 @@ void Director::setFileList()
// Texturas - Titulo
Asset::get()->add(prefix + "/data/gfx/title/title_bg_tile.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_bg_tile_v2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_coffee.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_crisis.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_arcade_edition.png", AssetType::BITMAP);

View File

@@ -55,6 +55,7 @@ void initParam()
param.title.title_duration = 800;
param.title.arcade_edition_position = 123;
param.title.title_c_c_position = 11;
param.title.bg_color = Color(255, 255, 255);
// BACKGROUND
param.background.attenuate_color = Color(255, 255, 255, 0);
@@ -77,6 +78,12 @@ void initParam()
param.notification.pos_h = NotifyPosition::LEFT;
param.notification.sound = false;
param.notification.color = Color(48, 48, 48);
// INTRO
param.intro.bg_color = Color::fromHex("543149");
param.intro.card_color = Color::fromHex("CBDBFC");
param.intro.shadow_color = Color::fromHex("00000080");
param.intro.text_distance_from_bottom = 48;
}
// Carga los parámetros desde un archivo
@@ -308,6 +315,11 @@ bool setParams(const std::string &var, const std::string &value)
param.title.title_c_c_position = std::stoi(value);
}
else if (var == "title.bg_color")
{
param.title.bg_color = Color::fromHex(value);
}
// BACKGROUND
else if (var == "background.attenuate_color")
{
@@ -449,6 +461,16 @@ bool setParams(const std::string &var, const std::string &value)
param.intro.card_color = Color::fromHex(value);
}
else if (var == "intro.shadow_color")
{
param.intro.shadow_color = Color::fromHex(value);
}
else if (var == "intro.text_distance_from_bottom")
{
param.intro.text_distance_from_bottom = std::stoi(value);
}
// DEBUG
else if (var == "debug.color")
{

View File

@@ -40,6 +40,7 @@ struct ParamTitle
int title_duration; // Tiempo de inactividad del título
int arcade_edition_position; // Posición del bitmap "Arcade Edition"
int title_c_c_position; // Posición del bitmap "Coffee Crisis"
Color bg_color; // Color para los tiles de fondo
};
// --- Parámetros del fondo ---
@@ -105,6 +106,8 @@ struct ParamIntro
{
Color bg_color;
Color card_color;
Color shadow_color;
int text_distance_from_bottom;
};
// --- Parámetros para Debug ---

View File

@@ -68,11 +68,11 @@ void Intro::updateScenes()
case 0:
{
// Primera imagen - UPV
sprites_.at(0)->enable();
card_sprites_.at(0)->enable();
shadow_sprites_.at(0)->enable();
// Primer texto de la primera imagen
if (sprites_.at(0)->hasFinished() && !texts_.at(0)->hasFinished())
if (card_sprites_.at(0)->hasFinished() && !texts_.at(0)->hasFinished())
{
texts_.at(0)->setEnabled(true);
}
@@ -104,11 +104,11 @@ void Intro::updateScenes()
case 1:
{
// Segunda imagen - Máquina
sprites_.at(1)->enable();
card_sprites_.at(1)->enable();
shadow_sprites_.at(1)->enable();
// Primer texto de la segunda imagen
if (sprites_.at(1)->hasFinished() && !texts_.at(3)->hasFinished())
if (card_sprites_.at(1)->hasFinished() && !texts_.at(3)->hasFinished())
{
texts_.at(3)->setEnabled(true);
}
@@ -128,14 +128,14 @@ void Intro::updateScenes()
// Tercera imagen junto con primer texto - GRITO
if (!texts_.at(4)->hasFinished())
{
sprites_.at(2)->enable();
card_sprites_.at(2)->enable();
shadow_sprites_.at(2)->enable();
texts_.at(4)->setEnabled(true);
}
// Fin de la tercera escena
if (sprites_.at(2)->hasFinished() && texts_.at(4)->hasFinished())
if (card_sprites_.at(2)->hasFinished() && texts_.at(4)->hasFinished())
{
texts_.at(4)->setEnabled(false);
scene_++;
@@ -147,7 +147,7 @@ void Intro::updateScenes()
case 3:
{
// Cuarta imagen junto con primer texto - Reflexión
sprites_.at(3)->enable();
card_sprites_.at(3)->enable();
shadow_sprites_.at(3)->enable();
if (!texts_.at(5)->hasFinished())
@@ -163,7 +163,7 @@ void Intro::updateScenes()
}
// Fin de la cuarta escena
if (sprites_.at(3)->hasFinished() && texts_.at(6)->hasFinished())
if (card_sprites_.at(3)->hasFinished() && texts_.at(6)->hasFinished())
{
texts_.at(6)->setEnabled(false);
scene_++;
@@ -175,7 +175,7 @@ void Intro::updateScenes()
case 4:
{
// Quinta imagen - Patada
sprites_.at(4)->enable();
card_sprites_.at(4)->enable();
shadow_sprites_.at(4)->enable();
// Primer texto de la quinta imagen
@@ -185,7 +185,7 @@ void Intro::updateScenes()
}
// Fin de la quinta escena
if (sprites_.at(4)->hasFinished() && texts_.at(7)->hasFinished())
if (card_sprites_.at(4)->hasFinished() && texts_.at(7)->hasFinished())
{
texts_.at(7)->setEnabled(false);
scene_++;
@@ -197,7 +197,7 @@ void Intro::updateScenes()
case 5:
{
// Sexta imagen junto con texto - Globos de café
sprites_.at(5)->enable();
card_sprites_.at(5)->enable();
shadow_sprites_.at(5)->enable();
if (!texts_.at(8)->hasFinished())
@@ -212,7 +212,7 @@ void Intro::updateScenes()
}
// Acaba la ultima imagen
if (sprites_.at(5)->hasFinished() && texts_.at(8)->hasFinished())
if (card_sprites_.at(5)->hasFinished() && texts_.at(8)->hasFinished())
{
state_ = IntroState::POST;
state_start_time_ = SDL_GetTicks();
@@ -272,6 +272,10 @@ void Intro::render()
case IntroState::SCENES:
{
renderSprites();
static const float HEIGHT = Resource::get()->getText("04b_25_metal")->getCharacterSize();
static SDL_FRect rect = {0.0f, param.game.height - param.intro.text_distance_from_bottom - HEIGHT, param.game.width, HEIGHT * 3};
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), param.intro.shadow_color.r, param.intro.shadow_color.g, param.intro.shadow_color.b, param.intro.shadow_color.a);
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
renderTexts();
break;
}
@@ -309,44 +313,75 @@ void Intro::initSprites()
"intro6.png"};
// Constantes
constexpr int TOTAL_SPRITES = TEXTURE_LIST.size();
const float BORDER = 2.0f;
auto texture = Resource::get()->getTexture(TEXTURE_LIST.front());
const float SPRITE_WIDTH = texture->getWidth();
const float SPRITE_HEIGHT = texture->getHeight();
const float X_DEST = param.game.game_area.center_x - SPRITE_WIDTH / 2;
const float Y_DEST = param.game.game_area.first_quarter_y - (SPRITE_HEIGHT / 4);
const float CARD_WIDTH = texture->getWidth() + (BORDER * 2);
const float CARD_HEIGHT = texture->getHeight() + (BORDER * 2);
// Inicializa los sprites con las imagenes
constexpr int TOTAL_SPRITES = 6;
for (int i = 0; i < TOTAL_SPRITES; ++i)
{
auto sprite = std::make_unique<PathSprite>(Resource::get()->getTexture(TEXTURE_LIST.at(i)));
sprite->setWidth(SPRITE_WIDTH);
sprite->setHeight(SPRITE_HEIGHT);
sprite->setSpriteClip(0, 0, SPRITE_WIDTH, SPRITE_HEIGHT);
sprites_.push_back(std::move(sprite));
}
sprites_.at(0)->addPath(-SPRITE_WIDTH - 10, X_DEST, PathType::HORIZONTAL, Y_DEST, 100, easeInOutExpo, 0);
sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, 100, easeOutBounce, 0);
sprites_.at(2)->addPath(-SPRITE_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, 40, easeOutQuint, 0);
sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, 300, easeInOutExpo, 0);
sprites_.at(4)->addPath(-SPRITE_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, 70, easeOutElastic, 0);
sprites_.at(5)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, 250, easeOutQuad, 450);
sprites_.at(5)->addPath(X_DEST, -SPRITE_WIDTH, PathType::HORIZONTAL, Y_DEST, 80, easeInElastic, 0);
// Constantes
const float BORDER = 4;
const float SHADOW_SPRITE_WIDTH = SPRITE_WIDTH + BORDER;
const float SHADOW_SPRITE_HEIGHT = SPRITE_HEIGHT + BORDER;
const float S_X_DEST = X_DEST - BORDER / 2;
const float S_Y_DEST = Y_DEST - BORDER / 2;
// Crea las texturas para las imágenes traseras
std::vector<std::shared_ptr<Texture>> shadow_textures;
// Crea las texturas para las tarjetas
std::vector<std::shared_ptr<Texture>> card_textures;
for (int i = 0; i < TOTAL_SPRITES; ++i)
{
// Crea la textura
auto card_texture = std::make_shared<Texture>(Screen::get()->getRenderer());
card_texture->createBlank(CARD_WIDTH, CARD_HEIGHT, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
card_texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Apuntamos el renderizador a la textura
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
card_texture->setAsRenderTarget(Screen::get()->getRenderer());
// Limpia la textura
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
SDL_RenderClear(Screen::get()->getRenderer());
// Pone color en el marco de la textura
auto color = param.intro.card_color;
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, color.a);
SDL_FRect rect1 = {1, 0, CARD_WIDTH - 2, CARD_HEIGHT};
SDL_FRect rect2 = {0, 1, CARD_WIDTH, CARD_HEIGHT - 2};
SDL_RenderRect(Screen::get()->getRenderer(), &rect1);
SDL_RenderRect(Screen::get()->getRenderer(), &rect2);
// Copia la textura con la imagen dentro del marco
SDL_FRect dest = {BORDER, BORDER, CARD_WIDTH - (BORDER * 2), CARD_HEIGHT - (BORDER * 2)};
SDL_RenderTexture(Screen::get()->getRenderer(), Resource::get()->getTexture(TEXTURE_LIST.at(i))->getSDLTexture(), nullptr, &dest);
// Deja el renderizador como estaba y añade la textura a la lista
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
card_textures.push_back(card_texture);
}
// Inicializa los sprites para las tarjetas
for (int i = 0; i < TOTAL_SPRITES; ++i)
{
auto sprite = std::make_unique<PathSprite>(card_textures.at(i));
sprite->setWidth(CARD_WIDTH);
sprite->setHeight(CARD_HEIGHT);
sprite->setSpriteClip(0, 0, CARD_WIDTH, CARD_HEIGHT);
card_sprites_.push_back(std::move(sprite));
}
const float X_DEST = param.game.game_area.center_x - CARD_WIDTH / 2;
const float Y_DEST = param.game.game_area.first_quarter_y - (CARD_HEIGHT / 4);
card_sprites_.at(0)->addPath(-CARD_WIDTH - 10, X_DEST, PathType::HORIZONTAL, Y_DEST, 100, easeInOutExpo, 0);
card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, 100, easeOutBounce, 0);
card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, 40, easeOutQuint, 0);
card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, 300, easeInOutExpo, 0);
card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, 70, easeOutElastic, 0);
card_sprites_.at(5)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, 250, easeOutQuad, 450);
card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, 80, easeInElastic, 0);
// Constantes
const float DESP = 8;
const float SHADOW_SPRITE_WIDTH = CARD_WIDTH;
const float SHADOW_SPRITE_HEIGHT = CARD_HEIGHT;
// Crea la textura para las sombras de las tarjetas
auto shadow_texture = std::make_shared<Texture>(Screen::get()->getRenderer());
shadow_texture->createBlank(SHADOW_SPRITE_WIDTH, SHADOW_SPRITE_HEIGHT, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
shadow_texture->setBlendMode(SDL_BLENDMODE_BLEND);
@@ -359,29 +394,32 @@ void Intro::initSprites()
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
SDL_RenderClear(Screen::get()->getRenderer());
// Pone color en el marco de la textura
auto color = param.intro.card_color;
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, color.a);
// Dibuja la sombra sobre la textura
auto color = param.intro.shadow_color;
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 255);
SDL_FRect rect1 = {1, 0, SHADOW_SPRITE_WIDTH - 2, SHADOW_SPRITE_HEIGHT};
SDL_FRect rect2 = {0, 1, SHADOW_SPRITE_WIDTH, SHADOW_SPRITE_HEIGHT - 2};
SDL_RenderRect(Screen::get()->getRenderer(), &rect1);
SDL_RenderRect(Screen::get()->getRenderer(), &rect2);
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect1);
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect2);
// Deja el renderizador como estaba y añade la textura a la lista
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
shadow_textures.push_back(shadow_texture);
}
// Inicializa los sprites para la sombra
// Inicializa los sprites para la sombras usando la texturas con la sombra
for (int i = 0; i < TOTAL_SPRITES; ++i)
{
auto sprite = std::make_unique<PathSprite>(shadow_textures.at(i));
auto color = param.intro.shadow_color;
auto sprite = std::make_unique<PathSprite>(shadow_texture);
sprite->setWidth(SHADOW_SPRITE_WIDTH);
sprite->setHeight(SHADOW_SPRITE_HEIGHT);
sprite->setSpriteClip(0, 0, SHADOW_SPRITE_WIDTH, SHADOW_SPRITE_HEIGHT);
sprite->getTexture()->setAlpha(color.a);
shadow_sprites_.push_back(std::move(sprite));
}
const float S_X_DEST = X_DEST + DESP;
const float S_Y_DEST = Y_DEST + DESP;
shadow_sprites_.at(0)->addPath(param.game.height + 10, S_Y_DEST, PathType::VERTICAL, S_X_DEST, 100, easeInOutExpo, 0);
shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, 100, easeOutBounce, 0);
shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, 40, easeOutQuint, 0);
@@ -398,8 +436,8 @@ void Intro::initTexts()
for (int i = 0; i < TOTAL_TEXTS; ++i)
{
auto w = std::make_unique<Writer>(Resource::get()->getText("04b_25_metal"));
w->setPosX(BLOCK * 0);
w->setPosY(param.game.height - (BLOCK * 6));
w->setPosX(0);
w->setPosY(param.game.height - param.intro.text_distance_from_bottom);
w->setKerning(-2);
w->setEnabled(false);
w->setFinishedCounter(180);
@@ -451,7 +489,7 @@ void Intro::initTexts()
// Actualiza los sprites
void Intro::updateSprites()
{
for (auto &sprite : sprites_)
for (auto &sprite : card_sprites_)
{
sprite->update();
}
@@ -475,7 +513,7 @@ void Intro::updateTexts()
void Intro::renderSprites()
{
shadow_sprites_.at(scene_)->render();
sprites_.at(scene_)->render();
card_sprites_.at(scene_)->render();
}
// Dibuja los textos
@@ -500,6 +538,7 @@ void Intro::updatePostState()
{
tiled_bg_->stopGracefully();
/*
// Modifica el color del fondo hasta llegar a blanco
if (bg_color_.r <= 253 || bg_color_.g <= 253 || bg_color_.b <= 253) // Garantiza que no se exceda de 255 al incrementar de 2 en 2
{
@@ -509,6 +548,17 @@ void Intro::updatePostState()
{
bg_color_ = Color(255, 255, 255); // Asegura que bg_color_ no exceda el límite máximo
}
*/
if (bg_color_.isEqualTo(param.title.bg_color))
{
// Ya hemos llegado al color objetivo
}
else
{
bg_color_ = bg_color_.approachTo(param.title.bg_color, 2);
}
tiled_bg_->setColor(bg_color_);
}

View File

@@ -41,10 +41,11 @@ private:
};
// --- Objetos ---
std::vector<std::unique_ptr<PathSprite>> sprites_; // Vector con los sprites inteligentes para los dibujos de la intro
std::vector<std::unique_ptr<PathSprite>> card_sprites_; // Vector con los sprites inteligentes para los dibujos de la intro
std::vector<std::unique_ptr<PathSprite>> shadow_sprites_; // Vector con los sprites inteligentes para las sombras
std::vector<std::unique_ptr<Writer>> texts_; // Textos de la intro
std::unique_ptr<TiledBG> tiled_bg_; // Fondo en mosaico
//std::unique_ptr<Sprite> shadow_square_for_text_; // Sprite
// --- Variables ---
Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa

View File

@@ -39,6 +39,7 @@ Title::Title()
state_(TitleState::LOGO_ANIMATING)
{
// Configura objetos
tiled_bg_->setColor(param.title.bg_color);
game_logo_->enable();
mini_logo_sprite_->setX(param.game.game_area.center_x - mini_logo_sprite_->getWidth() / 2);
fade_->setColor(param.fade.color);

View File

@@ -54,7 +54,7 @@ TiledBG::~TiledBG()
void TiledBG::fillTexture()
{
// Crea los objetos para pintar en la textura de fondo
auto tile = std::make_unique<Sprite>(Resource::get()->getTexture("title_bg_tile.png"), (SDL_FRect){0, 0, TILE_WIDTH_, TILE_HEIGHT_});
auto tile = std::make_unique<Sprite>(Resource::get()->getTexture("title_bg_tile_v2.png"), (SDL_FRect){0, 0, TILE_WIDTH_, TILE_HEIGHT_});
// Prepara para dibujar sobre la textura
auto temp = SDL_GetRenderTarget(renderer_);

View File

@@ -100,6 +100,20 @@ struct Color
return Color(r, g, b, a);
}
constexpr bool isEqualTo(const Color &other) const
{
return r == other.r && g == other.g && b == other.b && a == other.a;
}
constexpr Color approachTo(const Color &target, int step = 1) const
{
Uint8 newR = (std::abs(r - target.r) <= step) ? target.r : (r < target.r ? r + step : r - step);
Uint8 newG = (std::abs(g - target.g) <= step) ? target.g : (g < target.g ? g + step : g - step);
Uint8 newB = (std::abs(b - target.b) <= step) ? target.b : (b < target.b ? b + step : b - step);
return Color(newR, newG, newB, a);
}
};
// Estructura para definir un color HSV