254 lines
7.9 KiB
C++
254 lines
7.9 KiB
C++
#include "game_logo.h"
|
|
#include <SDL3/SDL_surface.h> // Para SDL_FlipMode
|
|
#include <algorithm> // Para max
|
|
#include "animated_sprite.h" // Para AnimatedSprite
|
|
#include "audio.h" // Para JA_PlaySound
|
|
#include "param.h" // Para Param, param, ParamGame, ParamTitle
|
|
#include "resource.h" // Para Resource
|
|
#include "screen.h" // Para Screen
|
|
#include "smart_sprite.h" // Para SmartSprite
|
|
#include "sprite.h" // Para Sprite
|
|
#include "texture.h" // Para Texture
|
|
#include "utils.h" // Para Color
|
|
|
|
constexpr int ZOOM_FACTOR = 5;
|
|
constexpr int FLASH_DELAY = 3;
|
|
constexpr int FLASH_LENGHT = FLASH_DELAY + 3;
|
|
|
|
// Constructor
|
|
GameLogo::GameLogo(int x, int y)
|
|
: dust_texture_(Resource::get()->getTexture("title_dust.png")),
|
|
coffee_texture_(Resource::get()->getTexture("title_coffee.png")),
|
|
crisis_texture_(Resource::get()->getTexture("title_crisis.png")),
|
|
arcade_edition_texture_(Resource::get()->getTexture("title_arcade_edition.png")),
|
|
dust_left_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
|
|
dust_right_sprite_(std::make_unique<AnimatedSprite>(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))),
|
|
coffee_sprite_(std::make_unique<SmartSprite>(coffee_texture_)),
|
|
crisis_sprite_(std::make_unique<SmartSprite>(crisis_texture_)),
|
|
arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())),
|
|
x_(x),
|
|
y_(y) {}
|
|
|
|
// Inicializa las variables
|
|
void GameLogo::init()
|
|
{
|
|
const auto xp = x_ - coffee_texture_->getWidth() / 2;
|
|
const auto desp = getInitialVerticalDesp();
|
|
|
|
// Variables
|
|
coffee_crisis_status_ = Status::DISABLED;
|
|
arcade_edition_status_ = Status::DISABLED;
|
|
shake_.init(1, 2, 8, xp);
|
|
zoom_ = 3.0f * ZOOM_FACTOR;
|
|
|
|
// Inicializa el bitmap de 'Coffee'
|
|
coffee_sprite_->setPosX(xp);
|
|
coffee_sprite_->setPosY(y_ - coffee_texture_->getHeight() - desp);
|
|
coffee_sprite_->setWidth(coffee_texture_->getWidth());
|
|
coffee_sprite_->setHeight(coffee_texture_->getHeight());
|
|
coffee_sprite_->setVelX(0.0f);
|
|
coffee_sprite_->setVelY(2.5f);
|
|
coffee_sprite_->setAccelX(0.0f);
|
|
coffee_sprite_->setAccelY(0.1f);
|
|
coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight());
|
|
coffee_sprite_->setEnabled(true);
|
|
coffee_sprite_->setFinishedCounter(0);
|
|
coffee_sprite_->setDestX(xp);
|
|
coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight());
|
|
|
|
// Inicializa el bitmap de 'Crisis'
|
|
crisis_sprite_->setPosX(xp + 15);
|
|
crisis_sprite_->setPosY(y_ + desp);
|
|
crisis_sprite_->setWidth(crisis_texture_->getWidth());
|
|
crisis_sprite_->setHeight(crisis_texture_->getHeight());
|
|
crisis_sprite_->setVelX(0.0f);
|
|
crisis_sprite_->setVelY(-2.5f);
|
|
crisis_sprite_->setAccelX(0.0f);
|
|
crisis_sprite_->setAccelY(-0.1f);
|
|
crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight());
|
|
crisis_sprite_->setEnabled(true);
|
|
crisis_sprite_->setFinishedCounter(0);
|
|
crisis_sprite_->setDestX(xp + 15);
|
|
crisis_sprite_->setDestY(y_);
|
|
|
|
// Inicializa el bitmap de 'DustRight'
|
|
dust_right_sprite_->resetAnimation();
|
|
dust_right_sprite_->setPosX(coffee_sprite_->getPosX() + coffee_sprite_->getWidth());
|
|
dust_right_sprite_->setPosY(y_);
|
|
dust_right_sprite_->setWidth(16);
|
|
dust_right_sprite_->setHeight(16);
|
|
dust_right_sprite_->setFlip(SDL_FLIP_HORIZONTAL);
|
|
|
|
// Inicializa el bitmap de 'DustLeft'
|
|
dust_left_sprite_->resetAnimation();
|
|
dust_left_sprite_->setPosX(coffee_sprite_->getPosX() - 16);
|
|
dust_left_sprite_->setPosY(y_);
|
|
dust_left_sprite_->setWidth(16);
|
|
dust_left_sprite_->setHeight(16);
|
|
|
|
// Inicializa el bitmap de 'Arcade Edition'
|
|
arcade_edition_sprite_->setZoom(zoom_);
|
|
}
|
|
|
|
// Pinta la clase en pantalla
|
|
void GameLogo::render()
|
|
{
|
|
// Dibuja el logo
|
|
coffee_sprite_->render();
|
|
crisis_sprite_->render();
|
|
|
|
if (arcade_edition_status_ != Status::DISABLED)
|
|
{
|
|
arcade_edition_sprite_->render();
|
|
}
|
|
|
|
// Dibuja el polvillo del logo
|
|
dust_right_sprite_->render();
|
|
dust_left_sprite_->render();
|
|
}
|
|
|
|
// Actualiza la lógica de la clase
|
|
void GameLogo::update()
|
|
{
|
|
switch (coffee_crisis_status_)
|
|
{
|
|
case Status::MOVING:
|
|
{
|
|
coffee_sprite_->update();
|
|
crisis_sprite_->update();
|
|
|
|
// Si los objetos han llegado a su destino, cambia el estado
|
|
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished())
|
|
{
|
|
coffee_crisis_status_ = Status::SHAKING;
|
|
|
|
// Reproduce el efecto sonoro
|
|
Audio::get()->playSound("title.wav");
|
|
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY);
|
|
Screen::get()->shake();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case Status::SHAKING:
|
|
{
|
|
// Agita "COFFEE CRISIS"
|
|
if (shake_.remaining > 0)
|
|
{
|
|
if (shake_.counter > 0)
|
|
{
|
|
shake_.counter--;
|
|
}
|
|
else
|
|
{
|
|
shake_.counter = shake_.delay;
|
|
const auto desp = shake_.remaining % 2 == 0 ? shake_.desp * (-1) : shake_.desp;
|
|
coffee_sprite_->setPosX(shake_.origin + desp);
|
|
crisis_sprite_->setPosX(shake_.origin + desp + 15);
|
|
shake_.remaining--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
coffee_sprite_->setPosX(shake_.origin);
|
|
crisis_sprite_->setPosX(shake_.origin + 15);
|
|
coffee_crisis_status_ = Status::FINISHED;
|
|
arcade_edition_status_ = Status::MOVING;
|
|
}
|
|
|
|
dust_right_sprite_->update();
|
|
dust_left_sprite_->update();
|
|
|
|
break;
|
|
}
|
|
|
|
case Status::FINISHED:
|
|
{
|
|
dust_right_sprite_->update();
|
|
dust_left_sprite_->update();
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (arcade_edition_status_)
|
|
{
|
|
case Status::MOVING:
|
|
{
|
|
zoom_ -= 0.1f * ZOOM_FACTOR;
|
|
arcade_edition_sprite_->setZoom(zoom_);
|
|
if (zoom_ <= 1.0f)
|
|
{
|
|
arcade_edition_status_ = Status::SHAKING;
|
|
zoom_ = 1.0f;
|
|
arcade_edition_sprite_->setZoom(zoom_);
|
|
shake_.init(1, 2, 8, arcade_edition_sprite_->getX());
|
|
Audio::get()->playSound("title.wav");
|
|
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY);
|
|
Screen::get()->shake();
|
|
}
|
|
break;
|
|
}
|
|
|
|
case Status::SHAKING:
|
|
{
|
|
// Agita "ARCADE EDITION"
|
|
if (shake_.remaining > 0)
|
|
{
|
|
if (shake_.counter > 0)
|
|
{
|
|
shake_.counter--;
|
|
}
|
|
else
|
|
{
|
|
shake_.counter = shake_.delay;
|
|
const auto desp = shake_.remaining % 2 == 0 ? shake_.desp * (-1) : shake_.desp;
|
|
arcade_edition_sprite_->setX(shake_.origin + desp);
|
|
shake_.remaining--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
arcade_edition_sprite_->setX(shake_.origin);
|
|
arcade_edition_status_ = Status::FINISHED;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (coffee_crisis_status_ == Status::FINISHED &&
|
|
arcade_edition_status_ == Status::FINISHED &&
|
|
post_finished_counter_ > 0)
|
|
{
|
|
--post_finished_counter_;
|
|
}
|
|
}
|
|
|
|
// Activa la clase
|
|
void GameLogo::enable()
|
|
{
|
|
init();
|
|
coffee_crisis_status_ = Status::MOVING;
|
|
}
|
|
|
|
// Indica si ha terminado la animación
|
|
bool GameLogo::hasFinished() const
|
|
{
|
|
return post_finished_counter_ == 0;
|
|
}
|
|
|
|
// Calcula el desplazamiento vertical inicial
|
|
int GameLogo::getInitialVerticalDesp()
|
|
{
|
|
const float OFFSET_UP = y_;
|
|
const float OFFSET_DOWN = param.game.height - y_;
|
|
|
|
return std::max(OFFSET_UP, OFFSET_DOWN);
|
|
} |