Files
coffee-crisis/source/game/scenes/intro.cpp
T

401 lines
11 KiB
C++

#include "game/scenes/intro.h"
#include <SDL3/SDL.h>
#include <string> // for basic_string
#include "core/audio/audio.hpp" // for Audio::get, Audio::update
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
#include "core/input/input.h" // for Input, Input::Repeat::OFF, InputAction
#include "core/locale/lang.h" // for Lang
#include "core/rendering/screen.h" // for Screen
#include "core/rendering/smartsprite.h" // for SmartSprite
#include "core/rendering/writer.h" // for Writer
#include "core/resources/resource.h"
#include "game/defaults.hpp" // for GAMECANVAS_CENTER_X, GAMECANVAS_FIRST_QU...
#include "utils/utils.h" // for Section, Color
// Constructor
Intro::Intro(SDL_Renderer *renderer, Section *section) {
// Copia los punteros
this->renderer_ = renderer;
this->section_ = section;
// Reserva memoria para los objetos
event_handler_ = new SDL_Event();
texture_ = Resource::get()->getTexture("intro.png");
text_ = Resource::get()->getText("nokia");
music_ = Resource::get()->getMusic("intro.ogg");
// Inicializa variables
section->name = SECTION_PROG_INTRO;
section->subsection = 0;
ticks_ = 0;
ticks_speed_ = 15;
scene_ = 1;
// Inicializa los bitmaps de la intro
const int TOTAL_BITMAPS = 6;
for (int i = 0; i < TOTAL_BITMAPS; ++i) {
auto *ss = new SmartSprite(texture_, renderer);
ss->setWidth(128);
ss->setHeight(96);
ss->setEnabledCounter(20);
ss->setDestX(GAMECANVAS_CENTER_X - 64);
ss->setDestY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps_.push_back(ss);
}
bitmaps_[0]->setPosX(-128);
bitmaps_[0]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps_[0]->setVelX(0.0F);
bitmaps_[0]->setVelY(0.0F);
bitmaps_[0]->setAccelX(0.6F);
bitmaps_[0]->setAccelY(0.0F);
bitmaps_[0]->setSpriteClip(0, 0, 128, 96);
bitmaps_[1]->setPosX(GAMECANVAS_WIDTH);
bitmaps_[1]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps_[1]->setVelX(-1.0F);
bitmaps_[1]->setVelY(0.0F);
bitmaps_[1]->setAccelX(-0.3F);
bitmaps_[1]->setAccelY(0.0F);
bitmaps_[1]->setSpriteClip(128, 0, 128, 96);
bitmaps_[2]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps_[2]->setPosY(-96);
bitmaps_[2]->setVelX(0.0F);
bitmaps_[2]->setVelY(3.0F);
bitmaps_[2]->setAccelX(0.1F);
bitmaps_[2]->setAccelY(0.3F);
bitmaps_[2]->setSpriteClip(0, 96, 128, 96);
bitmaps_[2]->setEnabledCounter(250);
bitmaps_[3]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps_[3]->setPosY(GAMECANVAS_HEIGHT);
bitmaps_[3]->setVelX(0.0F);
bitmaps_[3]->setVelY(-0.7F);
bitmaps_[3]->setAccelX(0.0F);
bitmaps_[3]->setAccelY(0.0F);
bitmaps_[3]->setSpriteClip(128, 96, 128, 96);
bitmaps_[4]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps_[4]->setPosY(-96);
bitmaps_[4]->setVelX(0.0F);
bitmaps_[4]->setVelY(3.0F);
bitmaps_[4]->setAccelX(0.1F);
bitmaps_[4]->setAccelY(0.3F);
bitmaps_[4]->setSpriteClip(0, 192, 128, 96);
bitmaps_[5]->setPosX(GAMECANVAS_WIDTH);
bitmaps_[5]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps_[5]->setVelX(-0.7F);
bitmaps_[5]->setVelY(0.0F);
bitmaps_[5]->setAccelX(0.0F);
bitmaps_[5]->setAccelY(0.0F);
bitmaps_[5]->setSpriteClip(128, 192, 128, 96);
// Inicializa los textos de la intro
const int TOTAL_TEXTS = 9;
for (int i = 0; i < TOTAL_TEXTS; ++i) {
auto *w = new Writer(text_);
w->setPosX(BLOCK * 0);
w->setPosY(GAMECANVAS_HEIGHT - (BLOCK * 6));
w->setKerning(-1);
w->setEnabled(false);
w->setEnabledCounter(180);
texts_.push_back(w);
}
// Un dia qualsevol de l'any 2000
texts_[0]->setCaption(Lang::get()->getText(27));
texts_[0]->setSpeed(8);
// Tot esta tranquil a la UPV
texts_[1]->setCaption(Lang::get()->getText(28));
texts_[1]->setSpeed(8);
// Fins que un desaprensiu...
texts_[2]->setCaption(Lang::get()->getText(29));
texts_[2]->setSpeed(12);
// HEY! ME ANE A FERME UN CORTAET...
texts_[3]->setCaption(Lang::get()->getText(30));
texts_[3]->setSpeed(8);
// UAAAAAAAAAAAAA!!!
texts_[4]->setCaption(Lang::get()->getText(31));
texts_[4]->setSpeed(1);
// Espera un moment...
texts_[5]->setCaption(Lang::get()->getText(32));
texts_[5]->setSpeed(16);
// Si resulta que no tinc solt!
texts_[6]->setCaption(Lang::get()->getText(33));
texts_[6]->setSpeed(2);
// MERDA DE MAQUINA!
texts_[7]->setCaption(Lang::get()->getText(34));
texts_[7]->setSpeed(3);
// Blop... blop... blop...
texts_[8]->setCaption(Lang::get()->getText(35));
texts_[8]->setSpeed(16);
for (auto *t : texts_) {
t->center(GAMECANVAS_CENTER_X);
}
Audio::get()->playMusic(music_, 0);
}
// Destructor
Intro::~Intro() {
delete event_handler_;
// texture, text, music son propiedad de Resource — no liberar aquí.
for (auto *bitmap : bitmaps_) {
delete bitmap;
}
for (auto *t : texts_) {
delete t;
}
}
// Comprueba las entradas
void Intro::checkInput() {
#ifndef __EMSCRIPTEN__
if (Input::get()->checkInput(EXIT, Input::Repeat::OFF)) {
section_->name = SECTION_PROG_QUIT;
return;
}
#endif
if (GlobalInputs::handle()) { return; }
if (Input::get()->checkInput(PAUSE, Input::Repeat::OFF) || Input::get()->checkInput(ACCEPT, Input::Repeat::OFF) || Input::get()->checkInput(FIRE_LEFT, Input::Repeat::OFF) || Input::get()->checkInput(FIRE_CENTER, Input::Repeat::OFF) || Input::get()->checkInput(FIRE_RIGHT, Input::Repeat::OFF)) {
Audio::get()->stopMusic();
section_->name = SECTION_PROG_TITLE;
section_->subsection = SUBSECTION_TITLE_1;
}
}
// Actualiza las escenas de la intro
void Intro::updateScenes() {
switch (scene_) {
case 1:
updateScene1();
break;
case 2:
updateScene2();
break;
case 3:
updateScene3();
break;
case 4:
updateScene4();
break;
case 5:
updateScene5();
break;
case 6:
updateScene6();
break;
default:
break;
}
}
// Primera escena - UPV
void Intro::updateScene1() {
// Primera imagen - UPV
if (!bitmaps_[0]->hasFinished()) {
bitmaps_[0]->setEnabled(true);
}
// Primer texto de la primera imagen
if (bitmaps_[0]->hasFinished() && !texts_[0]->hasFinished()) {
texts_[0]->setEnabled(true);
}
// Segundo texto de la primera imagen
if (texts_[0]->hasFinished() && !texts_[1]->hasFinished()) {
texts_[0]->setEnabled(false);
texts_[1]->setEnabled(true);
}
// Tercer texto de la primera imagen
if (texts_[1]->hasFinished() && !texts_[2]->hasFinished()) {
texts_[1]->setEnabled(false);
texts_[2]->setEnabled(true);
}
// Fin de la primera escena
if (texts_[2]->hasFinished()) {
bitmaps_[0]->setEnabled(false);
texts_[2]->setEnabled(false);
scene_++;
}
}
// Segunda escena - Máquina
void Intro::updateScene2() {
// Segunda imagen - Máquina
if (!bitmaps_[1]->hasFinished()) {
bitmaps_[1]->setEnabled(true);
}
// Primer texto de la segunda imagen
if (bitmaps_[1]->hasFinished() && !texts_[3]->hasFinished()) {
texts_[3]->setEnabled(true);
}
// Fin de la segunda escena
if (texts_[3]->hasFinished()) {
bitmaps_[1]->setEnabled(false);
texts_[3]->setEnabled(false);
scene_++;
}
}
// Tercera escena - GRITO
void Intro::updateScene3() {
// Tercera imagen junto con primer texto - GRITO
if (!bitmaps_[2]->hasFinished() && !texts_[4]->hasFinished()) {
bitmaps_[2]->setEnabled(true);
texts_[4]->setEnabled(true);
}
// Fin de la tercera escena
if (bitmaps_[2]->hasFinished() && texts_[4]->hasFinished()) {
bitmaps_[2]->setEnabled(false);
texts_[4]->setEnabled(false);
scene_++;
}
}
// Cuarta escena - Reflexión
void Intro::updateScene4() {
// Cuarta imagen junto con primer texto - Reflexión
if (!bitmaps_[3]->hasFinished() && !texts_[5]->hasFinished()) {
bitmaps_[3]->setEnabled(true);
texts_[5]->setEnabled(true);
}
// Segundo texto de la cuarta imagen
if (texts_[5]->hasFinished() && !texts_[6]->hasFinished()) {
texts_[5]->setEnabled(false);
texts_[6]->setEnabled(true);
}
// Fin de la cuarta escena
if (bitmaps_[3]->hasFinished() && texts_[6]->hasFinished()) {
bitmaps_[3]->setEnabled(false);
texts_[6]->setEnabled(false);
scene_++;
}
}
// Quinta escena - Patada
void Intro::updateScene5() {
// Quinta imagen - Patada
if (!bitmaps_[4]->hasFinished()) {
bitmaps_[4]->setEnabled(true);
}
// Primer texto de la quinta imagen
if (bitmaps_[4]->hasFinished() && !texts_[7]->hasFinished()) {
texts_[7]->setEnabled(true);
}
// Fin de la quinta escena
if (bitmaps_[4]->hasFinished() && texts_[7]->hasFinished()) {
bitmaps_[4]->setEnabled(false);
texts_[7]->setEnabled(false);
scene_++;
}
}
// Sexta escena - Globos de café
void Intro::updateScene6() {
// Sexta imagen junto con texto - Globos de café
if (!bitmaps_[5]->hasFinished() && !texts_[8]->hasFinished()) {
bitmaps_[5]->setEnabled(true);
texts_[8]->setEnabled(true);
}
// Acaba el último texto
if (bitmaps_[5]->hasFinished() && texts_[8]->hasFinished()) {
bitmaps_[5]->setEnabled(false);
texts_[8]->setEnabled(false);
Audio::get()->stopMusic();
section_->name = SECTION_PROG_TITLE;
section_->subsection = SUBSECTION_TITLE_1;
}
}
// Actualiza las variables del objeto
void Intro::update() {
Audio::update();
checkInput();
if (SDL_GetTicks() - ticks_ > ticks_speed_) {
// Actualiza el contador de ticks
ticks_ = SDL_GetTicks();
// Actualiza los objetos
for (auto *bitmap : bitmaps_) {
bitmap->update();
}
for (auto *t : texts_) {
t->update();
}
// Actualiza las escenas de la intro
updateScenes();
}
}
// Dibuja el objeto en pantalla
void Intro::render() {
// Prepara para empezar a dibujar en la textura de juego
Screen::get()->start();
// Limpia la pantalla
Screen::get()->clean(BG_COLOR);
// Dibuja los objetos
for (auto *bitmap : bitmaps_) {
bitmap->render();
}
for (auto *t : texts_) {
t->render();
}
// Vuelca el contenido del renderizador en pantalla
Screen::get()->blit();
}
// Bucle principal
void Intro::run() {
Audio::get()->playMusic(music_, 0);
while (section_->name == SECTION_PROG_INTRO) {
iterate();
}
}
// Ejecuta un frame
void Intro::iterate() {
update();
render();
}
// Procesa un evento individual
void Intro::handleEvent(const SDL_Event *event) {
// SDL_EVENT_QUIT ya lo maneja Director
}