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
+299 -202
View File
@@ -180,7 +180,8 @@ void GameDirector::initProg()
// 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->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->setDefaultActionWhenCancel(2);
mMenu.title->setBackgroundColor(0x30, 0x30, 0x40, 192);
@@ -668,6 +669,13 @@ void GameDirector::initTitle(Uint8 subsection)
// Carga los recursos
loadMediaTitle();
// Inicializa las variables
resetTitle(subsection);
}
// Resetea las variables necesarias para la sección 'Title'
void GameDirector::resetTitle(Uint8 subsection)
{
// Inicializa variables
mTitle.section = subsection;
mTitle.counter = TITLE_COUNTER;
@@ -900,7 +908,7 @@ void GameDirector::resetGame()
mGame.remainingExplosions = REMAINING_EXPLOSIONS;
mGame.remainingExplosionsCounter = REMAINING_EXPLOSIONS_COUNTER;
mGame.timeStopped = false;
mGame.timeStoppedCounter = TIME_STOPPED_COUNTER;
mGame.timeStoppedCounter = 0;
mGame.counter = 0;
mGame.balloonsPopped = 0;
mGame.lastEnemyDeploy = 0;
@@ -909,6 +917,7 @@ void GameDirector::resetGame()
mGame.effect.flash = false;
mGame.effect.shake = false;
mGame.effect.shakeCounter = SHAKE_COUNTER;
mGame.powerBallEabled = false;
initGameStages();
// Sprites
@@ -1046,6 +1055,7 @@ bool GameDirector::loadMediaGame()
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_CLOCK].sound = JA_LoadSound(mSound[SOUND_CLOCK].file.c_str());
mSound[SOUND_POWERBALL].sound = JA_LoadSound(mSound[SOUND_POWERBALL].file.c_str());
// Musicas
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_BUBBLE4].sound);
JA_DeleteSound(mSound[SOUND_CLOCK].sound);
JA_DeleteSound(mSound[SOUND_POWERBALL].sound);
// Musicas
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_TITLE].file = mProg.executablePath + "/" + "../media/sound/title.wav";
mSound[SOUND_CLOCK].file = mProg.executablePath + "/" + "../media/sound/clock.wav";
mSound[SOUND_POWERBALL].file = mProg.executablePath + "/" + "../media/sound/powerball.wav";
// Texturas
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 x4_0 = PLAY_AREA_LEFT;
//const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_4 / 2);
const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_4;
//const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_4 / 2);
const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_4;
const int y3 = (PLAY_AREA_TOP - BLOCK);
const int x3_0 = PLAY_AREA_LEFT;
//const int x3_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_3 / 2);
const int x3_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_3;
//const int x3_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_3 / 2);
const int x3_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_3;
const int y2 = (PLAY_AREA_TOP - BLOCK);
const int x2_0 = PLAY_AREA_LEFT;
//const int x2_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_2 / 2);
const int x2_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_2;
//const int x2_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_2 / 2);
const int x2_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_2;
const int y1 = (PLAY_AREA_TOP - BLOCK);
const int x1_0 = PLAY_AREA_LEFT;
const int x1_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_1 / 2);
const int x1_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_1;
const int x1_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_1 / 2);
const int x1_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_1;
const Uint16 creationTime = 300;
int incX = 0;
@@ -1621,7 +1633,7 @@ void GameDirector::initEnemyFormations()
incTime = 0;
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].velX = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1);
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
j = 2;
mEnemyFormation[j].numberOfEnemies = 4;
incX = BALLOON_SIZE_2 + 1;
incX = BALLOON_WIDTH_2 + 1;
incTime = 10;
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
j = 3;
mEnemyFormation[j].numberOfEnemies = 4;
incX = BALLOON_SIZE_2 + 1;
incX = BALLOON_WIDTH_2 + 1;
incTime = 10;
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
j = 4;
mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 * 2;
incX = BALLOON_WIDTH_3 * 2;
incTime = 10;
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
j = 5;
mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 * 2;
incX = BALLOON_WIDTH_3 * 2;
incTime = 10;
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
j = 6;
mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 + 1;
incX = BALLOON_WIDTH_3 + 1;
incTime = 10;
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
j = 7;
mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_3 + 1;
incX = BALLOON_WIDTH_3 + 1;
incTime = 10;
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
j = 8;
mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_1 + 1;
incX = BALLOON_WIDTH_1 + 1;
incTime = 10;
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
j = 9;
mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_1 + 1;
incX = BALLOON_WIDTH_1 + 1;
incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1743,7 +1755,7 @@ void GameDirector::initEnemyFormations()
// #10 - Tres enemigos BALLOON4 seguidos desde la izquierda
j = 10;
mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_4 + 1;
incX = BALLOON_WIDTH_4 + 1;
incTime = 15;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1757,7 +1769,7 @@ void GameDirector::initEnemyFormations()
// #11 - Tres enemigos BALLOON4 seguidos desde la derecha
j = 11;
mEnemyFormation[j].numberOfEnemies = 3;
incX = BALLOON_SIZE_4 + 1;
incX = BALLOON_WIDTH_4 + 1;
incTime = 15;
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
j = 12;
mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_2 + 1;
incX = BALLOON_WIDTH_2 + 1;
incTime = 10;
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
j = 13;
mEnemyFormation[j].numberOfEnemies = 6;
incX = BALLOON_SIZE_2 + 1;
incX = BALLOON_WIDTH_2 + 1;
incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1799,7 +1811,7 @@ void GameDirector::initEnemyFormations()
// #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados
j = 14;
mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 * 2;
incX = BALLOON_WIDTH_3 * 2;
incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1813,7 +1825,7 @@ void GameDirector::initEnemyFormations()
// #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados
j = 15;
mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 * 2;
incX = BALLOON_WIDTH_3 * 2;
incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1827,7 +1839,7 @@ void GameDirector::initEnemyFormations()
// #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos
j = 16;
mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 + 1;
incX = BALLOON_WIDTH_3 + 1;
incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1841,7 +1853,7 @@ void GameDirector::initEnemyFormations()
// #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos
j = 17;
mEnemyFormation[j].numberOfEnemies = 5;
incX = BALLOON_SIZE_3 + 1;
incX = BALLOON_WIDTH_3 + 1;
incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1855,7 +1867,7 @@ void GameDirector::initEnemyFormations()
// #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos
j = 18;
mEnemyFormation[j].numberOfEnemies = 12;
incX = BALLOON_SIZE_1 + 1;
incX = BALLOON_WIDTH_1 + 1;
incTime = 10;
for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++)
{
@@ -1869,7 +1881,7 @@ void GameDirector::initEnemyFormations()
// #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos
j = 19;
mEnemyFormation[j].numberOfEnemies = 12;
incX = BALLOON_SIZE_1 + 1;
incX = BALLOON_WIDTH_1 + 1;
incTime = 10;
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
j = 20;
mEnemyFormation[j].numberOfEnemies = 4;
incX = BALLOON_SIZE_4 + 1;
incX = BALLOON_WIDTH_4 + 1;
incTime = 0;
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
j = 21;
mEnemyFormation[j].numberOfEnemies = 10;
incX = BALLOON_SIZE_2 + 1;
incX = BALLOON_WIDTH_2 + 1;
incTime = 3;
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
j = 22;
mEnemyFormation[j].numberOfEnemies = 10;
incX = BALLOON_SIZE_3 * 2;
incX = BALLOON_WIDTH_3 * 2;
incTime = 10;
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
j = 23;
mEnemyFormation[j].numberOfEnemies = 10;
incX = BALLOON_SIZE_3 + 1;
incX = BALLOON_WIDTH_3 + 1;
incTime = 10;
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
j = 25;
mEnemyFormation[j].numberOfEnemies = 30;
incX = BALLOON_SIZE_1 + 1;
incX = BALLOON_WIDTH_1 + 1;
incTime = 5;
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
if (mGame.enemyDeployCounter == 0)
{
mGame.enemyDeployCounter = 255;
Uint8 set = (rand() % 10);
if (set == mGame.lastEnemyDeploy)
// En este punto se decide entre crear una powerball o una formación enemiga
if ((rand() % 100 < 15) && (canPowerBallBeCreated()))
{
set++;
set %= 10;
// Crea una powerball
createPowerBall();
mGame.enemyDeployCounter = 50;
}
mGame.lastEnemyDeploy = set;
else
{
if (mDebug.enabled)
set = mDebug.enemySet;
// Elige una formación enemiga la azar
Uint8 set = (rand() % 10);
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);
// Evita repetir la ultima formación enemiga desplegada
if (set == mGame.lastEnemyDeploy)
{
set++;
set %= 10;
}
mGame.lastEnemyDeploy = set;
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
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
@@ -2602,14 +2629,15 @@ Uint8 GameDirector::createNewBalloon(float x, int y, Uint8 kind, float velx, flo
// Crea una PowerBall
void GameDirector::createPowerBall()
{
const int y4 = (PLAY_AREA_TOP - BLOCK);
const int x4_0 = PLAY_AREA_LEFT;
const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_4 / 2);
const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_4;
const int x[3] = {x4_0, x4_50, x4_100};
int x4 = x[rand() % 3];
const int posY = (PLAY_AREA_TOP);
const int left = PLAY_AREA_LEFT;
const int center = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_4 / 2);
const int right = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_4;
const int x[3] = {left, center, right};
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
@@ -2688,88 +2716,115 @@ void GameDirector::updateBalloonSpeed()
// Explosiona un globo. Lo destruye y crea otros dos si es el caso
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
mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier()));
setScore(mGame.player->getScore());
updateHiScore();
// Si es del tipo más pequeño, simplemente elimina el globo
case BALLOON_1:
mGame.balloon[index]->pop();
break;
// Aumenta el poder de la fase
increaseStageCurrentPower();
mGame.balloonsPopped++;
case HEXAGON_1:
mGame.balloon[index]->pop();
break;
Uint8 kind = mGame.balloon[index]->getKind();
Uint8 freeIndex = 0;
switch (kind)
{
// Si es del tipo más pequeño, simplemente elimina el globo
case BALLOON_1:
mGame.balloon[index]->pop();
break;
// Si es del tipo PowerBall, destruye todos los globos
case POWER_BALL:
destroyAllBalloons();
mGame.powerBallEabled = false;
break;
case HEXAGON_1:
mGame.balloon[index]->pop();
break;
// En cualquier otro caso, crea dos globos de un tipo inferior
default:
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
case POWER_BALL:
destroyAllBalloons();
break;
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);
// En cualquier otro caso, crea dos globos de un tipo inferior
default:
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);
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();
// Elimina el globo
mGame.balloon[index]->pop();
break;
}
// Recalcula el nivel de amenaza
setMenace();
}
// Explosiona un globo. Lo destruye
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
mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier()));
setScore(mGame.player->getScore());
updateHiScore();
case BALLOON_SIZE_4:
score = BALLOON_SCORE_4 + (2 * BALLOON_SCORE_3) + (4 * BALLOON_SCORE_2) + (8 * BALLOON_SCORE_1);
power = 15;
break;
// Aumenta el poder de la fase
increaseStageCurrentPower();
mGame.balloonsPopped++;
case BALLOON_SIZE_3:
score = BALLOON_SCORE_3 + (2 * BALLOON_SCORE_2) + (4 * BALLOON_SCORE_1);
power = 7;
break;
// Destruye el globo
mGame.balloon[index]->pop();
case BALLOON_SIZE_2:
score = BALLOON_SCORE_2 + (2 * BALLOON_SCORE_1);
power = 3;
break;
// Recalcula el nivel de amenaza
setMenace();
case BALLOON_SIZE_1:
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
void GameDirector::popAllBalloons()
{
/*
int candidate[MAX_BALLOONS];
Uint8 j = 0;
for (Uint8 i = 0; i < MAX_BALLOONS; i++)
@@ -2783,26 +2838,22 @@ void GameDirector::popAllBalloons()
for (Uint8 i = 0; i < MAX_BALLOONS; i++)
if (candidate[i] >= 0)
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);
}
// Destruye todos los globos
void GameDirector::destroyAllBalloons()
{
int candidate[MAX_BALLOONS];
Uint8 j = 0;
for (Uint8 i = 0; i < MAX_BALLOONS; i++)
{
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);
JA_PlaySound(mSound[SOUND_BALLOON].sound);
JA_PlaySound(mSound[SOUND_POWERBALL].sound);
mGame.effect.flash = true;
mGame.effect.shake = true;
}
@@ -2930,11 +2981,11 @@ void GameDirector::checkBulletBalloonCollision()
Uint8 droppeditem = dropItem();
if ((droppeditem != NO_KIND) && !(mDemo.enabled) && !(mDemo.recording))
{
if (droppeditem == ITEM_POWER_BALL)
/*if (droppeditem == ITEM_POWER_BALL)
{
createPowerBall();
}
else
else*/
{
createItem(mGame.balloon[i]->getPosX(), mGame.balloon[i]->getPosY(), droppeditem);
JA_PlaySound(mSound[SOUND_ITEM_DROP].sound);
@@ -3050,10 +3101,10 @@ void GameDirector::resetItems()
// Devuelve un item en función del azar
Uint8 GameDirector::dropItem()
{
return ITEM_COFFEE;
//return ITEM_COFFEE;
Uint8 luckyNumber = rand() % 99;
Uint8 item = rand() % 7;
Uint8 item = rand() % 6;
switch (item)
{
case 0:
@@ -3080,11 +3131,12 @@ Uint8 GameDirector::dropItem()
if (luckyNumber < 5)
return ITEM_COFFEE;
break;
case 6:
/*case 6:
if (luckyNumber < 5)
if (countBalloons() > 10)
return ITEM_POWER_BALL;
break;
if (!mGame.powerBallEabled)
return ITEM_POWER_BALL;
break;*/
default:
break;
}
@@ -3159,8 +3211,8 @@ void GameDirector::throwCoffee(int x, int y)
mGame.smartSprite[index]->setEnabledTimer(1);
mGame.smartSprite[index]->setSpriteClip(80, 16, 16, 16);
mGame.smartSprite[index]->setRotate(true);
mGame.smartSprite[index]->setRotateSpeed(1);
mGame.smartSprite[index]->setRotateAmount(5.0);
mGame.smartSprite[index]->setRotateSpeed(10);
mGame.smartSprite[index]->setRotateAmount(90.0);
}
// Crea un SmartSprite para arrojar el item café al recibir un impacto
@@ -3346,6 +3398,12 @@ void GameDirector::setTimeStoppedCounter(Uint16 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
void GameDirector::updateTimeStoppedCounter()
{
@@ -4056,7 +4114,7 @@ void GameDirector::enableTimeStopItem()
{
stopAllBalloons(TIME_STOPPED_COUNTER);
setTimeStopped(true);
setTimeStoppedCounter(TIME_STOPPED_COUNTER);
incTimeStoppedCounter(TIME_STOPPED_COUNTER);
if (JA_GetMusicState() == JA_MUSIC_PLAYING)
{
JA_PauseMusic();
@@ -4067,7 +4125,8 @@ void GameDirector::enableTimeStopItem()
void GameDirector::disableTimeStopItem()
{
mGame.timeStopped = false;
mGame.timeStoppedCounter = TIME_STOPPED_COUNTER;
setTimeStoppedCounter(0);
//mGame.timeStoppedCounter = TIME_STOPPED_COUNTER;
startAllBalloons();
if (JA_GetMusicState() == JA_MUSIC_PAUSED)
{
@@ -4634,9 +4693,7 @@ void GameDirector::runTitle(Uint8 subsection)
mTitle.coffeeBitmap->render();
mTitle.crisisBitmap->render();
if (mTitle.menuVisible == true)
{
mMenu.active->render();
}
mTitle.dustBitmapR->animate(0);
mTitle.dustBitmapL->animate(0);
mTitle.dustBitmapR->render();
@@ -4673,27 +4730,36 @@ void GameDirector::runTitle(Uint8 subsection)
{
switch (mMenu.active->getItemSelected())
{
case 0:
setProgSection(PROG_SECTION_GAME);
case 0: // PLAY
JA_PlaySound(mSound[SOUND_MENU_SELECT].sound);
mMenu.active->reset();
mMenu.keyPressed = false;
JA_PlaySound(mSound[SOUND_MENU_SELECT].sound);
setProgSection(PROG_SECTION_GAME);
renderFade(1);
JA_StopMusic();
disableDemoMode();
break;
case 1:
case 1: // OPTIONS
JA_PlaySound(mSound[SOUND_MENU_SELECT].sound);
mMenu.active->reset();
mMenu.keyPressed = false;
mMenu.active = mMenu.options;
mOptions.fullScreenModePrevious = mOptions.fullScreenMode;
mOptions.windowSizePrevious = mOptions.windowSize;
break;
case 2:
mProg.quit = true;
case 2: // HOW TO PLAY
JA_PlaySound(mSound[SOUND_MENU_SELECT].sound);
mMenu.active->reset();
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);
mMenu.active->reset();
mMenu.keyPressed = false;
mProg.quit = true;
renderFade(1);
JA_StopMusic();
break;
@@ -4761,7 +4827,7 @@ void GameDirector::runTitle(Uint8 subsection)
// Sección Instrucciones
if (mTitle.section == TITLE_SECTION_INSTRUCTIONS)
runInstructions();
runInstructions(MODE_AUTO);
}
quitTitle();
@@ -4879,7 +4945,9 @@ void GameDirector::runGame()
// Volca el contenido de la textura en el renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL);
// Pinta la informacion de debug
renderDebugInfo();
// Actualiza la pantalla
SDL_RenderPresent(mRenderer);
}
@@ -4965,22 +5033,22 @@ void GameDirector::runPausedGame()
}
// Bucle para la pantalla de instrucciones
void GameDirector::runInstructions()
void GameDirector::runInstructions(Uint8 mode)
{
SDL_Rect window = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
Sprite *sprite = new Sprite();
SDL_Rect rect1 = {60, 88, 16, 16}; // Disquito
SDL_Rect rect2 = {60, 104, 16, 16}; // Gavineixon
SDL_Rect rect3 = {60, 120, 16, 16}; // Pacmar
SDL_Rect rect4 = {60, 136, 16, 16}; // Time Stopper
SDL_Rect rect5 = {60, 152, 16, 16}; // Explosive
SDL_Rect rect6 = {60, 168, 16, 16}; // Coffee
SDL_Rect rect = {0, 0, 16, 16};
sprite->init(rect1, mTexture[TEXTURE_ITEMS].texture, mRenderer);
SDL_Rect srcRect = {0, 0, 16, 16};
const SDL_Rect destRect1 = {60, 88 + (16 * 0), 16, 16}; // Disquito
const SDL_Rect destRect2 = {60, 88 + (16 * 1), 16, 16}; // Gavineixon
const SDL_Rect destRect3 = {60, 88 + (16 * 2), 16, 16}; // Pacmar
const SDL_Rect destRect4 = {60, 88 + (16 * 3), 16, 16}; // Time Stopper
const SDL_Rect destRect5 = {60, 88 + (16 * 4), 16, 16}; // Coffee
sprite->init(destRect1, mTexture[TEXTURE_ITEMS].texture, mRenderer);
while ((mTitle.section == TITLE_SECTION_INSTRUCTIONS) && (!exit()))
{
int y = 0;
// Comprueba los eventos que hay en la cola
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, 124, "5.000 POINTS", 0);
mText.white->write(84, 140, "TIME STOPPER", 0);
mText.white->write(84, 156, "FOUR EXPLOSIONS", 0);
mText.white->write(84, 172, "EXTRA HIT", 0);
mText.white->write(84, 156, "EXTRA HIT", 0);
sprite->init(rect1, mTexture[TEXTURE_ITEMS].texture, mRenderer);
sprite->setSpriteClip(rect);
rect.x += rect.w;
rect.y = 16 * (((mTitle.instructionsCounter + 3) / 36) % 2);
sprite->render();
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);
// Disquito
sprite->init(destRect1, mTexture[TEXTURE_ITEMS].texture, mRenderer);
srcRect.x = 0;
srcRect.y = 16 * (((mTitle.instructionsCounter + 0) / 36) % 2);
sprite->setSpriteClip(srcRect);
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);
// Limpia la pantalla
@@ -5053,13 +5125,7 @@ void GameDirector::runInstructions()
SDL_RenderClear(mRenderer);
// Dibuja los objetos
y = SCREEN_HEIGHT - (INSTRUCTIONS_COUNTER - mTitle.instructionsCounter) + 100;
if (y < 0)
{
y = 0;
}
window.y = y;
window.y = std::max(0, SCREEN_HEIGHT - (INSTRUCTIONS_COUNTER - mTitle.instructionsCounter) + 100);
SDL_RenderCopy(mRenderer, mInstructionsSurface, NULL, &window);
// Muestra la pantalla
@@ -5069,9 +5135,17 @@ void GameDirector::runInstructions()
if (mTitle.instructionsCounter == 0)
{
mTitle.instructionsCounter = INSTRUCTIONS_COUNTER;
mTitle.section = TITLE_SECTION_1;
resetTitle(TITLE_SECTION_1);
mTitle.section = TITLE_SECTION_3;
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;
@@ -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 + 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;
}