#include "game_logo.h" #include // Para SDL_FLIP_HORIZONTAL #include // Para max #include "animated_sprite.h" // Para AnimatedSprite #include "jail_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(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))), dust_right_sprite_(std::make_unique(dust_texture_, Resource::get()->getAnimation("title_dust.ani"))), coffee_sprite_(std::make_unique(coffee_texture_)), crisis_sprite_(std::make_unique(crisis_texture_)), arcade_edition_sprite_(std::make_unique(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 JA_PlaySound(Resource::get()->getSound("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()); JA_PlaySound(Resource::get()->getSound("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; } // Recarga las texturas void GameLogo::reLoad() { dust_texture_->reLoad(); coffee_texture_->reLoad(); crisis_texture_->reLoad(); arcade_edition_texture_->reLoad(); } // Calcula el desplazamiento vertical inicial int GameLogo::getInitialVerticalDesp() { auto desp_up = y_; auto desp_down = param.game.height - y_; return std::max(desp_up, desp_down); }