working on "How to play"

This commit is contained in:
2021-04-05 17:56:15 +02:00
parent d84137daa7
commit 36bb6b8fe8
16 changed files with 648 additions and 392 deletions

BIN
media/.DS_Store vendored

Binary file not shown.

View File

@@ -42,8 +42,7 @@ stage_change.wav
JailDoctor JailDoctor
menu_cancel.wav menu_cancel.wav
kenney_digitalaudio/lowRandom.ogg kenney_digitalaudio/pepSound1.ogg
kenney_digitalaudio/pepSound1.ogg <-
www.kenney.nl www.kenney.nl
bubble1.wav bubble1.wav
@@ -60,4 +59,7 @@ JailDoctor
clock.wav clock.wav
kenney_digitalaudio/switch2.ogg kenney_digitalaudio/switch2.ogg
www.kenney.nl www.kenney.nl
powerball.wav
JailDoctor

BIN
media/sound/powerball.wav Normal file

Binary file not shown.

View File

@@ -40,30 +40,29 @@ void AnimatedSprite::init(LTexture *texture, SDL_Renderer *renderer)
// Calcula el frame correspondiente a la animación // Calcula el frame correspondiente a la animación
void AnimatedSprite::animate(int index) void AnimatedSprite::animate(int index)
{ {
// Calculamos el frame actual a partir del contador if (mEnabled)
mCurrentFrame = mAnimationCounter / mAnimation[index].speed;
// Si alcanzamos el final de la animación, reiniciamos el contador de la animación
// en función de la variable loop
if (mCurrentFrame >= mAnimation[index].numFrames)
{ {
if (mAnimation[index].loop) // Calculamos el frame actual a partir del contador
mCurrentFrame = mAnimationCounter / mAnimation[index].speed;
// Si alcanzamos el final de la animación, reiniciamos el contador de la animación
// en función de la variable loop
if (mCurrentFrame >= mAnimation[index].numFrames)
{ {
mAnimationCounter = 0; if (mAnimation[index].loop)
mAnimationCounter = 0;
else
mCurrentFrame = mAnimation[index].numFrames;
} }
// En caso contrario
else else
{ {
mCurrentFrame = mAnimation[index].numFrames; // Escogemos el frame correspondiente de la animación
} setSpriteClip(mAnimation[index].frames[mCurrentFrame]);
}
// En caso contrario
else
{
// Escogemos el frame correspondiente de la animación
setSpriteClip(mAnimation[index].frames[mCurrentFrame]);
// Incrementamos el contador de la animacion // Incrementamos el contador de la animacion
++mAnimationCounter; mAnimationCounter++;
}
} }
} }

View File

