Files
coffee_crisis_opendingux_dev/source/balloon.cpp

644 lines
13 KiB
C++

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