#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; }