@@ -34,8 +34,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_1; mWidth = BALLOON_WIDTH_1;
mHeight = BALLOON_SIZE_1; mHeight = BALLOON_WIDTH_1;
mSize = BALLOON_SIZE_1;
mPower = 1;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -45,7 +47,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = 2.6f; mDefaultVelY = 2.6f;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 50; mScore = BALLOON_SCORE_1;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 1; mMenace = 1;
@@ -66,8 +68,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_2; mWidth = BALLOON_WIDTH_2;
mHeight = BALLOON_SIZE_2; mHeight = BALLOON_WIDTH_2;
mSize = BALLOON_SIZE_2;
mPower = 3;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -77,7 +81,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = 3.5f; mDefaultVelY = 3.5f;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 100; mScore = BALLOON_SCORE_2;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 2; mMenace = 2;
@@ -98,8 +102,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_3; mWidth = BALLOON_WIDTH_3;
mHeight = BALLOON_SIZE_3; mHeight = BALLOON_WIDTH_3;
mSize = BALLOON_SIZE_3;
mPower = 7;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -109,7 +115,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = 4.50f; mDefaultVelY = 4.50f;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 200; mScore = BALLOON_SCORE_3;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 4; mMenace = 4;
@@ -130,8 +136,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_4; mWidth = BALLOON_WIDTH_4;
mHeight = BALLOON_SIZE_4; mHeight = BALLOON_WIDTH_4;
mSize = BALLOON_SIZE_4;
mPower = 15;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -141,7 +149,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = 4.95f; mDefaultVelY = 4.95f;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 400; mScore = BALLOON_SCORE_4;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 8; mMenace = 8;
@@ -162,8 +170,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_1; mWidth = BALLOON_WIDTH_1;
mHeight = BALLOON_SIZE_1; mHeight = BALLOON_WIDTH_1;
mSize = BALLOON_SIZE_1;
mPower = 1;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -173,7 +183,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = abs(velx) * 2; mDefaultVelY = abs(velx) * 2;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 50; mScore = BALLOON_SCORE_1;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 1; mMenace = 1;
@@ -194,8 +204,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_2; mWidth = BALLOON_WIDTH_2;
mHeight = BALLOON_SIZE_2; mHeight = BALLOON_WIDTH_2;
mSize = BALLOON_SIZE_2;
mPower = 3;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -205,7 +217,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = abs(velx) * 2; mDefaultVelY = abs(velx) * 2;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 100; mScore = BALLOON_SCORE_2;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 2; mMenace = 2;
@@ -226,8 +238,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_3; mWidth = BALLOON_WIDTH_3;
mHeight = BALLOON_SIZE_3; mHeight = BALLOON_WIDTH_3;
mSize = BALLOON_SIZE_3;
mPower = 7;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -237,7 +251,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = abs(velx) * 2; mDefaultVelY = abs(velx) * 2;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 200; mScore = BALLOON_SCORE_3;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 4; mMenace = 4;
@@ -258,8 +272,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_4; mWidth = BALLOON_WIDTH_4;
mHeight = BALLOON_SIZE_4; mHeight = BALLOON_WIDTH_4;
mSize = BALLOON_SIZE_4;
mPower = 15;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -269,7 +285,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mDefaultVelY = abs(velx) * 2; mDefaultVelY = abs(velx) * 2;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
mScore = 400; mScore = BALLOON_SCORE_4;
// Amenaza que genera el globo // Amenaza que genera el globo
mMenace = 8; mMenace = 8;
@@ -290,8 +306,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mEnabled = true; mEnabled = true;
// Alto y ancho del objeto // Alto y ancho del objeto
mWidth = BALLOON_SIZE_4; mWidth = BALLOON_WIDTH_4;
mHeight = BALLOON_SIZE_4; mHeight = BALLOON_WIDTH_4;
mSize = 4;
mPower = 0;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
mVelX = velx; mVelX = velx;
@@ -311,11 +329,15 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, OFFSET_POWER_BALL, 37 * i, getWidth(), getHeight()); mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, OFFSET_POWER_BALL, 37 * i, getWidth(), getHeight());
for (Uint8 i = 0; i < NUM_FRAMES_BALLON_BORN; i++) for (Uint8 i = 0; i < NUM_FRAMES_BALLON_BORN; i++)
mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, OFFSET_BLUE_BALLOONS, 37 * i, getWidth(), getHeight()); mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, OFFSET_POWER_BALL, 37 * i, getWidth(), getHeight());
for (Uint8 i = 0; i < NUM_FRAMES_BALLON_POP; i++) for (Uint8 i = 0; i < NUM_FRAMES_BALLON_POP; i++)
mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, OFFSET_EXPLOSIONS, 37 * i, getWidth(), getHeight()); mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, OFFSET_EXPLOSIONS, 37 * i, getWidth(), getHeight());
// Añade rotación al sprite
mSprite->setRotate(false);
mSprite->setRotateSpeed(1);
mSprite->setRotateAmount(2.0);
break; break;
default: default:
@@ -471,6 +493,9 @@ void Balloon::move()
// Invierte sentido // Invierte sentido
mVelX = -mVelX; mVelX = -mVelX;
// Invierte la rotación
mSprite->switchRotate();
// Activa el efecto de rebote // Activa el efecto de rebote
bounceStart(); bounceStart();
} }
@@ -539,33 +564,38 @@ void Balloon::move()
// Deshabilita el globo y pone a cero todos los valores // Deshabilita el globo y pone a cero todos los valores
void Balloon::disable() void Balloon::disable()
{ {
mEnabled = false;
mPosX = 0.0f;
mPosY = 0.0f;
mWidth = 0;
mHeight = 0;
mVelX = 0.0f;
mVelY = 0.0f;
mGravity = 0.0f;
mDefaultVelY = 0.0f;
mMaxVelY = 0.0f;
mBeingCreated = false; mBeingCreated = false;
mBlinking = false; mBlinking = false;
mInvulnerable = false; mCollider.r = 0;
mPopping = false;
mStopped = false;
mVisible = false;
mCollider.x = 0; mCollider.x = 0;
mCollider.y = 0; mCollider.y = 0;
mCollider.r = 0; mCounter = 0;
mCreationCounter = 0; mCreationCounter = 0;
mCreationCounterIni = 0; mCreationCounterIni = 0;
mDefaultVelY = 0.0f;
mEnabled = false;
mGravity = 0.0f;
mHeight = 0;
mInvulnerable = false;
mKind = 0;
mMaxVelY = 0.0f;
mMenace = 0;
mPopping = false;
mPosX = 0.0f;
mPosY = 0.0f;
mPower = 0;
mScore = 0; mScore = 0;
mSize = 0;
mSpeed = 0;
mStopped = false;
mStoppedCounter = 0; mStoppedCounter = 0;
mTimeToLive = 0; mTimeToLive = 0;
mKind = 0; mTravelY = 0;
mMenace = 0; mVelX = 0.0f;
mVelY = 0.0f;
mVisible = false;
mWidth = 0;
mSprite->clear();
} }
// Explosiona el globo // Explosiona el globo
@@ -585,6 +615,7 @@ void Balloon::update()
{ {
if (mEnabled) if (mEnabled)
{ {
mSprite->MovingSprite::update();
move(); move();
updateAnimation(); updateAnimation();
updateColliders(); updateColliders();
@@ -661,6 +692,14 @@ void Balloon::updateState()
setStop(false); setStop(false);
setVisible(true); setVisible(true);
setInvulnerable(false); setInvulnerable(false);
if (mKind == POWER_BALL)
{
mSprite->setRotate(true);
if (mVelX > 0.0f)
mSprite->setRotateAmount(2.0);
else
mSprite->setRotateAmount(-2.0);
}
} }
} }
// Solo comprueba el estado detenido cuando no se está creando // Solo comprueba el estado detenido cuando no se está creando
@@ -741,6 +780,12 @@ int Balloon::getKind()
return mKind; return mKind;
} }
// Obtiene del valor de la variable
Uint8 Balloon::getSize()
{
return mSize;
}
// Obtiene la clase a la que pertenece el globo // Obtiene la clase a la que pertenece el globo
Uint8 Balloon::getClass() Uint8 Balloon::getClass()
{ {
@@ -877,6 +922,12 @@ Uint8 Balloon::getMenace()
return 0; return 0;
} }
// Obtiene le valor de la variable
Uint8 Balloon::getPower()
{
return mPower;
}
void Balloon::bounceStart() void Balloon::bounceStart()
{ {
mBouncing.enabled = true; mBouncing.enabled = true;

View File

@@ -39,6 +39,8 @@ private:
Uint32 mCounter; // Contador interno Uint32 mCounter; // Contador interno
float mTravelY; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad float mTravelY; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad
float mSpeed; // Velocidad a la que se mueven los globos float mSpeed; // Velocidad a la que se mueven los globos
Uint8 mSize; // Tamaño del globo
Uint8 mPower; // Cantidad de poder que alberga el globo
struct bouncing // Estructura para las variables para el efecto de los rebotes struct bouncing // Estructura para las variables para el efecto de los rebotes
{ {
@@ -121,6 +123,9 @@ public:
// Obtiene del valor de la variable // Obtiene del valor de la variable
int getKind(); int getKind();
// Obtiene del valor de la variable
Uint8 getSize();
// Obtiene la clase a la que pertenece el globo // Obtiene la clase a la que pertenece el globo
Uint8 getClass(); Uint8 getClass();
@@ -171,6 +176,9 @@ public:
// Obtiene le valor de la variable // Obtiene le valor de la variable
Uint8 getMenace(); Uint8 getMenace();
// Obtiene le valor de la variable
Uint8 getPower();
}; };
#endif #endif

View File

@@ -7,7 +7,7 @@
// Textos // Textos
#define WINDOW_CAPTION "Coffee Crisis" #define WINDOW_CAPTION "Coffee Crisis"
#define TEXT_COPYRIGHT "@2020,2021 JAILDESIGNER (V1.4)" #define TEXT_COPYRIGHT "@2020,2021 JAILDESIGNER (V1.5)"
// Recursos // Recursos
#define BINFILE_SCORE 0 #define BINFILE_SCORE 0
@@ -39,8 +39,9 @@
#define SOUND_STAGE_CHANGE 14 #define SOUND_STAGE_CHANGE 14
#define SOUND_TITLE 15 #define SOUND_TITLE 15
#define SOUND_CLOCK 16 #define SOUND_CLOCK 16
#define SOUND_POWERBALL 17
#define TOTAL_SOUND 17 #define TOTAL_SOUND 18
#define TEXTURE_BALLOON 0 #define TEXTURE_BALLOON 0
#define TEXTURE_BULLET 1 #define TEXTURE_BULLET 1
@@ -151,6 +152,10 @@ const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
#define TITLE_SECTION_3 2 #define TITLE_SECTION_3 2
#define TITLE_SECTION_INSTRUCTIONS 3 #define TITLE_SECTION_INSTRUCTIONS 3
// Modos
#define MODE_AUTO 0
#define MODE_MANUAL 1
// Estados de cada elemento que pertenece a un evento // Estados de cada elemento que pertenece a un evento
#define EVENT_WAITING 1 #define EVENT_WAITING 1
#define EVENT_RUNNING 2 #define EVENT_RUNNING 2
@@ -211,6 +216,18 @@ const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
#define HEXAGON_4 8 #define HEXAGON_4 8
#define POWER_BALL 9 #define POWER_BALL 9
// Puntos de globo
#define BALLOON_SCORE_1 50
#define BALLOON_SCORE_2 100
#define BALLOON_SCORE_3 200
#define BALLOON_SCORE_4 400
// Tamaños de globo
#define BALLOON_SIZE_1 1
#define BALLOON_SIZE_2 2
#define BALLOON_SIZE_3 3
#define BALLOON_SIZE_4 4
// Clases de globo // Clases de globo
#define BALLOON_CLASS 0 #define BALLOON_CLASS 0
#define HEXAGON_CLASS 1 #define HEXAGON_CLASS 1
@@ -235,10 +252,10 @@ const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
#define BALLOON_SPEED_5 1.00f #define BALLOON_SPEED_5 1.00f
// Tamaño de los globos // Tamaño de los globos
#define BALLOON_SIZE_1 8 #define BALLOON_WIDTH_1 8
#define BALLOON_SIZE_2 13 #define BALLOON_WIDTH_2 13
#define BALLOON_SIZE_3 21 #define BALLOON_WIDTH_3 21
#define BALLOON_SIZE_4 37 #define BALLOON_WIDTH_4 37
// Tipos de bala // Tipos de bala
#define BULLET_UP 1 #define BULLET_UP 1

View File

@@ -180,7 +180,8 @@ void GameDirector::initProg()
// Inicializa el objeto con el menu del titulo // Inicializa el objeto con el menu del titulo
mMenu.title->init("TITLE", 0, 15 * BLOCK, MENU_BACKGROUND_SOLID, mTexture[TEXTURE_MENU].texture, mRenderer, mText.white); mMenu.title->init("TITLE", 0, 15 * BLOCK, MENU_BACKGROUND_SOLID, mTexture[TEXTURE_MENU].texture, mRenderer, mText.white);
mMenu.title->addItem("PLAY"); mMenu.title->addItem("PLAY");
mMenu.title->addItem("OPTIONS", 0, 5); mMenu.title->addItem("OPTIONS");
mMenu.title->addItem("HOW TO PLAY", 0, 5);
mMenu.title->addItem("QUIT"); mMenu.title->addItem("QUIT");
mMenu.title->setDefaultActionWhenCancel(2); mMenu.title->setDefaultActionWhenCancel(2);
mMenu.title->setBackgroundColor(0x30, 0x30, 0x40, 192); mMenu.title->setBackgroundColor(0x30, 0x30, 0x40, 192);
@@ -668,6 +669,13 @@ void GameDirector::initTitle(Uint8 subsection)
// Carga los recursos // Carga los recursos
loadMediaTitle(); loadMediaTitle();
// Inicializa las variables
resetTitle(subsection);
}
// Resetea las variables necesarias para la sección 'Title'
void GameDirector::resetTitle(Uint8 subsection)
{
// Inicializa variables // Inicializa variables
mTitle.section = subsection; mTitle.section = subsection;
mTitle.counter = TITLE_COUNTER; mTitle.counter = TITLE_COUNTER;
@@ -900,7 +908,7 @@ void GameDirector::resetGame()
mGame.remainingExplosions = REMAINING_EXPLOSIONS; mGame.remainingExplosions = REMAINING_EXPLOSIONS;
mGame.remainingExplosionsCounter = REMAINING_EXPLOSIONS_COUNTER; mGame.remainingExplosionsCounter = REMAINING_EXPLOSIONS_COUNTER;
mGame.timeStopped = false; mGame.timeStopped = false;
mGame.timeStoppedCounter = TIME_STOPPED_COUNTER; mGame.timeStoppedCounter = 0;
mGame.counter = 0; mGame.counter = 0;
mGame.balloonsPopped = 0; mGame.balloonsPopped = 0;
mGame.lastEnemyDeploy = 0; mGame.lastEnemyDeploy = 0;
@@ -909,6 +917,7 @@ void GameDirector::resetGame()
mGame.effect.flash = false; mGame.effect.flash = false;
mGame.effect.shake = false; mGame.effect.shake = false;
mGame.effect.shakeCounter = SHAKE_COUNTER; mGame.effect.shakeCounter = SHAKE_COUNTER;
mGame.powerBallEabled = false;
initGameStages(); initGameStages();
// Sprites // Sprites
@@ -1046,6 +1055,7 @@ bool GameDirector::loadMediaGame()
mSound[SOUND_BUBBLE3].sound = JA_LoadSound(mSound[SOUND_BUBBLE3].file.c_str()); mSound[SOUND_BUBBLE3].sound = JA_LoadSound(mSound[SOUND_BUBBLE3].file.c_str());
mSound[SOUND_BUBBLE4].sound = JA_LoadSound(mSound[SOUND_BUBBLE4].file.c_str()); mSound[SOUND_BUBBLE4].sound = JA_LoadSound(mSound[SOUND_BUBBLE4].file.c_str());
mSound[SOUND_CLOCK].sound = JA_LoadSound(mSound[SOUND_CLOCK].file.c_str()); mSound[SOUND_CLOCK].sound = JA_LoadSound(mSound[SOUND_CLOCK].file.c_str());
mSound[SOUND_POWERBALL].sound = JA_LoadSound(mSound[SOUND_POWERBALL].file.c_str());
// Musicas // Musicas
mMusic[MUSIC_PLAYING].music = JA_LoadMusic(mMusic[MUSIC_PLAYING].file.c_str()); mMusic[MUSIC_PLAYING].music = JA_LoadMusic(mMusic[MUSIC_PLAYING].file.c_str());
@@ -1081,6 +1091,7 @@ void GameDirector::quitGame()
JA_DeleteSound(mSound[SOUND_BUBBLE3].sound); JA_DeleteSound(mSound[SOUND_BUBBLE3].sound);
JA_DeleteSound(mSound[SOUND_BUBBLE4].sound); JA_DeleteSound(mSound[SOUND_BUBBLE4].sound);
JA_DeleteSound(mSound[SOUND_CLOCK].sound); JA_DeleteSound(mSound[SOUND_CLOCK].sound);
JA_DeleteSound(mSound[SOUND_POWERBALL].sound);
// Musicas // Musicas
JA_DeleteMusic(mMusic[MUSIC_PLAYING].music); JA_DeleteMusic(mMusic[MUSIC_PLAYING].music);
@@ -1189,6 +1200,7 @@ void GameDirector::setFileList()
mSound[SOUND_STAGE_CHANGE].file = mProg.executablePath + "/" + "../media/sound/stage_change.wav"; mSound[SOUND_STAGE_CHANGE].file = mProg.executablePath + "/" + "../media/sound/stage_change.wav";
mSound[SOUND_TITLE].file = mProg.executablePath + "/" + "../media/sound/title.wav"; mSound[SOUND_TITLE].file = mProg.executablePath + "/" + "../media/sound/title.wav";
mSound[SOUND_CLOCK].file = mProg.executablePath + "/" + "../media/sound/clock.wav"; mSound[SOUND_CLOCK].file = mProg.executablePath + "/" + "../media/sound/clock.wav";
mSound[SOUND_POWERBALL].file = mProg.executablePath + "/" + "../media/sound/powerball.wav";
// Texturas // Texturas
mTexture[TEXTURE_BALLOON].file = mProg.executablePath + "/" + "../media/gfx/balloon.png"; mTexture[TEXTURE_BALLOON].file = mProg.executablePath + "/" + "../media/gfx/balloon.png";
@@ -1577,23 +1589,23 @@ void GameDirector::initEnemyFormations()
{ {
const int y4 = (PLAY_AREA_TOP - BLOCK); const int y4 = (PLAY_AREA_TOP - BLOCK);
const int x4_0 = PLAY_AREA_LEFT; const int x4_0 = PLAY_AREA_LEFT;
//const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_4 / 2); //const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_4 / 2);
const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_4; const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_4;
const int y3 = (PLAY_AREA_TOP - BLOCK); const int y3 = (PLAY_AREA_TOP - BLOCK);
const int x3_0 = PLAY_AREA_LEFT; const int x3_0 = PLAY_AREA_LEFT;
//const int x3_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_3 / 2); //const int x3_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_3 / 2);
const int x3_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_3; const int x3_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_3;
const int y2 = (PLAY_AREA_TOP - BLOCK); const int y2 = (PLAY_AREA_TOP - BLOCK);
const int x2_0 = PLAY_AREA_LEFT; const int x2_0 = PLAY_AREA_LEFT;
//const int x2_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_2 / 2); //const int x2_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_2 / 2);
const int x2_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_2; const int x2_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_2;
const int y1 = (PLAY_AREA_TOP - BLOCK); const int y1 = (PLAY_AREA_TOP - BLOCK);
const int x1_0 = PLAY_AREA_LEFT; const int x1_0 = PLAY_AREA_LEFT;
const int x1_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_1 / 2); const int x1_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_1 / 2);
const int x1_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_1; const int x1_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_1;
const Uint16 creationTime = 300; const Uint16 creationTime = 300;
int incX = 0; int incX = 0;
@@ -1621,7 +1633,7 @@ void GameDirector::initEnemyFormations()
incTime = 0; incTime = 0;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
mEnemyFormation[j].init[i].x = PLAY_AREA_CENTER_FIRST_QUARTER_X - (BALLOON_SIZE_4 / 2) + (i * incX); mEnemyFormation[j].init[i].x = PLAY_AREA_CENTER_FIRST_QUARTER_X - (BALLOON_WIDTH_4 / 2) + (i * incX);
mEnemyFormation[j].init[i].y = y4; mEnemyFormation[j].init[i].y = y4;
mEnemyFormation[j].init[i].velX = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1); mEnemyFormation[j].init[i].velX = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1);
mEnemyFormation[j].init[i].kind = BALLOON_4; mEnemyFormation[j].init[i].kind = BALLOON_4;
@@ -1631,7 +1643,7 @@ void GameDirector::initEnemyFormations()
// #02 - Cuatro enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro // #02 - Cuatro enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro
j = 2; j = 2;
mEnemyFormation[j].numberOfEnemies = 4; mEnemyFormation[j].numberOfEnemies = 4;
incX = BALLOON_SIZE_2 + 1; incX = BALLOON_WIDTH_2 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1645,7 +1657,7 @@ void GameDirector::initEnemyFormations()
// #03 - Cuatro enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro // #03 - Cuatro enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro
j = 3; j = 3;
mEnemyFormation[j].numberOfEnemies = 4; mEnemyFormation[j].numberOfEnemies = 4;
incX = BALLOON_SIZE_2 + 1; incX = BALLOON_WIDTH_2 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1659,7 +1671,7 @@ void GameDirector::initEnemyFormations()
// #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha // #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha
j = 4; j = 4;
mEnemyFormation[j].numberOfEnemies = 3; mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 * 2; incX = BALLOON_WIDTH_3 * 2;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1673,7 +1685,7 @@ void GameDirector::initEnemyFormations()
// #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda // #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda
j = 5; j = 5;
mEnemyFormation[j].numberOfEnemies = 3; mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 * 2; incX = BALLOON_WIDTH_3 * 2;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1687,7 +1699,7 @@ void GameDirector::initEnemyFormations()
// #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha // #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha
j = 6; j = 6;
mEnemyFormation[j].numberOfEnemies = 3; mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 + 1; incX = BALLOON_WIDTH_3 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1701,7 +1713,7 @@ void GameDirector::initEnemyFormations()
// #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda // #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda
j = 7; j = 7;
mEnemyFormation[j].numberOfEnemies = 3; mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 + 1; incX = BALLOON_WIDTH_3 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1715,7 +1727,7 @@ void GameDirector::initEnemyFormations()
// #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha // #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha
j = 8; j = 8;
mEnemyFormation[j].numberOfEnemies = 6; mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_1 + 1; incX = BALLOON_WIDTH_1 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1729,7 +1741,7 @@ void GameDirector::initEnemyFormations()
// #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda // #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda
j = 9; j = 9;
mEnemyFormation[j].numberOfEnemies = 6; mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_1 + 1; incX = BALLOON_WIDTH_1 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1743,7 +1755,7 @@ void GameDirector::initEnemyFormations()
// #10 - Tres enemigos BALLOON4 seguidos desde la izquierda // #10 - Tres enemigos BALLOON4 seguidos desde la izquierda
j = 10; j = 10;
mEnemyFormation[j].numberOfEnemies = 3; mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_4 + 1; incX = BALLOON_WIDTH_4 + 1;
incTime = 15; incTime = 15;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1757,7 +1769,7 @@ void GameDirector::initEnemyFormations()
// #11 - Tres enemigos BALLOON4 seguidos desde la derecha // #11 - Tres enemigos BALLOON4 seguidos desde la derecha
j = 11; j = 11;
mEnemyFormation[j].numberOfEnemies = 3; mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_4 + 1; incX = BALLOON_WIDTH_4 + 1;
incTime = 15; incTime = 15;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1771,7 +1783,7 @@ void GameDirector::initEnemyFormations()
// #12 - Seis enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro // #12 - Seis enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro
j = 12; j = 12;
mEnemyFormation[j].numberOfEnemies = 6; mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_2 + 1; incX = BALLOON_WIDTH_2 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1785,7 +1797,7 @@ void GameDirector::initEnemyFormations()
// #13 - Seis enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro // #13 - Seis enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro
j = 13; j = 13;
mEnemyFormation[j].numberOfEnemies = 6; mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_2 + 1; incX = BALLOON_WIDTH_2 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1799,7 +1811,7 @@ void GameDirector::initEnemyFormations()
// #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados // #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados
j = 14; j = 14;
mEnemyFormation[j].numberOfEnemies = 5; mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 * 2; incX = BALLOON_WIDTH_3 * 2;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1813,7 +1825,7 @@ void GameDirector::initEnemyFormations()
// #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados // #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados
j = 15; j = 15;
mEnemyFormation[j].numberOfEnemies = 5; mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 * 2; incX = BALLOON_WIDTH_3 * 2;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1827,7 +1839,7 @@ void GameDirector::initEnemyFormations()
// #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos // #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos
j = 16; j = 16;
mEnemyFormation[j].numberOfEnemies = 5; mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 + 1; incX = BALLOON_WIDTH_3 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1841,7 +1853,7 @@ void GameDirector::initEnemyFormations()
// #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos // #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos
j = 17; j = 17;
mEnemyFormation[j].numberOfEnemies = 5; mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 + 1; incX = BALLOON_WIDTH_3 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1855,7 +1867,7 @@ void GameDirector::initEnemyFormations()
// #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos // #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos
j = 18; j = 18;
mEnemyFormation[j].numberOfEnemies = 12; mEnemyFormation[j].numberOfEnemies = 12;
incX = BALLOON_SIZE_1 + 1; incX = BALLOON_WIDTH_1 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1869,7 +1881,7 @@ void GameDirector::initEnemyFormations()
// #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos // #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos
j = 19; j = 19;
mEnemyFormation[j].numberOfEnemies = 12; mEnemyFormation[j].numberOfEnemies = 12;
incX = BALLOON_SIZE_1 + 1; incX = BALLOON_WIDTH_1 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1883,7 +1895,7 @@ void GameDirector::initEnemyFormations()
// #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos // #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos
j = 20; j = 20;
mEnemyFormation[j].numberOfEnemies = 4; mEnemyFormation[j].numberOfEnemies = 4;
incX = BALLOON_SIZE_4 + 1; incX = BALLOON_WIDTH_4 + 1;
incTime = 0; incTime = 0;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1906,7 +1918,7 @@ void GameDirector::initEnemyFormations()
// #21 - Diez enemigos BALLOON2 uno detras del otro. Izquierda/derecha. Simetricos // #21 - Diez enemigos BALLOON2 uno detras del otro. Izquierda/derecha. Simetricos
j = 21; j = 21;
mEnemyFormation[j].numberOfEnemies = 10; mEnemyFormation[j].numberOfEnemies = 10;
incX = BALLOON_SIZE_2 + 1; incX = BALLOON_WIDTH_2 + 1;
incTime = 3; incTime = 3;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1930,7 +1942,7 @@ void GameDirector::initEnemyFormations()
// #22 - Diez enemigos BALLOON3. Hacia la derecha/izquierda. Separados. Simetricos // #22 - Diez enemigos BALLOON3. Hacia la derecha/izquierda. Separados. Simetricos
j = 22; j = 22;
mEnemyFormation[j].numberOfEnemies = 10; mEnemyFormation[j].numberOfEnemies = 10;
incX = BALLOON_SIZE_3 * 2; incX = BALLOON_WIDTH_3 * 2;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -1954,7 +1966,7 @@ void GameDirector::initEnemyFormations()
// #23 - Diez enemigos BALLOON3. Hacia la derecha. Juntos. Simetricos // #23 - Diez enemigos BALLOON3. Hacia la derecha. Juntos. Simetricos
j = 23; j = 23;
mEnemyFormation[j].numberOfEnemies = 10; mEnemyFormation[j].numberOfEnemies = 10;
incX = BALLOON_SIZE_3 + 1; incX = BALLOON_WIDTH_3 + 1;
incTime = 10; incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -2002,7 +2014,7 @@ void GameDirector::initEnemyFormations()
// #25 - Treinta enemigos BALLOON1. Del centro hacia adentro. Juntos. Simetricos // #25 - Treinta enemigos BALLOON1. Del centro hacia adentro. Juntos. Simetricos
j = 25; j = 25;
mEnemyFormation[j].numberOfEnemies = 30; mEnemyFormation[j].numberOfEnemies = 30;
incX = BALLOON_SIZE_1 + 1; incX = BALLOON_WIDTH_1 + 1;
incTime = 5; incTime = 5;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{ {
@@ -2279,36 +2291,51 @@ void GameDirector::deployEnemyFormation()
// Solo despliega una formación enemiga si ha pasado cierto tiempo desde la última // Solo despliega una formación enemiga si ha pasado cierto tiempo desde la última
if (mGame.enemyDeployCounter == 0) if (mGame.enemyDeployCounter == 0)
{ {
mGame.enemyDeployCounter = 255;
Uint8 set = (rand() % 10); // En este punto se decide entre crear una powerball o una formación enemiga
if ((rand() % 100 < 15) && (canPowerBallBeCreated()))
if (set == mGame.lastEnemyDeploy)
{ {
set++; // Crea una powerball
set %= 10; createPowerBall();
mGame.enemyDeployCounter = 50;
} }
mGame.lastEnemyDeploy = set; else
{
if (mDebug.enabled) // Elige una formación enemiga la azar
set = mDebug.enemySet; Uint8 set = (rand() % 10);
Uint8 numEnemies = mGame.stage[mGame.currentStage].enemyPool->set[set]->numberOfEnemies; // Evita repetir la ultima formación enemiga desplegada
for (Uint8 i = 0; i < numEnemies; i++) if (set == mGame.lastEnemyDeploy)
createNewBalloon(mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].x, {
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].y, set++;
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].kind, set %= 10;
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].velX, }
mGame.enemySpeed, mGame.lastEnemyDeploy = set;
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].creationCounter,
mTexture[TEXTURE_BALLOON].texture); if (mDebug.enabled)
set = mDebug.enemySet;
Uint8 numEnemies = mGame.stage[mGame.currentStage].enemyPool->set[set]->numberOfEnemies;
for (Uint8 i = 0; i < numEnemies; i++)
createNewBalloon(mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].x,
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].y,
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].kind,
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].velX,
mGame.enemySpeed,
mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].creationCounter,
mTexture[TEXTURE_BALLOON].texture);
mGame.enemyDeployCounter = 255;
}
} }
} }
// Aumenta el poder de la fase // Aumenta el poder de la fase
void GameDirector::increaseStageCurrentPower() void GameDirector::increaseStageCurrentPower(Uint8 power)
{ {
mGame.stage[mGame.currentStage].currentPower++; mGame.stage[mGame.currentStage].currentPower += power;
} }
// Establece el valor de la variable // Establece el valor de la variable
@@ -2602,14 +2629,15 @@ Uint8 GameDirector::createNewBalloon(float x, int y, Uint8 kind, float velx, flo
// Crea una PowerBall // Crea una PowerBall
void GameDirector::createPowerBall() void GameDirector::createPowerBall()
{ {
const int y4 = (PLAY_AREA_TOP - BLOCK); const int posY = (PLAY_AREA_TOP);
const int x4_0 = PLAY_AREA_LEFT; const int left = PLAY_AREA_LEFT;
const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_4 / 2); const int center = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_4 / 2);
const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_4; const int right = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_4;
const int x[3] = {x4_0, x4_50, x4_100}; const int x[3] = {left, center, right};
int x4 = x[rand() % 3]; int posX = x[rand() % 3];
mGame.balloon[getBalloonFreeIndex()]->init(x4, y4, POWER_BALL, BALLOON_VELX_POSITIVE * (((rand() % 2) * 2) - 1), mGame.enemySpeed, 350, mTexture[TEXTURE_BALLOON].texture, mRenderer); mGame.balloon[getBalloonFreeIndex()]->init(posX, posY, POWER_BALL, BALLOON_VELX_POSITIVE * (((rand() % 2) * 2) - 1), mGame.enemySpeed, 100, mTexture[TEXTURE_BALLOON].texture, mRenderer);
mGame.powerBallEabled = true;
} }
// Establece a cero todos los valores del vector de objetos globo // Establece a cero todos los valores del vector de objetos globo
@@ -2688,88 +2716,115 @@ void GameDirector::updateBalloonSpeed()
// Explosiona un globo. Lo destruye y crea otros dos si es el caso // Explosiona un globo. Lo destruye y crea otros dos si es el caso
void GameDirector::popBalloon(Uint8 index) void GameDirector::popBalloon(Uint8 index)
{ {
//if (mGame.balloon[index]->isActive()) // Otorga los puntos correspondientes al globo
mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier()));
setScore(mGame.player->getScore());
updateHiScore();
// Aumenta el poder de la fase
increaseStageCurrentPower(1);
mGame.balloonsPopped++;
Uint8 kind = mGame.balloon[index]->getKind();
Uint8 freeIndex = 0;
switch (kind)
{ {
// Otorga los puntos correspondientes al globo // Si es del tipo más pequeño, simplemente elimina el globo
mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier())); case BALLOON_1:
setScore(mGame.player->getScore()); mGame.balloon[index]->pop();
updateHiScore(); break;
// Aumenta el poder de la fase case HEXAGON_1:
increaseStageCurrentPower(); mGame.balloon[index]->pop();
mGame.balloonsPopped++; break;
Uint8 kind = mGame.balloon[index]->getKind(); // Si es del tipo PowerBall, destruye todos los globos
Uint8 freeIndex = 0; case POWER_BALL:
switch (kind) destroyAllBalloons();
{ mGame.powerBallEabled = false;
// Si es del tipo más pequeño, simplemente elimina el globo break;
case BALLOON_1:
mGame.balloon[index]->pop();
break;
case HEXAGON_1: // En cualquier otro caso, crea dos globos de un tipo inferior
mGame.balloon[index]->pop(); default:
break; freeIndex = getBalloonFreeIndex();
mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_NEGATIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer);
mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2));
if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS)
mGame.balloon[freeIndex]->setVelY(-2.50f);
else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS)
mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE);
// Si es del tipo PowerBall, destruye todos los globos freeIndex = getBalloonFreeIndex();
case POWER_BALL: mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_POSITIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer);
destroyAllBalloons(); mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2));
break; if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS)
mGame.balloon[freeIndex]->setVelY(-2.50f);
else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS)
mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE);
// En cualquier otro caso, crea dos globos de un tipo inferior // Elimina el globo
default: mGame.balloon[index]->pop();
freeIndex = getBalloonFreeIndex(); break;
mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_NEGATIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer);
mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2));
if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS)
mGame.balloon[freeIndex]->setVelY(-2.50f);
else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS)
mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE);
freeIndex = getBalloonFreeIndex();
mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_POSITIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer);
mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2));
if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS)
mGame.balloon[freeIndex]->setVelY(-2.50f);
else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS)
mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE);
// Elimina el globo
mGame.balloon[index]->pop();
break;
}
// Recalcula el nivel de amenaza
setMenace();
} }
// Recalcula el nivel de amenaza
setMenace();
} }
// Explosiona un globo. Lo destruye // Explosiona un globo. Lo destruye
void GameDirector::destroyBalloon(Uint8 index) void GameDirector::destroyBalloon(Uint8 index)
{ {
//if (mGame.balloon[index]->isActive()) int score = 0;
Uint8 power = 0;
// Calcula la puntuación y el poder que generaria el globo en caso de romperlo a él y a sus hijos
switch (mGame.balloon[index]->getSize())
{ {
// Otorga los puntos correspondientes al globo case BALLOON_SIZE_4:
mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier())); score = BALLOON_SCORE_4 + (2 * BALLOON_SCORE_3) + (4 * BALLOON_SCORE_2) + (8 * BALLOON_SCORE_1);
setScore(mGame.player->getScore()); power = 15;
updateHiScore(); break;
// Aumenta el poder de la fase case BALLOON_SIZE_3:
increaseStageCurrentPower(); score = BALLOON_SCORE_3 + (2 * BALLOON_SCORE_2) + (4 * BALLOON_SCORE_1);
mGame.balloonsPopped++; power = 7;
break;
// Destruye el globo case BALLOON_SIZE_2:
mGame.balloon[index]->pop(); score = BALLOON_SCORE_2 + (2 * BALLOON_SCORE_1);
power = 3;
break;
// Recalcula el nivel de amenaza case BALLOON_SIZE_1:
setMenace(); score = BALLOON_SCORE_1;
power = 1;
break;
default:
score = 0;
power = 0;
break;
} }
// Otorga los puntos correspondientes al globo
mGame.player->addScore(Uint32(score * mGame.player->getScoreMultiplier()));
setScore(mGame.player->getScore());
updateHiScore();
// Aumenta el poder de la fase
increaseStageCurrentPower(power);
mGame.balloonsPopped += power;
// Destruye el globo
mGame.balloon[index]->pop();
// Recalcula el nivel de amenaza
setMenace();
} }
// Explosiona todos los globos // Explosiona todos los globos
void GameDirector::popAllBalloons() void GameDirector::popAllBalloons()
{ {
/*
int candidate[MAX_BALLOONS]; int candidate[MAX_BALLOONS];
Uint8 j = 0; Uint8 j = 0;
for (Uint8 i = 0; i < MAX_BALLOONS; i++) for (Uint8 i = 0; i < MAX_BALLOONS; i++)
@@ -2783,26 +2838,22 @@ void GameDirector::popAllBalloons()
for (Uint8 i = 0; i < MAX_BALLOONS; i++) for (Uint8 i = 0; i < MAX_BALLOONS; i++)
if (candidate[i] >= 0) if (candidate[i] >= 0)
popBalloon(i); popBalloon(i);
*/
for (Uint8 i = 0; i < MAX_BALLOONS; i++)
if ((mGame.balloon[i]->isEnabled()) && (!mGame.balloon[i]->isPopping()) && (!mGame.balloon[i]->isBeingCreated()))
popBalloon(i);
JA_PlaySound(mSound[SOUND_BALLOON].sound); JA_PlaySound(mSound[SOUND_BALLOON].sound);
} }
// Destruye todos los globos // Destruye todos los globos
void GameDirector::destroyAllBalloons() void GameDirector::destroyAllBalloons()
{ {
int candidate[MAX_BALLOONS];
Uint8 j = 0;
for (Uint8 i = 0; i < MAX_BALLOONS; i++) for (Uint8 i = 0; i < MAX_BALLOONS; i++)
{
if ((mGame.balloon[i]->isEnabled()) && (!mGame.balloon[i]->isPopping()) && (!mGame.balloon[i]->isBeingCreated())) if ((mGame.balloon[i]->isEnabled()) && (!mGame.balloon[i]->isPopping()) && (!mGame.balloon[i]->isBeingCreated()))
candidate[j] = i;
else
candidate[j] = -1;
j++;
}
for (Uint8 i = 0; i < MAX_BALLOONS; i++)
if (candidate[i] >= 0)
destroyBalloon(i); destroyBalloon(i);
JA_PlaySound(mSound[SOUND_BALLOON].sound);
JA_PlaySound(mSound[SOUND_POWERBALL].sound);
mGame.effect.flash = true; mGame.effect.flash = true;
mGame.effect.shake = true; mGame.effect.shake = true;
} }
@@ -2930,11 +2981,11 @@ void GameDirector::checkBulletBalloonCollision()
Uint8 droppeditem = dropItem(); Uint8 droppeditem = dropItem();
if ((droppeditem != NO_KIND) && !(mDemo.enabled) && !(mDemo.recording)) if ((droppeditem != NO_KIND) && !(mDemo.enabled) && !(mDemo.recording))
{ {
if (droppeditem == ITEM_POWER_BALL) /*if (droppeditem == ITEM_POWER_BALL)
{ {
createPowerBall(); createPowerBall();
} }
else else*/
{ {
createItem(mGame.balloon[i]->getPosX(), mGame.balloon[i]->getPosY(), droppeditem); createItem(mGame.balloon[i]->getPosX(), mGame.balloon[i]->getPosY(), droppeditem);
JA_PlaySound(mSound[SOUND_ITEM_DROP].sound); JA_PlaySound(mSound[SOUND_ITEM_DROP].sound);
@@ -3050,10 +3101,10 @@ void GameDirector::resetItems()
// Devuelve un item en función del azar // Devuelve un item en función del azar
Uint8 GameDirector::dropItem() Uint8 GameDirector::dropItem()
{ {
return ITEM_COFFEE; //return ITEM_COFFEE;
Uint8 luckyNumber = rand() % 99; Uint8 luckyNumber = rand() % 99;
Uint8 item = rand() % 7; Uint8 item = rand() % 6;
switch (item) switch (item)
{ {
case 0: case 0:
@@ -3080,11 +3131,12 @@ Uint8 GameDirector::dropItem()
if (luckyNumber < 5) if (luckyNumber < 5)
return ITEM_COFFEE; return ITEM_COFFEE;
break; break;
case 6: /*case 6:
if (luckyNumber < 5) if (luckyNumber < 5)
if (countBalloons() > 10) if (countBalloons() > 10)
return ITEM_POWER_BALL; if (!mGame.powerBallEabled)
break; return ITEM_POWER_BALL;
break;*/
default: default:
break; break;
} }
@@ -3159,8 +3211,8 @@ void GameDirector::throwCoffee(int x, int y)
mGame.smartSprite[index]->setEnabledTimer(1); mGame.smartSprite[index]->setEnabledTimer(1);
mGame.smartSprite[index]->setSpriteClip(80, 16, 16, 16); mGame.smartSprite[index]->setSpriteClip(80, 16, 16, 16);
mGame.smartSprite[index]->setRotate(true); mGame.smartSprite[index]->setRotate(true);
mGame.smartSprite[index]->setRotateSpeed(1); mGame.smartSprite[index]->setRotateSpeed(10);
mGame.smartSprite[index]->setRotateAmount(5.0); mGame.smartSprite[index]->setRotateAmount(90.0);
} }
// Crea un SmartSprite para arrojar el item café al recibir un impacto // Crea un SmartSprite para arrojar el item café al recibir un impacto
@@ -3346,6 +3398,12 @@ void GameDirector::setTimeStoppedCounter(Uint16 value)
mGame.timeStoppedCounter = value; mGame.timeStoppedCounter = value;
} }
// Incrementa el valor de la variable
void GameDirector::incTimeStoppedCounter(Uint16 value)
{
mGame.timeStoppedCounter += value;
}
// Actualiza y comprueba el valor de la variable // Actualiza y comprueba el valor de la variable
void GameDirector::updateTimeStoppedCounter() void GameDirector::updateTimeStoppedCounter()
{ {
@@ -4056,7 +4114,7 @@ void GameDirector::enableTimeStopItem()
{ {
stopAllBalloons(TIME_STOPPED_COUNTER); stopAllBalloons(TIME_STOPPED_COUNTER);
setTimeStopped(true); setTimeStopped(true);
setTimeStoppedCounter(TIME_STOPPED_COUNTER); incTimeStoppedCounter(TIME_STOPPED_COUNTER);
if (JA_GetMusicState() == JA_MUSIC_PLAYING) if (JA_GetMusicState() == JA_MUSIC_PLAYING)
{ {
JA_PauseMusic(); JA_PauseMusic();
@@ -4067,7 +4125,8 @@ void GameDirector::enableTimeStopItem()
void GameDirector::disableTimeStopItem() void GameDirector::disableTimeStopItem()
{ {
mGame.timeStopped = false; mGame.timeStopped = false;
mGame.timeStoppedCounter = TIME_STOPPED_COUNTER; setTimeStoppedCounter(0);
//mGame.timeStoppedCounter = TIME_STOPPED_COUNTER;
startAllBalloons(); startAllBalloons();
if (JA_GetMusicState() == JA_MUSIC_PAUSED) if (JA_GetMusicState() == JA_MUSIC_PAUSED)
{ {
@@ -4634,9 +4693,7 @@ void GameDirector::runTitle(Uint8 subsection)
mTitle.coffeeBitmap->render(); mTitle.coffeeBitmap->render();
mTitle.crisisBitmap->render(); mTitle.crisisBitmap->render();
if (mTitle.menuVisible == true) if (mTitle.menuVisible == true)
{
mMenu.active->render(); mMenu.active->render();
}
mTitle.dustBitmapR->animate(0); mTitle.dustBitmapR->animate(0);
mTitle.dustBitmapL->animate(0); mTitle.dustBitmapL->animate(0);
mTitle.dustBitmapR->render(); mTitle.dustBitmapR->render();
@@ -4673,27 +4730,36 @@ void GameDirector::runTitle(Uint8 subsection)
{ {
switch (mMenu.active->getItemSelected()) switch (mMenu.active->getItemSelected())
{ {
case 0: case 0: // PLAY
setProgSection(PROG_SECTION_GAME); JA_PlaySound(mSound[SOUND_MENU_SELECT].sound);
mMenu.active->reset(); mMenu.active->reset();
mMenu.keyPressed = false; mMenu.keyPressed = false;
JA_PlaySound(mSound[SOUND_MENU_SELECT].sound); setProgSection(PROG_SECTION_GAME);
renderFade(1); renderFade(1);
JA_StopMusic(); JA_StopMusic();
disableDemoMode(); disableDemoMode();
break; break;
case 1: case 1: // OPTIONS
JA_PlaySound(mSound[SOUND_MENU_SELECT].sound); JA_PlaySound(mSound[SOUND_MENU_SELECT].sound);
mMenu.active->reset(); mMenu.active->reset();
mMenu.keyPressed = false;
mMenu.active = mMenu.options; mMenu.active = mMenu.options;
mOptions.fullScreenModePrevious = mOptions.fullScreenMode; mOptions.fullScreenModePrevious = mOptions.fullScreenMode;
mOptions.windowSizePrevious = mOptions.windowSize; mOptions.windowSizePrevious = mOptions.windowSize;
break; break;
case 2: case 2: // HOW TO PLAY
mProg.quit = true; JA_PlaySound(mSound[SOUND_MENU_SELECT].sound);
mMenu.active->reset(); mMenu.active->reset();
mMenu.keyPressed = false; mMenu.keyPressed = false;
mTitle.section = TITLE_SECTION_INSTRUCTIONS;
//runInstructions(MODE_MANUAL);
//setProgSection(PROG_SECTION_TITLE,TITLE_SECTION_INSTRUCTIONS);
break;
case 3: // QUIT
JA_PlaySound(mSound[SOUND_MENU_CANCEL].sound); JA_PlaySound(mSound[SOUND_MENU_CANCEL].sound);
mMenu.active->reset();
mMenu.keyPressed = false;
mProg.quit = true;
renderFade(1); renderFade(1);
JA_StopMusic(); JA_StopMusic();
break; break;
@@ -4761,7 +4827,7 @@ void GameDirector::runTitle(Uint8 subsection)
// Sección Instrucciones // Sección Instrucciones
if (mTitle.section == TITLE_SECTION_INSTRUCTIONS) if (mTitle.section == TITLE_SECTION_INSTRUCTIONS)
runInstructions(); runInstructions(MODE_AUTO);
} }
quitTitle(); quitTitle();
@@ -4879,7 +4945,9 @@ void GameDirector::runGame()
// Volca el contenido de la textura en el renderizador // Volca el contenido de la textura en el renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL); SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL);
// Pinta la informacion de debug
renderDebugInfo(); renderDebugInfo();
// Actualiza la pantalla // Actualiza la pantalla
SDL_RenderPresent(mRenderer); SDL_RenderPresent(mRenderer);
} }
@@ -4965,22 +5033,22 @@ void GameDirector::runPausedGame()
} }
// Bucle para la pantalla de instrucciones // Bucle para la pantalla de instrucciones
void GameDirector::runInstructions() void GameDirector::runInstructions(Uint8 mode)
{ {
SDL_Rect window = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; SDL_Rect window = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
Sprite *sprite = new Sprite(); Sprite *sprite = new Sprite();
SDL_Rect rect1 = {60, 88, 16, 16}; // Disquito SDL_Rect srcRect = {0, 0, 16, 16};
SDL_Rect rect2 = {60, 104, 16, 16}; // Gavineixon
SDL_Rect rect3 = {60, 120, 16, 16}; // Pacmar const SDL_Rect destRect1 = {60, 88 + (16 * 0), 16, 16}; // Disquito
SDL_Rect rect4 = {60, 136, 16, 16}; // Time Stopper const SDL_Rect destRect2 = {60, 88 + (16 * 1), 16, 16}; // Gavineixon
SDL_Rect rect5 = {60, 152, 16, 16}; // Explosive const SDL_Rect destRect3 = {60, 88 + (16 * 2), 16, 16}; // Pacmar
SDL_Rect rect6 = {60, 168, 16, 16}; // Coffee const SDL_Rect destRect4 = {60, 88 + (16 * 3), 16, 16}; // Time Stopper
SDL_Rect rect = {0, 0, 16, 16}; const SDL_Rect destRect5 = {60, 88 + (16 * 4), 16, 16}; // Coffee
sprite->init(rect1, mTexture[TEXTURE_ITEMS].texture, mRenderer);
sprite->init(destRect1, mTexture[TEXTURE_ITEMS].texture, mRenderer);
while ((mTitle.section == TITLE_SECTION_INSTRUCTIONS) && (!exit())) while ((mTitle.section == TITLE_SECTION_INSTRUCTIONS) && (!exit()))
{ {
int y = 0;
// Comprueba los eventos que hay en la cola // Comprueba los eventos que hay en la cola
while (SDL_PollEvent(mEventHandler) != 0) while (SDL_PollEvent(mEventHandler) != 0)
{ {
@@ -5012,40 +5080,44 @@ void GameDirector::runInstructions()
mText.white->write(84, 108, "2.500 POINTS", 0); mText.white->write(84, 108, "2.500 POINTS", 0);
mText.white->write(84, 124, "5.000 POINTS", 0); mText.white->write(84, 124, "5.000 POINTS", 0);
mText.white->write(84, 140, "TIME STOPPER", 0); mText.white->write(84, 140, "TIME STOPPER", 0);
mText.white->write(84, 156, "FOUR EXPLOSIONS", 0); mText.white->write(84, 156, "EXTRA HIT", 0);
mText.white->write(84, 172, "EXTRA HIT", 0);
sprite->init(rect1, mTexture[TEXTURE_ITEMS].texture, mRenderer); // Disquito
sprite->setSpriteClip(rect); sprite->init(destRect1, mTexture[TEXTURE_ITEMS].texture, mRenderer);
rect.x += rect.w; srcRect.x = 0;
rect.y = 16 * (((mTitle.instructionsCounter + 3) / 36) % 2); srcRect.y = 16 * (((mTitle.instructionsCounter + 0) / 36) % 2);
sprite->render(); sprite->setSpriteClip(srcRect);
sprite->init(rect2, mTexture[TEXTURE_ITEMS].texture, mRenderer);
sprite->setSpriteClip(rect);
rect.x += rect.w;
rect.y = 16 * (((mTitle.instructionsCounter + 6) / 36) % 2);
sprite->render();
sprite->init(rect3, mTexture[TEXTURE_ITEMS].texture, mRenderer);
sprite->setSpriteClip(rect);
rect.x += rect.w;
rect.y = 16 * (((mTitle.instructionsCounter + 9) / 36) % 2);
sprite->render();
sprite->init(rect4, mTexture[TEXTURE_ITEMS].texture, mRenderer);
sprite->setSpriteClip(rect);
rect.x += rect.w;
rect.y = 16 * (((mTitle.instructionsCounter + 12) / 36) % 2);
sprite->render();
sprite->init(rect5, mTexture[TEXTURE_ITEMS].texture, mRenderer);
sprite->setSpriteClip(rect);
rect.x += rect.w;
rect.y = 16 * (((mTitle.instructionsCounter + 15) / 36) % 2);
sprite->render();
sprite->init(rect6, mTexture[TEXTURE_ITEMS].texture, mRenderer);
sprite->setSpriteClip(rect);
rect.x = 0;
rect.y = 16 * (((mTitle.instructionsCounter + 0) / 36) % 2);
sprite->render(); sprite->render();
// Gavineixon
sprite->init(destRect2, mTexture[TEXTURE_ITEMS].texture, mRenderer);
srcRect.x += srcRect.w;
srcRect.y = 16 * (((mTitle.instructionsCounter + 3) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Pacmar
sprite->init(destRect3, mTexture[TEXTURE_ITEMS].texture, mRenderer);
srcRect.x += srcRect.w;
srcRect.y = 16 * (((mTitle.instructionsCounter + 6) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Time Stopper
sprite->init(destRect4, mTexture[TEXTURE_ITEMS].texture, mRenderer);
srcRect.x += srcRect.w;
srcRect.y = 16 * (((mTitle.instructionsCounter + 9) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Coffee
sprite->init(destRect5, mTexture[TEXTURE_ITEMS].texture, mRenderer);
srcRect.x += (srcRect.w * 2); // Se salta el icono del TNT
srcRect.y = 16 * (((mTitle.instructionsCounter + 12) / 36) % 2);
sprite->setSpriteClip(srcRect);
sprite->render();
// Cambia el destino de renderizado
SDL_SetRenderTarget(mRenderer, nullptr); SDL_SetRenderTarget(mRenderer, nullptr);
// Limpia la pantalla // Limpia la pantalla
@@ -5053,13 +5125,7 @@ void GameDirector::runInstructions()
SDL_RenderClear(mRenderer); SDL_RenderClear(mRenderer);
// Dibuja los objetos // Dibuja los objetos
y = SCREEN_HEIGHT - (INSTRUCTIONS_COUNTER - mTitle.instructionsCounter) + 100; window.y = std::max(0, SCREEN_HEIGHT - (INSTRUCTIONS_COUNTER - mTitle.instructionsCounter) + 100);
if (y < 0)
{
y = 0;
}
window.y = y;
SDL_RenderCopy(mRenderer, mInstructionsSurface, NULL, &window); SDL_RenderCopy(mRenderer, mInstructionsSurface, NULL, &window);
// Muestra la pantalla // Muestra la pantalla
@@ -5069,9 +5135,17 @@ void GameDirector::runInstructions()
if (mTitle.instructionsCounter == 0) if (mTitle.instructionsCounter == 0)
{ {
mTitle.instructionsCounter = INSTRUCTIONS_COUNTER; resetTitle(TITLE_SECTION_1);
mTitle.section = TITLE_SECTION_1; mTitle.section = TITLE_SECTION_3;
mTitle.nextProgSection = PROG_SECTION_LOGO; mTitle.nextProgSection = PROG_SECTION_LOGO;
// Prepara las variables para la sección 3 del titulo
mTitle.dustBitmapL->setEnabled(false);
mTitle.dustBitmapR->setEnabled(false);
mTitle.menuVisible = true;
mTitle.coffeeBitmap->setPosY(11);
mTitle.crisisBitmap->setPosY(57);
mMenu.title->setSelectorPos(2);
} }
} }
delete sprite; delete sprite;
@@ -5201,4 +5275,27 @@ void GameDirector::renderDebugInfo()
mText.white->writeShadowed(2, 2 + 8 * BLOCK, "balloonsPop: " + std::to_string(mGame.balloonsPopped), R, G, B); mText.white->writeShadowed(2, 2 + 8 * BLOCK, "balloonsPop: " + std::to_string(mGame.balloonsPopped), R, G, B);
mText.white->writeShadowed(2, 2 + 9 * BLOCK, "(Z-X)ballSped:" + std::to_string(mGame.enemySpeed), R, G, B); mText.white->writeShadowed(2, 2 + 9 * BLOCK, "(Z-X)ballSped:" + std::to_string(mGame.enemySpeed), R, G, B);
} }
}
// Indica si se puede crear una powerball
bool GameDirector::canPowerBallBeCreated()
{
bool success = false;
if ((!mGame.powerBallEabled) && (calculateScreenPower() > 0))
success = true;
else
success = false;
return success;
}
// Calcula el poder actual de los globos en pantalla
int GameDirector::calculateScreenPower()
{
int power = 0;
for (Uint8 i = 0; i < MAX_BALLOONS; i++)
if (mGame.balloon[i]->isEnabled())
power += mGame.balloon[i]->getPower();
return power;
} }

View File

@@ -153,6 +153,7 @@ private:
Uint8 enemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero Uint8 enemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
float enemySpeed; // Velocidad a la que se mueven los enemigos float enemySpeed; // Velocidad a la que se mueven los enemigos
effect_t effect; // Variable para gestionar los efectos visuales effect_t effect; // Variable para gestionar los efectos visuales
bool powerBallEabled; // Indica si hay una powerball ya activa
}; };
game_t mGame; // Variable con todas las variables usadas durante el juego game_t mGame; // Variable con todas las variables usadas durante el juego
@@ -300,6 +301,9 @@ public:
// Inicializa las variables necesarias para la sección 'Title' // Inicializa las variables necesarias para la sección 'Title'
void initTitle(Uint8 subsection = TITLE_SECTION_1); void initTitle(Uint8 subsection = TITLE_SECTION_1);
// Resetea las variables necesarias para la sección 'Title'
void resetTitle(Uint8 subsection = TITLE_SECTION_1);
// Carga los recursos necesarios para la sección 'Title' // Carga los recursos necesarios para la sección 'Title'
bool loadMediaTitle(); bool loadMediaTitle();
@@ -364,7 +368,7 @@ public:
void deployEnemyFormation(); void deployEnemyFormation();
// Aumenta el poder de la fase // Aumenta el poder de la fase
void increaseStageCurrentPower(); void increaseStageCurrentPower(Uint8 power);
// Establece el valor de la variable // Establece el valor de la variable
void setScore(Uint32 score); void setScore(Uint32 score);
@@ -553,6 +557,9 @@ public:
// Establece el valor de la variable // Establece el valor de la variable
void setTimeStoppedCounter(Uint16 value); void setTimeStoppedCounter(Uint16 value);
// Incrementa el valor de la variable
void incTimeStoppedCounter(Uint16 value);
// Actualiza la variable EnemyDeployCounter // Actualiza la variable EnemyDeployCounter
void updateEnemyDeployCounter(); void updateEnemyDeployCounter();
@@ -644,7 +651,7 @@ public:
void runPausedGame(); void runPausedGame();
// Bucle para la pantalla de instrucciones // Bucle para la pantalla de instrucciones
void runInstructions(); void runInstructions(Uint8 mode);
// Bucle para la pantalla de game over // Bucle para la pantalla de game over
void runGameOverScreen(); void runGameOverScreen();
@@ -660,6 +667,12 @@ public:
// Dibuja la informacion de debug en pantalla // Dibuja la informacion de debug en pantalla
void renderDebugInfo(); void renderDebugInfo();
// Indica si se puede crear una powerball
bool canPowerBallBeCreated();
// Calcula el poder actual de los globos en pantalla
int calculateScreenPower();
}; };
#endif #endif

View File

@@ -63,6 +63,9 @@ public:
// Establece el indice del item que se usará por defecto al cancelar el menu // Establece el indice del item que se usará por defecto al cancelar el menu
void setDefaultActionWhenCancel(Uint8 item); void setDefaultActionWhenCancel(Uint8 item);
// Coloca el selector en una posición específica
void setSelectorPos(Uint8 index);
private: private:
// Establece el valor de la variable // Establece el valor de la variable
void setTotalItems(int num); void setTotalItems(int num);
@@ -91,9 +94,6 @@ private:
// Establece el destino del selector // Establece el destino del selector
void setSelectorTarget(int value); void setSelectorTarget(int value);
// Coloca el selector en una posición específica
void setSelectorPos(Uint8 index);
// Obtiene la anchura del elemento más ancho del menu // Obtiene la anchura del elemento más ancho del menu
Uint16 getWidestItem(); Uint16 getWidestItem();

View File

@@ -5,13 +5,35 @@
// Constructor // Constructor
MovingSprite::MovingSprite() MovingSprite::MovingSprite()
{ {
init(0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr); clear();
} }
// Destructor // Destructor
MovingSprite::~MovingSprite() MovingSprite::~MovingSprite()
{ {
init(0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr); clear();
}
// Reinicia todas las variables
void MovingSprite::clear()
{
mPosX = 0.0f; // Posición en el eje X
mPosY = 0.0f; // Posición en el eje Y
mVelX = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
mVelY = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
mAccelX = 0.0f; // Aceleración en el eje X. Variación de la velocidad
mAccelY = 0.0f; // Aceleración en el eje Y. Variación de la velocidad
mZoomW = 1.0f; // Zoom aplicado a la anchura
mZoomH = 1.0f; // Zoom aplicado a la altura
mAngle = 0.0; // Angulo para dibujarlo
mRotate = false; // Indica si ha de rotar
mRotateSpeed = 0; // Velocidad de giro
mRotateAmount = 0.0; // Cantidad de grados a girar en cada iteración
mCounter = 0; // Contador interno
} }
// Iniciador // Iniciador
@@ -40,6 +62,14 @@ void MovingSprite::init(float x, float y, int w, int h, float velx, float vely,
// Establece el angulo con el que se dibujará // Establece el angulo con el que se dibujará
setAngle(0.0); setAngle(0.0);
// Establece los valores de rotacion
setRotate(false);
setRotateSpeed(0);
setRotateAmount(0.0);
// Contador interno
mCounter = 0;
// Establece la textura donde están los gráficos para el sprite // Establece la textura donde están los gráficos para el sprite
setTexture(texture); setTexture(texture);
@@ -53,18 +83,21 @@ void MovingSprite::init(float x, float y, int w, int h, float velx, float vely,
// Mueve el sprite // Mueve el sprite
void MovingSprite::move() void MovingSprite::move()
{ {
mPosX += mVelX; if (mEnabled)
mPosY += mVelY; {
mPosX += mVelX;
mPosY += mVelY;
mVelX += mAccelX; mVelX += mAccelX;
mVelY += mAccelY; mVelY += mAccelY;
}
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void MovingSprite::render() void MovingSprite::render()
{ {
//mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip); if (mEnabled)
mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle); mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle);
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
@@ -185,4 +218,63 @@ void MovingSprite::incAngle(double inc)
void MovingSprite::decAngle(double dec) void MovingSprite::decAngle(double dec)
{ {
mAngle -= dec; mAngle -= dec;
}
// Obtiene el valor de la variable
bool MovingSprite::getRotate()
{
return mRotate;
}
// Obtiene el valor de la variable
Uint16 MovingSprite::getRotateSpeed()
{
return mRotateSpeed;
}
// Establece la rotacion
void MovingSprite::rotate()
{
if (mEnabled)
if (mRotate)
{
if (mCounter % mRotateSpeed == 0)
{
incAngle(mRotateAmount);
}
}
}
// Establece el valor de la variable
void MovingSprite::setRotate(bool value)
{
mRotate = value;
}
// Establece el valor de la variable
void MovingSprite::setRotateSpeed(Uint16 value)
{
mRotateSpeed = value;
}
// Establece el valor de la variable
void MovingSprite::setRotateAmount(double value)
{
mRotateAmount = value;
}
// Actualiza las variables internas del objeto
void MovingSprite::update()
{
move();
rotate();
if (mEnabled)
++mCounter %= 60000;
}
// Cambia el sentido de la rotación
void MovingSprite::switchRotate()
{
mRotateAmount *= -1;
} }

View File

@@ -8,7 +8,7 @@
// Clase MovingSprite. Añade posicion y velocidad en punto flotante // Clase MovingSprite. Añade posicion y velocidad en punto flotante
class MovingSprite : public Sprite class MovingSprite : public Sprite
{ {
private: protected:
float mPosX; // Posición en el eje X float mPosX; // Posición en el eje X
float mPosY; // Posición en el eje Y float mPosY; // Posición en el eje Y
@@ -21,7 +21,11 @@ private:
float mZoomW; // Zoom aplicado a la anchura float mZoomW; // Zoom aplicado a la anchura
float mZoomH; // Zoom aplicado a la altura float mZoomH; // Zoom aplicado a la altura
double mAngle; // Angulo para dibujarlo double mAngle; // Angulo para dibujarlo
bool mRotate; // Indica si ha de rotar
Uint16 mRotateSpeed; // Velocidad de giro
double mRotateAmount; // Cantidad de grados a girar en cada iteración
Uint16 mCounter; // Contador interno
public: public:
// Constructor // Constructor
@@ -36,6 +40,15 @@ public:
// Mueve el sprite // Mueve el sprite
void move(); void move();
// Rota el sprite
void rotate();
// Actualiza las variables internas del objeto
void update();
// Reinicia todas las variables
void clear();
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void render(); void render();
@@ -66,6 +79,12 @@ public:
// Obten el valor de la variable // Obten el valor de la variable
double getAngle(); double getAngle();
// Obtiene el valor de la variable
bool getRotate();
// Obtiene el valor de la variable
Uint16 getRotateSpeed();
// Establece el valor de la variable // Establece el valor de la variable
void setPosX(float x); void setPosX(float x);
@@ -98,6 +117,18 @@ public:
// Decrementa el valor de la variable // Decrementa el valor de la variable
void decAngle(double dec); void decAngle(double dec);
// Establece el valor de la variable
void setRotate(bool value);
// Establece el valor de la variable
void setRotateSpeed(Uint16 value);
// Establece el valor de la variable
void setRotateAmount(double value);
// Cambia el sentido de la rotación
void switchRotate();
}; };
#endif #endif

View File

@@ -92,24 +92,6 @@ void SmartSprite::setDestY(int value)
mDestY = value; mDestY = value;
} }
// Establece el valor de la variable
void SmartSprite::setRotate(bool value)
{
mRotate = value;
}
// Establece el valor de la variable
void SmartSprite::setRotateSpeed(Uint16 value)
{
mRotateSpeed = value;
}
// Establece el valor de la variable
void SmartSprite::setRotateAmount(double value)
{
mRotateAmount = value;
}
// Obtiene el valor de la variable // Obtiene el valor de la variable
int SmartSprite::getDestX() int SmartSprite::getDestX()
{ {
@@ -122,37 +104,12 @@ int SmartSprite::getDestY()
return mDestY; return mDestY;
} }
// Obtiene el valor de la variable
bool SmartSprite::getRotate()
{
return mRotate;
}
// Obtiene el valor de la variable
Uint16 SmartSprite::getRotateSpeed()
{
return mRotateSpeed;
}
// Establece la rotacion
void SmartSprite::rotate()
{
if (mRotate)
{
if (mCounter % mRotateSpeed == 0)
{
incAngle(mRotateAmount);
}
}
}
// Actualiza la posición y comprueba si ha llegado a su destino // Actualiza la posición y comprueba si ha llegado a su destino
bool SmartSprite::update() bool SmartSprite::update()
{ {
if (mEnabled) if (mEnabled)
{ {
move(); MovingSprite::update();
rotate();
// Comprueba si se desplaza en el eje X hacia la derecha // Comprueba si se desplaza en el eje X hacia la derecha
if ((getAccelX() > 0) || ((getAccelX() == 0) && (getVelX() > 0))) if ((getAccelX() > 0) || ((getAccelX() == 0) && (getVelX() > 0)))
@@ -168,7 +125,6 @@ bool SmartSprite::update()
setAccelX(0.0f); setAccelX(0.0f);
} }
} }
// Comprueba si se desplaza en el eje X hacia la izquierda // Comprueba si se desplaza en el eje X hacia la izquierda
else if ((getAccelX() < 0) || ((getAccelX() == 0) && (getVelX() < 0))) else if ((getAccelX() < 0) || ((getAccelX() == 0) && (getVelX() < 0)))
{ {
@@ -244,9 +200,6 @@ bool SmartSprite::update()
} }
} }
} }
mCounter++;
mCounter %= 65000;
} }
return mIsOnDestination; return mIsOnDestination;

View File

@@ -11,15 +11,11 @@ class SmartSprite : public AnimatedSprite
private: private:
bool mEnabled; // Indica si esta habilitado bool mEnabled; // Indica si esta habilitado
bool mIsOnDestination; // Indica si está en el destino bool mIsOnDestination; // Indica si está en el destino
bool mRotate; // Indica si ha de rotar
int mDestX; // Posicion de destino en el eje X int mDestX; // Posicion de destino en el eje X
int mDestY; // Posicion de destino en el eje Y int mDestY; // Posicion de destino en el eje Y
int mId; // Identificador int mId; // Identificador
Uint16 mCounter; // Contador interno
Uint16 mEnabledCounter; // Contador para deshabilitarlo Uint16 mEnabledCounter; // Contador para deshabilitarlo
Uint16 mRotateSpeed; // Velocidad de giro
Uint8 *mIntroEvents; // Dirección del array de eventos donde notificar el estado Uint8 *mIntroEvents; // Dirección del array de eventos donde notificar el estado
double mRotateAmount; // Cantidad de grados a girar en cada iteración
public: public:
// Constructor // Constructor
@@ -52,30 +48,12 @@ public:
// Establece el valor de la variable // Establece el valor de la variable
void setDestY(int value); void setDestY(int value);
// Establece el valor de la variable
void setRotate(bool value);
// Establece el valor de la variable
void setRotateSpeed(Uint16 value);
// Establece el valor de la variable
void setRotateAmount(double value);
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getDestX(); int getDestX();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getDestY(); int getDestY();
// Obtiene el valor de la variable
bool getRotate();
// Obtiene el valor de la variable
Uint16 getRotateSpeed();
// Establece la rotacion
void rotate();
// Actualiza la posición y comprueba si ha llegado a su destino // Actualiza la posición y comprueba si ha llegado a su destino
bool update(); bool update();

View File

@@ -32,6 +32,9 @@ void Sprite::init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *r
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
setSpriteClip(0, 0, w, h); setSpriteClip(0, 0, w, h);
// Habilita el objeto
setEnabled(true);
} }
// Inicializador // Inicializador
@@ -58,7 +61,8 @@ void Sprite::init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer)
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void Sprite::render() void Sprite::render()
{ {
mTexture->render(mRenderer, mPosX, mPosY, &mSpriteClip); if (mEnabled)
mTexture->render(mRenderer, mPosX, mPosY, &mSpriteClip);
} }
// Obten el valor de la variable // Obten el valor de la variable
@@ -146,4 +150,16 @@ void Sprite::setTexture(LTexture *texture)
void Sprite::setRenderer(SDL_Renderer *renderer) void Sprite::setRenderer(SDL_Renderer *renderer)
{ {
mRenderer = renderer; mRenderer = renderer;
}
// Establece el valor de la variable
void Sprite::setEnabled(bool value)
{
mEnabled = value;
}
// Comprueba si el objeto está habilitado
bool Sprite::isEnabled()
{
return mEnabled;
} }

View File

@@ -8,44 +8,56 @@
// Clase sprite // Clase sprite
class Sprite class Sprite
{ {
protected:
int mPosX; // Posición en el eje X donde dibujar el sprite
int mPosY; // Posición en el eje Y donde dibujar el sprite
Uint16 mWidth; // Ancho del sprite
Uint16 mHeight; // Alto del sprite
SDL_Renderer *mRenderer; // Puntero al renderizador de la ventana
LTexture *mTexture; // Textura donde estan todos los dibujos del sprite
SDL_Rect mSpriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla
bool mEnabled; // Indica si el sprite esta habilitado
public: public:
// Constructor // Constructor
Sprite(); Sprite();
// Destructor // Destructor
~Sprite(); ~Sprite();
// Inicializador // Inicializador
void init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer); void init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer);
void init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer); void init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer);
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void render(); void render();
// Obten el valor de la variable // Obten el valor de la variable
int getPosX(); int getPosX();
// Obten el valor de la variable // Obten el valor de la variable
int getPosY(); int getPosY();
// Obten el valor de la variable // Obten el valor de la variable
int getWidth(); int getWidth();
// Obten el valor de la variable // Obten el valor de la variable
int getHeight(); int getHeight();
// Establece el valor de la variable // Establece el valor de la variable
void setPosX(int x); void setPosX(int x);
// Establece el valor de la variable // Establece el valor de la variable
void setPosY(int y); void setPosY(int y);
// Establece el valor de la variable // Establece el valor de la variable
void setWidth(int w); void setWidth(int w);
// Establece el valor de la variable // Establece el valor de la variable
void setHeight(int h); void setHeight(int h);
// Obten el valor de la variable // Obten el valor de la variable
SDL_Rect getSpriteClip(); SDL_Rect getSpriteClip();
@@ -56,32 +68,19 @@ public:
void setSpriteClip(int x, int y, int w, int h); void setSpriteClip(int x, int y, int w, int h);
// Obten el valor de la variable // Obten el valor de la variable
LTexture* getTexture(); LTexture *getTexture();
// Establece el valor de la variable // Establece el valor de la variable
void setTexture(LTexture *texture); void setTexture(LTexture *texture);
// Establece el valor de la variable // Establece el valor de la variable
void setRenderer(SDL_Renderer *renderer); void setRenderer(SDL_Renderer *renderer);
// Establece el valor de la variable
void setEnabled(bool value);
protected: // Comprueba si el objeto está habilitado
// Posición X,Y donde dibujar el sprite bool isEnabled();
int mPosX;
int mPosY;
// Alto y ancho del sprite
Uint16 mWidth;
Uint16 mHeight;
// Puntero al renderizador de la ventana
SDL_Renderer *mRenderer;
// Textura donde estan todos los dibujos del sprite
LTexture *mTexture;
// Rectangulo de la textura que se dibujará en pantalla
SDL_Rect mSpriteClip;
}; };
#endif #endif