From 4df0db088f000667989edaf0fc8aa740d402d933 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 25 Sep 2022 20:10:31 +0200 Subject: [PATCH] =?UTF-8?q?Organizaci=C3=B3n=20de=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- media/lang/ba_BA.txt | 2 +- source/game.cpp | 246 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 236 insertions(+), 12 deletions(-) diff --git a/media/lang/ba_BA.txt b/media/lang/ba_BA.txt index ac7b3f6..c87bfe3 100644 --- a/media/lang/ba_BA.txt +++ b/media/lang/ba_BA.txt @@ -113,7 +113,7 @@ mult ## 56 MARCADOR max. puntuacio ## 57 MARCADOR -pantalla +fase ## 58 - MENU DE OPCIONES MODE DE VISUALITZACIO ## 59 - MENU DE OPCIONES diff --git a/source/game.cpp b/source/game.cpp index f8a46f5..6b5f08e 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -16,20 +16,36 @@ Game::Game(int numPlayers, SDL_Renderer *renderer, Screen *screen, std::string * mDemo.enabled = demo; mNumPlayers = numPlayers; if (mNumPlayers == 1) + { mOptions->input[0].deviceType = INPUT_USE_ANY; + } mDifficulty = mOptions->difficulty; // Crea los objetos for (int i = 0; i < mNumPlayers; i++) + { mPlayer[i] = new Player(); + } + for (int i = 0; i < MAX_BALLOONS; i++) + { mBalloon[i] = new Balloon(); + } + for (int i = 0; i < MAX_BULLETS; i++) + { mBullet[i] = new Bullet(); + } + for (int i = 0; i < MAX_ITEMS; i++) + { mItem[i] = new Item(); + } + for (int i = 0; i < MAX_SMART_SPRITES; i++) + { mSmartSprite[i] = new SmartSprite(); + } mTextureBalloon = new LTexture(); mTextureBullet = new LTexture(); @@ -1923,22 +1939,33 @@ void Game::updateBalloonSpeed() if (mEnemySpeed == BALLOON_SPEED_1) { if (percent > 0.2f) + { incBalloonSpeed(); + } } + else if (mEnemySpeed == BALLOON_SPEED_2) { if (percent > 0.4f) + { incBalloonSpeed(); + } } + else if (mEnemySpeed == BALLOON_SPEED_3) { if (percent > 0.6f) + { incBalloonSpeed(); + } } + else if (mEnemySpeed == BALLOON_SPEED_4) { if (percent > 0.8f) + { incBalloonSpeed(); + } } } @@ -1975,17 +2002,25 @@ void Game::popBalloon(Uint8 index) mBalloon[freeIndex]->init(0, mBalloon[index]->getPosY(), mBalloon[index]->getKind() - 1, BALLOON_VELX_NEGATIVE, mEnemySpeed, 0, mTextureBalloon, mRenderer); mBalloon[freeIndex]->allignTo(mBalloon[index]->getPosX() + (mBalloon[index]->getWidth() / 2)); if (mBalloon[freeIndex]->getClass() == BALLOON_CLASS) + { mBalloon[freeIndex]->setVelY(-2.50f); + } else if (mBalloon[freeIndex]->getClass() == HEXAGON_CLASS) + { mBalloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE); + } freeIndex = getBalloonFreeIndex(); mBalloon[freeIndex]->init(0, mBalloon[index]->getPosY(), mBalloon[index]->getKind() - 1, BALLOON_VELX_POSITIVE, mEnemySpeed, 0, mTextureBalloon, mRenderer); mBalloon[freeIndex]->allignTo(mBalloon[index]->getPosX() + (mBalloon[index]->getWidth() / 2)); if (mBalloon[freeIndex]->getClass() == BALLOON_CLASS) + { mBalloon[freeIndex]->setVelY(-2.50f); + } else if (mBalloon[freeIndex]->getClass() == HEXAGON_CLASS) + { mBalloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE); + } // Elimina el globo mBalloon[index]->pop(); @@ -2033,7 +2068,9 @@ void Game::destroyBalloon(Uint8 index) // Otorga los puntos correspondientes al globo for (int i = 0; i < mNumPlayers; i++) + { mPlayer[i]->addScore(Uint32(score * mPlayer[i]->getScoreMultiplier() * mDifficultyScoreMultiplier)); + } updateHiScore(); // Aumenta el poder de la fase @@ -2051,8 +2088,12 @@ void Game::destroyBalloon(Uint8 index) void Game::popAllBalloons() { for (int i = 0; i < MAX_BALLOONS; i++) + { if ((mBalloon[i]->isEnabled()) && (!mBalloon[i]->isPopping()) && (!mBalloon[i]->isBeingCreated())) + { popBalloon(i); + } + } JA_PlaySound(mSoundBalloon); } @@ -2061,9 +2102,12 @@ 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())) + { destroyBalloon(i); + } + } mEnemyDeployCounter = 255; JA_PlaySound(mSoundPowerBall); @@ -2075,22 +2119,26 @@ void Game::destroyAllBalloons() void Game::stopAllBalloons(Uint16 time) { for (int i = 0; i < MAX_BALLOONS; i++) + { if (mBalloon[i]->isEnabled()) { mBalloon[i]->setStop(true); mBalloon[i]->setStoppedTimer(time); } + } } // Pone en marcha todos los globos void Game::startAllBalloons() { for (int i = 0; i < MAX_BALLOONS; i++) + { if ((mBalloon[i]->isEnabled()) && (!mBalloon[i]->isBeingCreated())) { mBalloon[i]->setStop(false); mBalloon[i]->setStoppedTimer(0); } + } } // Obtiene el numero de globos activos @@ -2099,9 +2147,15 @@ Uint8 Game::countBalloons() Uint8 num = 0; for (int i = 0; i < MAX_BALLOONS; i++) + { if (mBalloon[i]->isEnabled()) + { if (!mBalloon[i]->isPopping()) + { num++; + } + } + } return num; } @@ -2110,9 +2164,15 @@ Uint8 Game::countBalloons() bool Game::checkPlayerBalloonCollision(int index) { for (int i = 0; i < MAX_BALLOONS; i++) + { if ((mBalloon[i]->isEnabled()) && !(mBalloon[i]->isStopped()) && !(mBalloon[i]->isInvulnerable())) + { if (checkCollision(mPlayer[index]->getCollider(), mBalloon[i]->getCollider())) + { return true; + } + } + } return false; } @@ -2180,8 +2240,11 @@ void Game::checkPlayerItemCollision(int index) void Game::checkBulletBalloonCollision() { for (int i = 0; i < MAX_BALLOONS; i++) + { for (int j = 0; j < MAX_BULLETS; j++) + { if (mBalloon[i]->isEnabled() && (!mBalloon[i]->isInvulnerable()) && mBullet[j]->isActive()) + { if (checkCollision(mBalloon[i]->getCollider(), mBullet[j]->getCollider())) { // Otorga los puntos correspondientes al globo al jugador que disparó la bala @@ -2195,7 +2258,9 @@ void Game::checkBulletBalloonCollision() // Si no es el modo demo, genera un sonido if (!mDemo.enabled) + { JA_PlaySound(mSoundBalloon); + } // Destruye la bala mBullet[j]->erase(); @@ -2217,31 +2282,48 @@ void Game::checkBulletBalloonCollision() } break; } + } + } + } } // Mueve las balas activas void Game::moveBullets() { for (int i = 0; i < MAX_BULLETS; i++) + { if (mBullet[i]->isActive()) + { if (mBullet[i]->move() == BULLET_MOVE_OUT) + { mPlayer[mBullet[i]->getOwner()]->decScoreMultiplier(); + } + } + } } // Pinta las balas activas void Game::renderBullets() { for (int i = 0; i < MAX_BULLETS; i++) + { if (mBullet[i]->isActive()) + { mBullet[i]->render(); + } + } } // Devuelve el primer indice no activo del vector de balas Uint8 Game::getBulletFreeIndex() { for (int i = 0; i < MAX_BULLETS; i++) + { if (mBullet[i]->isActive() == false) + { return i; + } + } return 0; } @@ -2250,7 +2332,9 @@ Uint8 Game::getBulletFreeIndex() void Game::resetBullets() { for (int i = 0; i < MAX_BULLETS; i++) + { mBullet[i]->erase(); + } } // Crea un objeto bala @@ -2277,15 +2361,21 @@ void Game::updateItems() void Game::renderItems() { for (int i = 0; i < MAX_ITEMS; i++) + { mItem[i]->render(); + } } // Devuelve el primer indice no activo del vector de items Uint8 Game::getItemFreeIndex() { for (int i = 0; i < MAX_ITEMS; i++) + { if (mItem[i]->getClass() == NO_KIND) + { return i; + } + } return 0; } @@ -2294,7 +2384,9 @@ Uint8 Game::getItemFreeIndex() void Game::resetItems() { for (int i = 0; i < MAX_ITEMS; i++) + { mItem[i]->erase(); + } } // Devuelve un item en función del azar @@ -2309,18 +2401,22 @@ Uint8 Game::dropItem() if (luckyNumber < mHelper.itemPoints1Odds) return ITEM_POINTS_1_DISK; break; + case 1: if (luckyNumber < mHelper.itemPoints2Odds) return ITEM_POINTS_2_GAVINA; break; + case 2: if (luckyNumber < mHelper.itemPoints3Odds) return ITEM_POINTS_3_PACMAR; break; + case 3: if (luckyNumber < mHelper.itemClockOdds) return ITEM_CLOCK; break; + case 4: if (luckyNumber < mHelper.itemCoffeeOdds) { @@ -2330,22 +2426,30 @@ Uint8 Game::dropItem() else { if (mHelper.needCoffee) + { mHelper.itemCoffeeOdds++; + } } break; + case 5: if (luckyNumber < mHelper.itemCoffeeMachineOdds) { mHelper.itemCoffeeMachineOdds = ITEM_COFFEE_MACHINE_ODDS; if ((!mCoffeeMachineEnabled) && (mHelper.needCoffeeMachine)) + { return ITEM_COFFEE_MACHINE; + } } else { if (mHelper.needCoffeeMachine) + { mHelper.itemCoffeeMachineOdds++; + } } break; + default: break; } @@ -2393,7 +2497,9 @@ void Game::updateShakeEffect() if (mEffect.shake) { if (mEffect.shakeCounter > 0) + { mEffect.shakeCounter--; + } else { mEffect.shake = false; @@ -2452,22 +2558,30 @@ void Game::throwPlayer(int x, int y, int index) void Game::updateSmartSprites() { for (int i = 0; i < MAX_SMART_SPRITES; i++) + { mSmartSprite[i]->update(); + } } // Pinta los SmartSprites activos void Game::renderSmartSprites() { for (int i = 0; i < MAX_SMART_SPRITES; i++) + { mSmartSprite[i]->render(); + } } // Devuelve el primer indice no activo del vector de SmartSprites Uint8 Game::getSmartSpriteFreeIndex() { for (int i = 0; i < MAX_SMART_SPRITES; i++) + { if (!mSmartSprite[i]->isEnabled()) + { return i; + } + } return 0; } @@ -2476,7 +2590,9 @@ Uint8 Game::getSmartSpriteFreeIndex() void Game::resetSmartSprites() { for (int i = 0; i < MAX_SMART_SPRITES; i++) + { mSmartSprite[i]->erase(); + } } // Acciones a realizar cuando el jugador muere @@ -2501,9 +2617,13 @@ void Game::killPlayer(int index) throwPlayer(mPlayer[index]->getPosX(), mPlayer[index]->getPosY(), index); mPlayer[index]->setAlive(false); if (allPlayersAreDead()) + { JA_StopMusic(); + } else + { JA_ResumeMusic(); + } } } } @@ -2513,8 +2633,12 @@ void Game::evaluateAndSetMenace() { mMenaceCurrent = 0; for (int i = 0; i < MAX_BALLOONS; i++) + { if (mBalloon[i]->isEnabled()) + { mMenaceCurrent += mBalloon[i]->getMenace(); + } + } } // Obtiene el valor de la variable @@ -2610,7 +2734,9 @@ void Game::updateRemainingExplosionsCounter() void Game::updateEnemyDeployCounter() { if (mEnemyDeployCounter > 0) + { mEnemyDeployCounter--; + } } // Actualiza el campo de juego @@ -2657,7 +2783,9 @@ void Game::updatePlayField() // Comprueba el nivel de amenaza para ver si se han de crear nuevos enemigos if (!mGameCompleted) + { updateMenace(); + } // Actualiza la velocidad de los enemigos updateBalloonSpeed(); @@ -2675,23 +2803,35 @@ void Game::updateBackground() mClouds2b->move(); if (mClouds1a->getPosX() < -mClouds1a->getWidth()) + { mClouds1a->setPosX(mClouds1a->getWidth()); + } if (mClouds1b->getPosX() < -mClouds1b->getWidth()) + { mClouds1b->setPosX(mClouds1b->getWidth()); + } if (mClouds2a->getPosX() < -mClouds2a->getWidth()) + { mClouds2a->setPosX(mClouds2a->getWidth()); + } if (mClouds2b->getPosX() < -mClouds2b->getWidth()) + { mClouds2b->setPosX(mClouds2b->getWidth()); + } mSpriteGrass->setSpriteClip(256, 85 + (6 * (mCounter / 20 % 2)), SCREEN_WIDTH, 6); if (mEffect.shake) + { mSpriteBackground->setPosX(((mEffect.shakeCounter % 2) * 2) - 1); + } else + { mSpriteBackground->setPosX(0); + } } // Dibuja el fondo @@ -2731,12 +2871,22 @@ void Game::renderPlayField() renderItems(); renderSmartSprites(); renderScoreBoard(); + for (int i = 0; i < mNumPlayers; i++) + { mPlayer[i]->render(); + } + if ((mDeathCounter <= 150) && !mPlayer[0]->isAlive()) + { renderDeathFade(150 - mDeathCounter); + } + if ((mGameCompleted) && (mGameCompletedCounter >= 300)) + { renderDeathFade(mGameCompletedCounter - 300); + } + renderFlashEffect(); } @@ -2775,51 +2925,70 @@ void Game::checkGameInput() { const int index = 0; if (mDemo.dataFile[mDemo.counter].left == 1) + { mPlayer[index]->setInput(INPUT_LEFT); + } if (mDemo.dataFile[mDemo.counter].right == 1) + { mPlayer[index]->setInput(INPUT_RIGHT); + } if (mDemo.dataFile[mDemo.counter].noInput == 1) + { mPlayer[index]->setInput(INPUT_NULL); + } if (mDemo.dataFile[mDemo.counter].fire == 1) + { if (mPlayer[index]->canFire()) { mPlayer[index]->setInput(INPUT_BUTTON_2); createBullet(mPlayer[index]->getPosX() + (mPlayer[index]->getWidth() / 2) - 4, mPlayer[index]->getPosY() + (mPlayer[index]->getHeight() / 2), BULLET_UP, mPlayer[index]->isPowerUp(), index); mPlayer[index]->setFireCooldown(10); } - + } if (mDemo.dataFile[mDemo.counter].fireLeft == 1) + { if (mPlayer[index]->canFire()) { mPlayer[index]->setInput(INPUT_BUTTON_1); createBullet(mPlayer[index]->getPosX() + (mPlayer[index]->getWidth() / 2) - 4, mPlayer[index]->getPosY() + (mPlayer[index]->getHeight() / 2), BULLET_UP, mPlayer[index]->isPowerUp(), index); mPlayer[index]->setFireCooldown(10); } + } if (mDemo.dataFile[mDemo.counter].fireRight == 1) + { if (mPlayer[index]->canFire()) { mPlayer[index]->setInput(INPUT_BUTTON_3); createBullet(mPlayer[index]->getPosX() + (mPlayer[index]->getWidth() / 2) - 4, mPlayer[index]->getPosY() + (mPlayer[index]->getHeight() / 2), BULLET_UP, mPlayer[index]->isPowerUp(), index); mPlayer[index]->setFireCooldown(10); } + } // Comprueba el input de pausa if (mInput->checkInput(INPUT_BUTTON_PAUSE, REPEAT_FALSE)) + { mSection.name = PROG_SECTION_TITLE; + } // Incrementa el contador de la demo if (mDemo.counter < TOTAL_DEMO_DATA) + { mDemo.counter++; + } else + { mSection = {PROG_SECTION_TITLE, TITLE_SECTION_INSTRUCTIONS}; + } } // Modo Demo no activo else + { for (int i = 0; i < mNumPlayers; i++) + { if (mPlayer[i]->isAlive()) { // Input a la izquierda @@ -2897,13 +3066,17 @@ void Game::checkGameInput() mSection.subsection = GAME_SECTION_PAUSE; if (JA_GetMusicState() == JA_MUSIC_PLAYING) + { JA_PauseMusic(); + } } if (mDemo.counter < TOTAL_DEMO_DATA) { if (mDemo.recording) + { mDemo.dataFile[mDemo.counter] = mDemo.keys; + } mDemo.counter++; } else if (mDemo.recording) @@ -2911,6 +3084,8 @@ void Game::checkGameInput() mSection.name = PROG_SECTION_QUIT; } } + } + } } // Pinta diferentes mensajes en la pantalla @@ -2991,7 +3166,9 @@ void Game::enableTimeStopItem() setTimeStopped(true); incTimeStoppedCounter(TIME_STOPPED_COUNTER); if (JA_GetMusicState() == JA_MUSIC_PLAYING) + { JA_PauseMusic(); + } } // Deshabilita el efecto del item de detener el tiempo @@ -3001,7 +3178,9 @@ void Game::disableTimeStopItem() setTimeStoppedCounter(0); startAllBalloons(); if (JA_GetMusicState() == JA_MUSIC_PAUSED) + { JA_ResumeMusic(); + } } // Agita la pantalla @@ -3010,10 +3189,6 @@ void Game::shakeScreen() const int v[] = {-1, 1, -1, 1, -1, 1, -1, 0}; for (int n = 0; n < 8; n++) { - // Limpia la pantalla - // SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF); - // SDL_RenderClear(mRenderer); - // Prepara para empezar a dibujar en la textura de juego mScreen->start(); @@ -3040,12 +3215,11 @@ void Game::shakeScreen() renderBullets(); renderItems(); for (int i = 0; i < mNumPlayers; i++) + { mPlayer[i]->render(); + } renderScoreBoard(); - // Actualiza la pantalla - // SDL_RenderPresent(mRenderer); - // Vuelca el contenido del renderizador en pantalla mScreen->blit(); SDL_Delay(50); @@ -3061,11 +3235,15 @@ section_t Game::run() { // Sección juego en pausa if (mSection.subsection == GAME_SECTION_PAUSE) + { runPausedGame(); + } // Sección Game Over if (mSection.subsection == GAME_SECTION_GAMEOVER) + { runGameOverScreen(); + } // Sección juego jugando if ((mSection.subsection == GAME_SECTION_PLAY_1P) || (mSection.subsection == GAME_SECTION_PLAY_2P)) @@ -3075,8 +3253,12 @@ section_t Game::run() { // Reproduce la música if (!mGameCompleted) + { if (mPlayer[0]->isAlive()) + { JA_PlayMusic(mMusicPlaying); + } + } } // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego @@ -3182,12 +3364,20 @@ void Game::runPausedGame() { case 0: mSection.name = PROG_SECTION_GAME; + if (mNumPlayers == 1) + { mSection.subsection = GAME_SECTION_PLAY_1P; + } else + { mSection.subsection = GAME_SECTION_PLAY_2P; + } + if (JA_GetMusicState() == JA_MUSIC_PAUSED) + { JA_ResumeMusic(); + } break; case 1: @@ -3238,10 +3428,16 @@ void Game::runGameOverScreen() { case 0: // YES mSection.name = PROG_SECTION_GAME; + if (mNumPlayers == 1) + { mSection.subsection = GAME_SECTION_PLAY_1P; + } else + { mSection.subsection = GAME_SECTION_PLAY_2P; + } + init(); break; @@ -3330,9 +3526,11 @@ void Game::renderDebugInfo() bool Game::canPowerBallBeCreated() { if ((!mPowerBallEnabled) && (calculateScreenPower() > POWERBALL_SCREENPOWER_MINIMUM) && (mPowerBallCounter == 0)) + { return true; - else - return false; + } + + return false; } // Calcula el poder actual de los globos en pantalla @@ -3341,8 +3539,12 @@ int Game::calculateScreenPower() int power = 0; for (int i = 0; i < MAX_BALLOONS; i++) + { if (mBalloon[i]->isEnabled()) + { power += mBalloon[i]->getPower(); + } + } return power; } @@ -3359,11 +3561,17 @@ void Game::initPaths() for (int i = 0; i < STAGE_COUNTER; i++) { if (i < firstPart) + { mStageBitmapPath[i] = (mSin[(int)((i * 1.8f) + 90)] * (distance) + centerPoint); + } else if (i < secondPart) + { mStageBitmapPath[i] = (int)centerPoint; + } else + { mStageBitmapPath[i] = (mSin[(int)(((i - 149) * 1.8f) + 90)] * (centerPoint + 17) - 17); + } } // Letrero de GetReady @@ -3387,7 +3595,9 @@ void Game::initPaths() mGetReadyBitmapPath[i] -= size; } else if (i < secondPart) + { mGetReadyBitmapPath[i] = (int)finish1; + } else { mGetReadyBitmapPath[i] = mSin[(int)((i - 150) * 1.8f)]; @@ -3401,10 +3611,14 @@ void Game::initPaths() void Game::updateGameCompleted() { if (mGameCompleted) + { mGameCompletedCounter++; + } if (mGameCompletedCounter == 500) + { mSection.subsection = GAME_SECTION_GAMEOVER; + } } // Actualiza las variables de ayuda @@ -3416,14 +3630,22 @@ void Game::updateHelper() for (int i = 0; i < mNumPlayers; i++) { if (mPlayer[i]->getCoffees() == 0) + { mHelper.needCoffee = true; + } else + { mHelper.needCoffee = false; + } if (!mPlayer[i]->isPowerUp()) + { mHelper.needCoffeeMachine = true; + } else + { mHelper.needCoffeeMachine = false; + } } } else @@ -3438,7 +3660,9 @@ bool Game::allPlayersAreDead() { bool success = true; for (int i = 0; i < mNumPlayers; i++) + { success &= (!mPlayer[i]->isAlive()); + } return success; } \ No newline at end of file