Files
coffee_crisis_arcade_edition/source/background.cpp

216 lines
6.0 KiB
C++

#include "background.h"
// Constructor
Background::Background(SDL_Renderer *renderer, Screen *screen, Asset *asset, param_t *param)
{
// Copia los punteros
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
this->param = param;
// Inicializa variables
gradientNumber = 0;
alpha = 0;
cloudsSpeed = 0;
transition = 0;
counter = 0;
rect = {0, 0, param->gameWidth, param->gameHeight};
srcRect = {playArea.x, rect.h - playArea.h, playArea.w, playArea.h};
dstRect = {0, 0, playArea.w, playArea.h};
base = rect.h;
gradientRect[0] = {0, 0, rect.w, rect.h};
gradientRect[1] = {rect.w, 0, rect.w, rect.h};
gradientRect[2] = {0, rect.h, rect.w, rect.h};
gradientRect[3] = {rect.w, rect.h, rect.w, rect.h};
// Carga las texturas
buildingsTexture = new Texture(renderer, asset->get("game_buildings.png"));
cloudsTexture = new Texture(renderer, asset->get("game_clouds.png"));
grassTexture = new Texture(renderer, asset->get("game_grass.png"));
gradientsTexture = new Texture(renderer, asset->get("game_sky_colors.png"));
// Crea los sprites
const int cloudsHeight = base - 196;
clouds1A = new MovingSprite(0, cloudsHeight, rect.w, 52, -0.4f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer);
clouds1B = new MovingSprite(rect.w, cloudsHeight, rect.w, 52, -0.4f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer);
clouds2A = new MovingSprite(0, cloudsHeight + 57, rect.w, 32, -0.2f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer);
clouds2B = new MovingSprite(rect.w, cloudsHeight + 57, rect.w, 32, -0.2f, 0.0f, 0.0f, 0.0f, cloudsTexture, renderer);
buildingsSprite = new Sprite(0, 0, rect.w, 135, buildingsTexture, renderer);
gradientSprite = new Sprite(0, 0, rect.w, rect.h, gradientsTexture, renderer);
grassSprite = new Sprite(0, 0, 256, 6, grassTexture, renderer);
// Inicializa objetos
clouds1A->setSpriteClip(0, 0, cloudsTexture->getWidth(), 52);
clouds1B->setSpriteClip(0, 0, cloudsTexture->getWidth(), 52);
clouds2A->setSpriteClip(0, 52, cloudsTexture->getWidth(), 32);
clouds2B->setSpriteClip(0, 52, cloudsTexture->getWidth(), 32);
buildingsSprite->setPosY(base - buildingsSprite->getHeight());
grassSprite->setPosY(base - grassSprite->getHeight());
// Crea la textura para componer el fondo
canvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect.w, rect.h);
SDL_SetTextureBlendMode(canvas, SDL_BLENDMODE_BLEND);
}
// Destructor
Background::~Background()
{
buildingsTexture->unload();
delete buildingsTexture;
cloudsTexture->unload();
delete cloudsTexture;
grassTexture->unload();
delete grassTexture;
gradientsTexture->unload();
delete gradientsTexture;
delete clouds1A;
delete clouds1B;
delete clouds2A;
delete clouds2B;
delete buildingsSprite;
delete gradientSprite;
delete grassSprite;
SDL_DestroyTexture(canvas);
}
// Actualiza la lógica del objeto
void Background::update()
{
// Aplica la velocidad calculada a las nubes
clouds1A->setVelX(cloudsSpeed);
clouds1B->setVelX(cloudsSpeed);
clouds2A->setVelX(cloudsSpeed / 2);
clouds2B->setVelX(cloudsSpeed / 2);
// Mueve las nubes
clouds1A->move();
clouds1B->move();
clouds2A->move();
clouds2B->move();
// Calcula el offset de las nubes
if (clouds1A->getPosX() < -clouds1A->getWidth())
{
clouds1A->setPosX(clouds1A->getWidth());
}
if (clouds1B->getPosX() < -clouds1B->getWidth())
{
clouds1B->setPosX(clouds1B->getWidth());
}
if (clouds2A->getPosX() < -clouds2A->getWidth())
{
clouds2A->setPosX(clouds2A->getWidth());
}
if (clouds2B->getPosX() < -clouds2B->getWidth())
{
clouds2B->setPosX(clouds2B->getWidth());
}
// Calcula el frame de la hierba
grassSprite->setSpriteClip(0, (6 * (counter / 20 % 2)), 256, 6);
// Calcula el valor de alpha
alpha = std::max((255 - (int)(255 * transition)), 0);
// Incrementa el contador
counter++;
}
// Compone todos los elementos del fondo en la textura
void Background::fillCanvas()
{
// Cambia el destino del renderizador
SDL_Texture *temp = SDL_GetRenderTarget(renderer);
SDL_SetRenderTarget(renderer, canvas);
// Dibuja el gradiente 2
gradientSprite->setSpriteClip(gradientRect[(gradientNumber + 1) % 4]);
gradientsTexture->setAlpha(255);
gradientSprite->render();
// Dibuja el gradiente 1 con una opacidad cada vez menor
gradientSprite->setSpriteClip(gradientRect[gradientNumber]);
gradientsTexture->setAlpha(alpha);
gradientSprite->render();
// Dibuja las nubes
clouds1A->render();
clouds1B->render();
clouds2A->render();
clouds2B->render();
// Dibuja los edificios
buildingsSprite->render();
// Dibuja la hierba
//grassSprite->render();
// Deja el renderizador apuntando donde estaba
SDL_SetRenderTarget(renderer, temp);
}
// Dibuja el objeto
void Background::render()
{
fillCanvas();
SDL_RenderCopy(renderer, canvas, &srcRect, &dstRect);
}
// Vuelve a cargar las texturas
void Background::reloadTextures()
{
buildingsTexture->reLoad();
cloudsTexture->reLoad();
grassTexture->reLoad();
gradientsTexture->reLoad();
}
// Ajusta el valor de la variable
void Background::setCloudsSpeed(float value)
{
cloudsSpeed = value;
}
// Ajusta el valor de la variable
void Background::setGradientNumber(int value)
{
gradientNumber = value % 4;
}
// Ajusta el valor de la variable
void Background::setTransition(float value)
{
transition = value;
}
// Establece la posición del objeto
void Background::setPos(SDL_Rect rect)
{
dstRect = rect;
// Si cambian las medidas del destino, hay que cambiar las del origen para evitar deformar la imagen
srcRect.w = rect.w;
srcRect.h = rect.h;
}
// Ajusta el valor de la variable
void Background::setSrcDest(SDL_Rect value)
{
srcRect = value;
}
// Ajusta el valor de la variable
void Background::setDstDest(SDL_Rect value)
{
dstRect = value;
}