#include "const.h" #include "balloon.h" // Constructor Balloon::Balloon() { mSprite = new AnimatedSprite(); init(0, 0, NO_KIND, BALLON_VELX_POSITIVE, 0, nullptr, nullptr); } // Destructor Balloon::~Balloon() { delete mSprite; } // Inicializador void Balloon::init(float x, int y, Uint8 kind, float velx, Uint16 creationtimer, LTexture *texture, SDL_Renderer *renderer) { const Uint8 NUM_FRAMES_BALLON = 10; const Uint8 NUM_FRAMES_BALLON_POP = 12; const Uint8 NUM_FRAMES_BALLON_BORN = 10; switch (kind) { case BALLOON_1: // Posición inicial mPosX = x; mPosY = y; // Alto y ancho del objeto mWidth = 8; mHeight = mWidth; // Inicializa los valores de velocidad y gravedad mVelX = velx; mVelY = 0; mMaxVelY = 3; mGravity = 0.09f; mDefaultVelY = 3; // Puntos que da el globo al ser destruido mScore = 50; // Amenaza que genera el globo mMenace = 1; // Establece los frames de cada animación for (Uint8 i = 0; i < NUM_FRAMES_BALLON; i++) { mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, 50, 21 + (37 * i), getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_BORN; i++) { mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, 50 + 58, 21 + (37 * i), getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_POP; i++) { mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, 50 + 58 + 58, 21 + (37 * i), getWidth(), getHeight()); } break; case BALLOON_2: // Posición inicial mPosX = x; mPosY = y; // Alto y ancho del objeto mWidth = 13; mHeight = mWidth; // Inicializa los valores de velocidad y gravedad mVelX = velx; mVelY = 0; mMaxVelY = 3; mGravity = 0.10f; mDefaultVelY = 4; // Puntos que da el globo al ser destruido mScore = 100; // Amenaza que genera el globo mMenace = 2; // Establece los frames de cada animación for (Uint8 i = 0; i < NUM_FRAMES_BALLON; i++) { mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, 37, 21 + (37 * i), getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_BORN; i++) { mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, 37 + 58, 21 + (37 * i), getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_POP; i++) { mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, 37 + 58 + 58, 21 + (37 * i), getWidth(), getHeight()); } break; case BALLOON_3: // Posición inicial mPosX = x; mPosY = y; // Alto y ancho del objeto mWidth = 21; mHeight = mWidth; // Inicializa los valores de velocidad y gravedad mVelX = velx; mVelY = 0; mMaxVelY = 3; mGravity = 0.10f; mDefaultVelY = 4.5; // Puntos que da el globo al ser destruido mScore = 200; // Amenaza que genera el globo mMenace = 4; // Establece los frames de cada animación for (Uint8 i = 0; i < NUM_FRAMES_BALLON; i++) { mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, 37, 37 * i, getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_BORN; i++) { mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, 37 + 58, 37 * i, getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_POP; i++) { mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, 37 + 58 + 58, 37 * i, getWidth(), getHeight()); } break; case BALLOON_4: // Posición inicial mPosX = x; mPosY = y; // Alto y ancho del objeto mWidth = 37; mHeight = mWidth; // Inicializa los valores de velocidad y gravedad mVelX = velx; mVelY = 0; mMaxVelY = 3; mGravity = 0.10f; mDefaultVelY = 5; // Puntos que da el globo al ser destruido mScore = 400; // Amenaza que genera el globo mMenace = 8; // Establece los frames de cada animación for (Uint8 i = 0; i < NUM_FRAMES_BALLON; i++) { mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, 0, 37 * i, getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_BORN; i++) { mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, 58, 37 * i, getWidth(), getHeight()); } for (Uint8 i = 0; i < NUM_FRAMES_BALLON_POP; i++) { mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, 58 + 58, 37 * i, getWidth(), getHeight()); } break; default: // Posición inicial mPosX = x; mPosY = y; // Alto y ancho del objeto mWidth = 0; mHeight = mWidth; // Inicializa los valores de velocidad y gravedad mVelX = velx; mVelY = 0; mMaxVelY = 0; mGravity = 0; mDefaultVelY = 0; // Puntos que da el globo al ser destruido mScore = 0; // Amenaza que genera el globo mMenace = 0; // Establece los frames de cada animación mSprite->setAnimationFrames(0, 0, 0, 0, getWidth(), getHeight()); mSprite->setAnimationFrames(1, 0, 0, 0, getWidth(), getHeight()); mSprite->setAnimationFrames(2, 0, 0, 0, getWidth(), getHeight()); break; } // Textura con los gráficos del sprite mSprite->setTexture(texture); // Renderizador mSprite->setRenderer(renderer); // Alto y ancho del sprite mSprite->setWidth(mWidth); mSprite->setHeight(mHeight); // Posición X,Y del sprite mSprite->setPosX(int(mPosX)); mSprite->setPosY(mPosY); // Tamaño del circulo de colisión mCollider.r = mWidth / 2; // Alinea el circulo de colisión con el objeto shiftColliders(); // Inicializa variables mStopped = true; mStoppedTimer = 0; mBlinking = false; mVisible = true; mInvulnerable = false; mBeingCreated = true; mCreationTimer = creationtimer; mPopping = false; // Tipo mKind = kind; // Inicializa las variables para la animación mSprite->setCurrentFrame(0); mSprite->setAnimationCounter(0); // Establece el numero de frames de cada animacion mSprite->setAnimationNumFrames(BALLOON_MOVING_ANIMATION, NUM_FRAMES_BALLON); mSprite->setAnimationNumFrames(BALLOON_POP_ANIMATION, NUM_FRAMES_BALLON_POP); mSprite->setAnimationNumFrames(BALLOON_BORN_ANIMATION, NUM_FRAMES_BALLON_BORN); // Establece la velocidad de cada animación mSprite->setAnimationSpeed(BALLOON_MOVING_ANIMATION, 10); mSprite->setAnimationSpeed(BALLOON_POP_ANIMATION, 5); mSprite->setAnimationSpeed(BALLOON_BORN_ANIMATION, 20); // Establece si la animación se reproduce en bucle mSprite->setAnimationLoop(BALLOON_MOVING_ANIMATION, true); mSprite->setAnimationLoop(BALLOON_POP_ANIMATION, false); mSprite->setAnimationLoop(BALLOON_BORN_ANIMATION, true); // Selecciona un frame para pintar mSprite->setSpriteClip(mSprite->getAnimationClip(0, 0)); } // Centra el globo en la posición X void Balloon::allignTo(int x) { mPosX = float(x - (mWidth / 2)); if (mPosX < PLAY_AREA_LEFT) { mPosX = PLAY_AREA_LEFT + 1; } else if ((mPosX + mWidth) > PLAY_AREA_RIGHT) { mPosX = float(PLAY_AREA_RIGHT - mWidth - 1); } // Posición X,Y del sprite mSprite->setPosX(getPosX()); mSprite->setPosY(getPosY()); // Alinea el circulo de colisión con el objeto shiftColliders(); } // Pinta el globo en la pantalla void Balloon::render() { if (mVisible) { mSprite->render(); } } // Actualiza la posición y estados del globo void Balloon::move() { // Comprobamos si se puede mover if (isStopped() == false) { // Lo movemos a izquierda o derecha mPosX += mVelX; // Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido if ((mPosX < PLAY_AREA_LEFT) || (mPosX + mWidth > PLAY_AREA_RIGHT)) { // Corregir posición mPosX -= mVelX; // Invertir sentido mVelX = -mVelX; } // Mueve el globo hacia arriba o hacia abajo mPosY += int(mVelY); // Si se sale por arriba if (mPosY < PLAY_AREA_TOP) { // Corregimos mPosY -= int(mVelY); // Invertimos sentido mVelY = -mVelY; } // Si el globo se sale por la parte inferior if (mPosY + mHeight > PLAY_AREA_BOTTOM) { // Corregimos mPosY -= int(mVelY); // Invertimos colocando una velocidad por defecto mVelY = -mDefaultVelY; } // Aplica gravedad al objeto, sin pasarse de un limite establecido if (int(mVelY) > mMaxVelY) { mVelY = float(mMaxVelY); } else { mVelY += mGravity; } // Actualiza la posición del sprite mSprite->setPosX(getPosX()); mSprite->setPosY(mPosY); } // Si no se puede mover: // Comprobar si se está creando else if (isBeingCreated() == true) { // Actualiza el valor de las variables setStop(true); setInvulnerable(true); // Todavia tiene tiempo en el contador if (mCreationTimer > 0) { // Desplaza lentamente el globo hacia abajo y hacia un lado if (mCreationTimer % 10 == 0) { ++mPosY; mPosX += mVelX; // Actualiza la posición del sprite mSprite->setPosX(getPosX()); mSprite->setPosY(mPosY); // Actualiza la posición del circulo de colisión shiftColliders(); } // Hace visible el globo de forma intermitente if (mCreationTimer > 100) { setVisible(mCreationTimer / 10 % 2 == 0); } else { setVisible(mCreationTimer / 5 % 2 == 0); } --mCreationTimer; } // El contador ha llegado a cero else { setBeingCreated(false); setStop(false); setVisible(true); setInvulnerable(false); } } // Comprobar si está detenido else if (isStopped() == true) { // Si todavía está detenido, reduce el contador if (mStoppedTimer > 0) { --mStoppedTimer; } // Si el contador ha llegado a cero, ya no está detenido else { setStop(false); } } } // Pone a cero todos los valores del globo void Balloon::erase() { init(0, 0, NO_KIND, 0, 0, nullptr, nullptr); } // Explosiona el globo void Balloon::pop() { setPopping(true); mSprite->setAnimationCounter(0); setTimeToLive(120); setStop(true); setStoppedTimer(2000); setInvulnerable(true); mMenace = 0; } // Actualiza al globo a su posicion, animación y controla los contadores void Balloon::update() { move(); setAnimation(); shiftColliders(); if (isPopping()) { setInvulnerable(true); setStop(true); if (mTimeToLive > 0) { --mTimeToLive; } else { erase(); } } } // Establece la animación correspondiente al estado void Balloon::setAnimation() { // Establece el frame de animación if (isPopping()) { mSprite->animate(BALLOON_POP_ANIMATION); } else if (isBeingCreated()) { mSprite->animate(BALLOON_BORN_ANIMATION); } else { mSprite->animate(BALLOON_MOVING_ANIMATION); } } // Comprueba si el globo tiene algun tipo asignado bool Balloon::isActive() { if (mKind == NO_KIND) { return false; } else { return true; } } // Obtiene del valor de la variable int Balloon::getPosX() { return int(mPosX); } // Obtiene del valor de la variable int Balloon::getPosY() { return mPosY; } // Obtiene del valor de la variable float Balloon::getVelY() { return mVelY; } // Obtiene del valor de la variable int Balloon::getWidth() { return mWidth; } // Obtiene del valor de la variable int Balloon::getHeight() { return mHeight; } // Establece el valor de la variable void Balloon::setVelY(float velY) { mVelY = velY; } // Obtiene del valor de la variable int Balloon::getKind() { return mKind; } // Establece el valor de la variable void Balloon::setStop(bool state) { mStopped = state; } // Obtiene del valor de la variable bool Balloon::isStopped() { return mStopped; } // Establece el valor de la variable void Balloon::setBlink(bool state) { mBlinking = state; } // Obtiene del valor de la variable bool Balloon::isBlinking() { return mBlinking; } // Establece el valor de la variable void Balloon::setVisible(bool state) { mVisible = state; } // Obtiene del valor de la variable bool Balloon::isVisible() { return mVisible; } // Establece el valor de la variable void Balloon::setInvulnerable(bool state) { mInvulnerable = state; } // Obtiene del valor de la variable bool Balloon::isInvulnerable() { return mInvulnerable; } // Establece el valor de la variable void Balloon::setBeingCreated(bool state) { mBeingCreated = state; } // Obtiene del valor de la variable bool Balloon::isBeingCreated() { return mBeingCreated; } // Establece el valor de la variable void Balloon::setPopping(bool state) { mPopping = state; } // Obtiene del valor de la variable bool Balloon::isPopping() { return mPopping; } // Establece el valor de la variable void Balloon::setTimeToLive(Uint16 time) { mTimeToLive = time; } // Obtiene del valor de la variable Uint16 Balloon::getTimeToLive() { return mTimeToLive; } // Establece el valor de la variable void Balloon::setStoppedTimer(Uint16 time) { mStoppedTimer = time; } // Obtiene del valor de la variable Uint16 Balloon::getStoppedTimer() { return mStoppedTimer; } // Obtiene del valor de la variable Uint16 Balloon::getScore() { return mScore; } // Obtiene el circulo de colisión Circle &Balloon::getCollider() { return mCollider; } // Alinea el circulo de colisión con la posición del objeto globo void Balloon::shiftColliders() { // Align collider to center of balloon mCollider.x = Uint16(mPosX + mCollider.r); mCollider.y = mPosY + mCollider.r; } // Obtiene le valor de la variable Uint8 Balloon::getMenace() { return mMenace; }