diff --git a/source/director.cpp b/source/director.cpp index da3d6f7..8eeb657 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -448,28 +448,23 @@ void Director::runGame() void Director::run() { - const std::string text = "españa"; - printf("lenght = %d\n", text.length()); - for (int i = 0; i < text.length(); i++) - printf("%d - %d\n", i, (unsigned int)text[i]); - // Bucle principal - //while (!(getSection() == PROG_SECTION_QUIT)) - //{ - // switch (getSection()) - // { - // case PROG_SECTION_LOGO: - // runLogo(); - // break; - // case PROG_SECTION_INTRO: - // runIntro(); - // break; - // case PROG_SECTION_TITLE: - // runTitle(); - // break; - // case PROG_SECTION_GAME: - // runGame(); - // break; - // } - //} + while (!(getSection() == PROG_SECTION_QUIT)) + { + switch (getSection()) + { + case PROG_SECTION_LOGO: + runLogo(); + break; + case PROG_SECTION_INTRO: + runIntro(); + break; + case PROG_SECTION_TITLE: + runTitle(); + break; + case PROG_SECTION_GAME: + runGame(); + break; + } + } } \ No newline at end of file diff --git a/source/game.cpp b/source/game.cpp index a3e692b..17f2d96 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -240,13 +240,15 @@ void Game::init() mTicksSpeed = 15; // Inicializa las variables + mGameCompleted = false; + mGameCompletedCounter = 0; mSection.name = PROG_SECTION_GAME; mSection.subsection = GAME_SECTION_PLAY; mMenaceCurrent = 0; mMenaceThreshold = 0; mScore = 0; mHiScoreAchieved = false; - mCurrentStage = 0; + mCurrentStage = 9; mStageBitmapCounter = STAGE_COUNTER; mDeathCounter = DEATH_COUNTER; mExplosionTime = false; @@ -287,7 +289,7 @@ void Game::init() initGameStages(); // Modo debug - mDebug.enabled = false; + mDebug.enabled = true; mDebug.enemySet = 0; mDebug.gradR = mDebug.gradG = mDebug.gradB = 0; @@ -295,6 +297,9 @@ void Game::init() mDemo.recording = false; mDemo.counter = 0; + // Iniciualiza el objeto para el fundido + mFade->init(); + // Inicializa los objetos de texto mText->init(TEXT_FIXED, BLOCK); mTextX2->init(TEXT_FIXED, BLOCK * 2); @@ -353,7 +358,7 @@ void Game::init() resetBalloons(); // Con los globos creados, calcula el nivel de amenaza - setMenace(); + evaluateAndSetMenace(); // Establece a cero todos los valores del vector de objetos bala resetBullets(); @@ -1343,7 +1348,7 @@ void Game::initGameStages() // STAGE 10 mStage[9].number = 10; - mStage[9].currentPower = 0; + mStage[9].currentPower = 900; mStage[9].powerToComplete = 950; mStage[9].minMenace = 7 + (4 * 9); mStage[9].maxMenace = 7 + (4 * 15); @@ -1546,6 +1551,16 @@ void Game::updateStage() { // Cambio de fase mCurrentStage++; + if (mCurrentStage == 10) + { + mGameCompleted = true; // Marca el juego como completado + mCurrentStage = 9; // Deja el valor dentro de los limites + mStage[mCurrentStage].currentPower = 0; // Deja el poder a cero para que no vuelva a entrar en esta condición + destroyAllBalloons(); // Destruye a todos los enemigos + mStage[mCurrentStage].currentPower = 0; // Vuelve a dejar el poder a cero, por lo que hubiera podido subir al destruir todos lo globos + mMenaceCurrent = 255; + JA_StopMusic(); + } JA_PlaySound(mSoundStageChange); mStageBitmapCounter = 0; mEnemySpeed = BALLOON_SPEED_1; @@ -1554,8 +1569,14 @@ void Game::updateStage() mEffect.shake = true; } + // Incrementa el contador del bitmap que aparece mostrando el cambio de fase if (mStageBitmapCounter < STAGE_COUNTER) mStageBitmapCounter++; + + // Si el juego se ha completado, el bitmap se detiene en el centro de la pantalla + if (mGameCompleted) + if (mStageBitmapCounter > 100) + mStageBitmapCounter = 100; } // Actualiza el estado de muerte @@ -1623,13 +1644,13 @@ void Game::updateDeath() } // Renderiza el fade final cuando se acaba la partida -void Game::renderDeathFade() +void Game::renderDeathFade(bool trigger, int counter) { - if (!mPlayer->isAlive() && (mDeathCounter < 150)) + if ((trigger) && (counter < 150)) { // 192 / 6 = 32, 6 cuadrados de 32 pixeles SDL_Rect rect[12]; - Uint8 h = (150 - mDeathCounter) / 3; + Uint8 h = counter / 3; SDL_SetRenderDrawColor(mRenderer, 0x27, 0x27, 0x36, 255); for (int i = 0; i < 12; i++) { @@ -1823,7 +1844,7 @@ void Game::popBalloon(Uint8 index) } // Recalcula el nivel de amenaza - setMenace(); + evaluateAndSetMenace(); } // Explosiona un globo. Lo destruye @@ -1874,7 +1895,7 @@ void Game::destroyBalloon(Uint8 index) mBalloon[index]->pop(); // Recalcula el nivel de amenaza - setMenace(); + evaluateAndSetMenace(); } // Explosiona todos los globos @@ -1891,9 +1912,11 @@ void Game::popAllBalloons() void Game::destroyAllBalloons() { for (int i = 0; i < MAX_BALLOONS; i++) - if ((mBalloon[i]->isEnabled()) && (!mBalloon[i]->isPopping()) && (!mBalloon[i]->isBeingCreated())) + //if ((mBalloon[i]->isEnabled()) && (!mBalloon[i]->isPopping()) && (!mBalloon[i]->isBeingCreated())) + if ((mBalloon[i]->isEnabled()) && (!mBalloon[i]->isPopping())) destroyBalloon(i); + mEnemyDeployCounter = 255; JA_PlaySound(mSoundPowerBall); mEffect.flash = true; mEffect.shake = true; @@ -2009,7 +2032,7 @@ void Game::checkBulletBalloonCollision() if (!mDemo.enabled) JA_PlaySound(mSoundBalloon); mBullet[j]->erase(); - setMenace(); + evaluateAndSetMenace(); const Uint8 droppeditem = dropItem(); if ((droppeditem != NO_KIND) && !(mDemo.enabled) && !(mDemo.recording)) { @@ -2276,7 +2299,7 @@ void Game::killPlayer() } // Calcula y establece el valor de amenaza en funcion de los globos activos -void Game::setMenace() +void Game::evaluateAndSetMenace() { mMenaceCurrent = 0; for (int i = 0; i < MAX_BALLOONS; i++) @@ -2419,14 +2442,18 @@ void Game::updatePlayField() // Comprueba las colisiones entre globos y balas checkBulletBalloonCollision(); - // Comprueba las colisiones entre elk jugador y los items + // Comprueba las colisiones entre el jugador y los items checkPlayerItemCollision(); - // Comprueba el nivel de amenaza - updateMenace(); + // Comprueba el nivel de amenaza para ver si se han de crear nuevos enemigos + if (!mGameCompleted) + updateMenace(); // Actualiza la velocidad de los enemigos updateBalloonSpeed(); + + // Actualiza el tramo final de juego, una vez completado + updateGameCompleted(); } // Actualiza el fondo @@ -2494,7 +2521,7 @@ void Game::renderPlayField() renderSmartSprites(); mPlayer->render(); renderMessages(); - renderDeathFade(); + renderDeathFade(!mPlayer->isAlive(), 150 - mDeathCounter); renderScoreBoard(); renderFlashEffect(); } @@ -2515,7 +2542,7 @@ void Game::updateMenace() deployEnemyFormation(); // Recalcula el nivel de amenaza con el nuevo globo - setMenace(); + evaluateAndSetMenace(); } } @@ -2704,8 +2731,12 @@ void Game::renderMessages() mTextX2->writeDX(TXT_CENTER | TXT_SHADOW, PLAY_AREA_CENTER_X, PLAY_AREA_FIRST_QUARTER_Y, mTextStrings[37], 0, noColor, 2, shdwTxtColor); // STAGE NUMBER + std::string text = mTextStrings[38] + std::to_string(mStage[mCurrentStage].number); + if (mGameCompleted) // Texto de juego completado + text = mTextStrings[50]; + if (mStageBitmapCounter < STAGE_COUNTER) - mTextX2->writeDX(TXT_CENTER | TXT_SHADOW, PLAY_AREA_CENTER_X, mStageBitmapPath[mStageBitmapCounter], mTextStrings[38] + std::to_string(mStage[mCurrentStage].number), 0, noColor, 2, shdwTxtColor); + mTextX2->writeDX(TXT_CENTER | TXT_SHADOW, PLAY_AREA_CENTER_X, mStageBitmapPath[mStageBitmapCounter], text, 0, noColor, 2, shdwTxtColor); } // Habilita el efecto del item de detener el tiempo @@ -2788,8 +2819,9 @@ section_t Game::run() if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) { // Reproduce la música - if (mPlayer->isAlive()) - JA_PlayMusic(mMusicPlaying); + if (!mGameCompleted) + if (mPlayer->isAlive()) + JA_PlayMusic(mMusicPlaying); } // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego @@ -3000,14 +3032,12 @@ void Game::runGameOverScreen() case 0: // YES mSection.name = PROG_SECTION_GAME; mSection.subsection = GAME_SECTION_PLAY; - //JA_StopMusic(); init(); break; case 1: // NO mSection.name = PROG_SECTION_TITLE; mSection.subsection = TITLE_SECTION_1; - //JA_StopMusic(); break; default: @@ -3065,14 +3095,15 @@ void Game::renderDebugInfo() mText->writeShadowed(2, 2 + 0 * BLOCK, "menace(umb): " + std::to_string(mMenaceCurrent) + "(" + std::to_string(mMenaceThreshold) + ")", color); mText->writeShadowed(2, 2 + 1 * BLOCK, "currentPower: " + std::to_string(mStage[mCurrentStage].currentPower), color); - mText->writeShadowed(2, 2 + 2 * BLOCK, "mCurrentStage: " + std::to_string(mCurrentStage), color); - mText->writeShadowed(2, 2 + 3 * BLOCK, "mCounter: " + std::to_string(mCounter), color); + mText->writeShadowed(2, 2 + 2 * BLOCK, "mCurrentStage:" + std::to_string(mCurrentStage), color); + mText->writeShadowed(2, 2 + 3 * BLOCK, "mCounter: " + std::to_string(mCounter), color); mText->writeShadowed(2, 2 + 4 * BLOCK, "(R)enemyset: " + std::to_string(mDebug.enemySet), color); mText->writeShadowed(2, 2 + 5 * BLOCK, "RGB: " + std::to_string(mDebug.gradR) + "," + std::to_string(mDebug.gradG) + "," + std::to_string(mDebug.gradB), color); - mText->writeShadowed(2, 2 + 6 * BLOCK, "(I)invuln : " + std::to_string(mPlayer->getInvulnerableCounter()), color); + mText->writeShadowed(2, 2 + 6 * BLOCK, "(I)invuln: " + std::to_string(mPlayer->getInvulnerableCounter()), color); mText->writeShadowed(2, 2 + 7 * BLOCK, "balloons: " + std::to_string(countBalloons()), color); mText->writeShadowed(2, 2 + 8 * BLOCK, "balloonsPop: " + std::to_string(mBalloonsPopped), color); mText->writeShadowed(2, 2 + 9 * BLOCK, "(Z-X)ballSped:" + std::to_string(mEnemySpeed), color); + mText->writeShadowed(2, 2 + 10 * BLOCK, "EGcounter: " + std::to_string(mGameCompletedCounter), color); } } @@ -3144,3 +3175,13 @@ void Game::initPaths() } } } + +// Actualiza el tramo final de juego, una vez completado +void Game::updateGameCompleted() +{ + if (mGameCompleted) + mGameCompletedCounter++; + + if (mGameCompletedCounter >= 300) + renderDeathFade(mGameCompleted, 300 - mGameCompletedCounter); +} \ No newline at end of file diff --git a/source/game.h b/source/game.h index 54840ce..671c25b 100644 --- a/source/game.h +++ b/source/game.h @@ -159,8 +159,9 @@ private: effect_t mEffect; // Variable para gestionar los efectos visuales bool mPowerBallEnabled; // Indica si hay una powerball ya activa Uint8 mPostFade; // Qué hacer al acabar el fade - Uint8 mNextProgSection; - float mSin[360]; // Vector con los valores del seno para 360 grados + float mSin[360]; // Vector con los valores del seno para 360 grados + bool mGameCompleted; // Indica si se ha completado la partida, llegando al final de la ultima pantalla + int mGameCompletedCounter; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos struct demo_t { @@ -249,7 +250,7 @@ public: void updateDeath(); // Renderiza el fade final cuando se acaba la partida - void renderDeathFade(); + void renderDeathFade(bool trigger, int counter); // Actualiza los globos void updateBalloons(); @@ -378,7 +379,7 @@ public: Uint8 getSubsection(); // Calcula y establece el valor de amenaza en funcion de los globos activos - void setMenace(); + void evaluateAndSetMenace(); // Obtiene el valor de la variable Uint8 getMenace(); @@ -466,6 +467,9 @@ public: // Inicializa las variables que contienen puntos de ruta para mover objetos void initPaths(); + + // Actualiza el tramo final de juego, una vez completado + void updateGameCompleted(); }; #endif diff --git a/source/lang.h b/source/lang.h index 3a65dcf..621da69 100644 --- a/source/lang.h +++ b/source/lang.h @@ -265,6 +265,11 @@ const std::string gTextStrings[MAX_TEXT_STRINGS][3] = "NO", "NO"}, + // 50 - TEXTO DE COMPLETAR EL JUEGO + {"FELICIDADES!!", + "FELICITATS!!", + "CONGRATULATIONS!!"}, + }; void initTextStrings(std::string *textStrings, Uint8 lang);