From ca7ae7418e1252e22a0d4c86d4392bdd1c8fd660 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 9 Oct 2022 11:46:11 +0200 Subject: [PATCH] Arreglado el modo 2P --- data/gfx/menu_game_over_end.png | Bin 0 -> 3844 bytes source/director.cpp | 4 ++ source/game.cpp | 110 +++++++++++++++++++++++--------- source/game.h | 15 +++-- todo.txt | 7 +- 5 files changed, 99 insertions(+), 37 deletions(-) create mode 100644 data/gfx/menu_game_over_end.png diff --git a/data/gfx/menu_game_over_end.png b/data/gfx/menu_game_over_end.png new file mode 100644 index 0000000000000000000000000000000000000000..5e8fe65366ee761c089269860507aec300754c24 GIT binary patch literal 3844 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"data/gfx/intro.png", t_bitmap); asset->add("data/gfx/logo.png", t_bitmap); asset->add("data/gfx/menu_game_over.png", t_bitmap); + asset->add("data/gfx/menu_game_over_end.png", t_bitmap); asset->add("data/gfx/item_points1_disk.png", t_bitmap); asset->add("data/gfx/item_points1_disk.ani", t_data); diff --git a/source/game.cpp b/source/game.cpp index 0ce70b3..e4ca9f5 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -14,7 +14,7 @@ Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *scr // Pasa variables this->demo.enabled = demo; this->numPlayers = numPlayers; - this->currentStage = currentStage; + this->currentStage = 9; // currentStage; lastStageReached = currentStage; if (numPlayers == 1) { // Si solo juega un jugador, permite jugar tanto con teclado como con mando @@ -45,6 +45,7 @@ Game::Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *scr grassSprite = new Sprite(0, 0, 256, 6, gameGrassTexture, renderer); powerMeterSprite = new Sprite(PLAY_AREA_CENTER_X - 20, 170, 40, 7, gamePowerMeterTexture, renderer); gameOverSprite = new Sprite(16, 80, 128, 96, gameOverTexture, renderer); + gameOverEndSprite = new Sprite(PLAY_AREA_CENTER_X - gameOverEndTexture->getWidth() / 2, 80, 128, 96, gameOverEndTexture, renderer); // Inicializa las variables necesarias para la sección 'Game' init(); @@ -88,6 +89,9 @@ Game::~Game() gameOverTexture->unload(); delete gameOverTexture; + gameOverEndTexture->unload(); + delete gameOverEndTexture; + // Animaciones for (auto animation : playerAnimations) { @@ -157,6 +161,8 @@ Game::~Game() delete skyColorsSprite; delete grassSprite; delete powerMeterSprite; + delete gameOverSprite; + delete gameOverEndSprite; JA_DeleteSound(balloonSound); JA_DeleteSound(bulletSound); @@ -183,13 +189,14 @@ void Game::init() ticks = 0; ticksSpeed = 15; - // Crea los jugadores + // Elimina qualquier jugador que hubiese antes de crear los nuevos for (auto player : players) { delete player; }; players.clear(); + // Crea los jugadores if (numPlayers == 1) { Player *player = new Player(PLAY_AREA_CENTER_X - 11, PLAY_AREA_BOTTOM - 24, renderer, player1Textures, playerAnimations); @@ -212,7 +219,6 @@ void Game::init() difficultyScoreMultiplier = 0.5f; difficultyColor = {75, 105, 47}; pauseMenu->setSelectorColor(difficultyColor, 255); - // gameOverMenu->setSelectorTextColor(difficultyColor); gameOverMenu->setSelectorColor(difficultyColor, 255); break; @@ -221,7 +227,6 @@ void Game::init() difficultyScoreMultiplier = 1.0f; difficultyColor = {255, 122, 0}; pauseMenu->setSelectorColor(difficultyColor, 255); - // gameOverMenu->setSelectorTextColor(difficultyColor); gameOverMenu->setSelectorColor(difficultyColor, 255); break; @@ -230,13 +235,13 @@ void Game::init() difficultyScoreMultiplier = 1.5f; difficultyColor = {118, 66, 138}; pauseMenu->setSelectorColor(difficultyColor, 255); - // gameOverMenu->setSelectorTextColor(difficultyColor); gameOverMenu->setSelectorColor(difficultyColor, 255); break; default: break; } + gameCompleted = false; gameCompletedCounter = 0; section.name = PROG_SECTION_GAME; @@ -302,6 +307,9 @@ void Game::init() totalPowerToCompleteGame += stage[i].powerToComplete; } + balloonsPopped = totalPowerToCompleteGame - 20; + stage[9].currentPower = stage[9].powerToComplete - 20; + // Modo demo demo.recording = false; demo.counter = 0; @@ -392,6 +400,7 @@ void Game::loadMedia() gameSkyColorsTexture = new LTexture(renderer, asset->get("game_sky_colors.png")); gameTextTexture = new LTexture(renderer, asset->get("game_text.png")); gameOverTexture = new LTexture(renderer, asset->get("menu_game_over.png")); + gameOverEndTexture = new LTexture(renderer, asset->get("menu_game_over_end.png")); // Texturas - Globos LTexture *balloon1Texture = new LTexture(renderer, asset->get("balloon1.png")); @@ -455,7 +464,7 @@ void Game::loadMedia() player2Textures.push_back(player2Death); LTexture *player2Fire = new LTexture(renderer, asset->get("player_arounder_fire.png")); - player1Textures.push_back(player2Fire); + player2Textures.push_back(player2Fire); // Animaciones -- Jugador std::vector *playerHeadAnimation = new std::vector; @@ -1706,8 +1715,7 @@ void Game::updateStage() stage[currentStage].currentPower = 0; // Vuelve a dejar el poder a cero, por lo que hubiera podido subir al destruir todos lo globos menaceCurrent = 255; // Sube el nivel de amenaza para que no cree mas globos for (auto player : players) - // for (int i = 0; i < numPlayers; i++) // Añade un millon de puntos a los jugadores que queden vivos - { + { // Añade un millon de puntos a los jugadores que queden vivos if (player->isAlive()) { player->addScore(1000000); @@ -2755,18 +2763,38 @@ void Game::update() // Actualiza el fondo void Game::updateBackground() { - const float speed = (-0.2f) + (-3.00f * ((float)balloonsPopped / (float)totalPowerToCompleteGame)); + if (!gameCompleted) + { // Si el juego no esta completo, la velocidad de las nubes es igual a los globos explotados + cloudsSpeed = balloonsPopped; + } + else + { // Si el juego está completado, se reduce la velocidad de las nubes + if (cloudsSpeed > 400) + { + cloudsSpeed -= 25; + } + else + { + cloudsSpeed = 200; + } + } + // Calcula la velocidad en función de los globos explotados y el total de globos a explotar para acabar el juego + const float speed = (-0.2f) + (-3.00f * ((float)cloudsSpeed / (float)totalPowerToCompleteGame)); + + // Aplica la velocidad calculada a las nubes clouds1A->setVelX(speed); clouds1B->setVelX(speed); clouds2A->setVelX(speed / 2); clouds2B->setVelX(speed / 2); + // Mueve las nubes clouds1A->move(); clouds1B->move(); clouds2A->move(); clouds2B->move(); + // Calcula el offset de las nubes if (clouds1A->getPosX() < -clouds1A->getWidth()) { clouds1A->setPosX(clouds1A->getWidth()); @@ -2787,8 +2815,10 @@ void Game::updateBackground() clouds2B->setPosX(clouds2B->getWidth()); } + // Calcula el frame de la hierba grassSprite->setSpriteClip(0, (6 * (counter / 20 % 2)), 256, 6); + // Mueve los edificios en funcion de si está activo el efecto de agitarlos if (effect.shake) { buildingsSprite->setPosX(((effect.shakeCounter % 2) * 2) - 1); @@ -2853,16 +2883,13 @@ void Game::render() renderDeathFade(150 - deathCounter); } - if ((gameCompleted) && (gameCompletedCounter >= 300)) + if ((gameCompleted) && (gameCompletedCounter >= GAME_COMPLETED_START_FADE)) { - renderDeathFade(gameCompletedCounter - 300); + renderDeathFade(gameCompletedCounter - GAME_COMPLETED_START_FADE); } renderFlashEffect(); - const std::string txt = std::to_string(balloonsPopped) + "-" + std::to_string(totalPowerToCompleteGame); - text->write(0, 0, txt); - // Vuelca el contenido del renderizador en pantalla screen->blit(); } @@ -3297,9 +3324,9 @@ void Game::runPausedGame() renderDeathFade(150 - deathCounter); } - if ((gameCompleted) && (gameCompletedCounter >= 300)) + if ((gameCompleted) && (gameCompletedCounter >= GAME_COMPLETED_START_FADE)) { - renderDeathFade(gameCompletedCounter - 300); + renderDeathFade(gameCompletedCounter - GAME_COMPLETED_START_FADE); } renderFlashEffect(); @@ -3385,10 +3412,18 @@ void Game::runGameOverScreen() switch (postFade) { case 0: // YES - section.name = PROG_SECTION_GAME; - deleteAllVectorObjects(); - init(); - section.subsection = numPlayers == 1 ? GAME_SECTION_PLAY_1P : GAME_SECTION_PLAY_2P; + if (!gameCompleted) + { // Si el juego no se ha terminado, el menu actua normal + section.name = PROG_SECTION_GAME; + deleteAllVectorObjects(); + init(); + section.subsection = numPlayers == 1 ? GAME_SECTION_PLAY_1P : GAME_SECTION_PLAY_2P; + } + else + { // Si ha completado el juego, siempre vuelve a la pantalla de titulo + section.name = PROG_SECTION_TITLE; + section.subsection = TITLE_SECTION_1; + } break; case 1: // NO @@ -3411,29 +3446,44 @@ void Game::runGameOverScreen() screen->clean(bgColor); // Dibujo - gameOverSprite->render(); + if (!gameCompleted) + { // Dibujo de haber perdido la partida + gameOverSprite->render(); + } + else + { // Dinujo de haber completado la partida + gameOverEndSprite->render(); + } // Dibuja los objetos if (numPlayers == 1) { // Game Over textBig->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 6), lang->getText(43)); - // textBig->writeDX(TXT_CENTER | TXT_SHADOW, PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 6), lang->getText(43), 1, {255, 255, 235}, 1, difficultyColor); // Your Score text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 3), lang->getText(44) + std::to_string(players.at(0)->getScore())); - // text->writeDX(TXT_CENTER | TXT_SHADOW, PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 3), lang->getText(44) + std::to_string(players.at(0)->getScore()), 1, {255, 255, 235}, 1, difficultyColor); } else { - textBig->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - 36, lang->getText(43)); - text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - 12, lang->getText(77) + std::to_string(players.at(0)->getScore())); - text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y, lang->getText(78) + std::to_string(players.at(1)->getScore())); + // Game Over + textBig->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 7), lang->getText(43)); + + // Player1 Score + text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 4), lang->getText(77) + std::to_string(players.at(0)->getScore())); + + // Player2 Score + text->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 2), lang->getText(78) + std::to_string(players.at(1)->getScore())); } + // Continue? - text->writeCentered(199, PLAY_AREA_CENTER_Y + BLOCK * 3, lang->getText(45)); - // text->writeDX(TXT_CENTER | TXT_SHADOW, 199, PLAY_AREA_CENTER_Y + BLOCK * 3, lang->getText(45), 1, {255, 255, 235}, 1, difficultyColor); - gameOverMenu->render(); + if (!gameCompleted) + { // Solo dibuja el menu de continuar en el caso de no haber completado la partida + text->writeCentered(199, PLAY_AREA_CENTER_Y + BLOCK * 3, lang->getText(45)); + gameOverMenu->render(); + } + + // Pinta el fade fade->render(); // Vuelca el contenido del renderizador en pantalla @@ -3563,7 +3613,7 @@ void Game::updateGameCompleted() gameCompletedCounter++; } - if (gameCompletedCounter == 500) + if (gameCompletedCounter == GAME_COMPLETED_END) { section.subsection = GAME_SECTION_GAMEOVER; } diff --git a/source/game.h b/source/game.h index 4addfd8..41deb79 100644 --- a/source/game.h +++ b/source/game.h @@ -31,6 +31,8 @@ #define STAGE_COUNTER 200 #define SHAKE_COUNTER 10 #define HELP_COUNTER 1000 +#define GAME_COMPLETED_START_FADE 500 +#define GAME_COMPLETED_END 700 // Formaciones enemigas #define NUMBER_OF_ENEMY_FORMATIONS 100 @@ -138,6 +140,7 @@ private: LTexture *gameSkyColorsTexture; // Textura con los diferentes colores de fondo del juego LTexture *gameTextTexture; // Textura para los sprites con textos LTexture *gameOverTexture; // Textura para la pantalla de game over + LTexture *gameOverEndTexture; // Textura para la pantalla de game over de acabar el juego std::vector *> itemAnimations; // Vector con las animaciones de los items std::vector *> playerAnimations; // Vector con las animaciones del jugador @@ -163,11 +166,12 @@ private: SmartSprite *n2500Sprite; // Sprite con el texto 2.500 SmartSprite *n5000Sprite; // Sprite con el texto 5.000 - Sprite *buildingsSprite; // Sprite con los edificios de fondo - Sprite *skyColorsSprite; // Sprite con los graficos del degradado de color de fondo - Sprite *grassSprite; // Sprite para la hierba - Sprite *powerMeterSprite; // Sprite para el medidor de poder de la fase - Sprite *gameOverSprite; // Sprite para dibujar los graficos del game over + Sprite *buildingsSprite; // Sprite con los edificios de fondo + Sprite *skyColorsSprite; // Sprite con los graficos del degradado de color de fondo + Sprite *grassSprite; // Sprite para la hierba + Sprite *powerMeterSprite; // Sprite para el medidor de poder de la fase + Sprite *gameOverSprite; // Sprite para dibujar los graficos del game over + Sprite *gameOverEndSprite; // Sprite para dibujar los graficos del game over de acabar el juego JA_Sound balloonSound; // Sonido para la explosión del globo JA_Sound bulletSound; // Sonido para los disparos @@ -230,6 +234,7 @@ private: Uint8 lastStageReached; // Contiene el numero de la última pantalla que se ha alcanzado demo_t demo; // Variable con todas las variables relacionadas con el modo demo int totalPowerToCompleteGame; // La suma del poder necesario para completar todas las fases + int cloudsSpeed; // Velocidad a la que se desplazan las nubes // Actualiza el juego void update(); diff --git a/todo.txt b/todo.txt index ec29b2f..bb42cd1 100644 --- a/todo.txt +++ b/todo.txt @@ -21,5 +21,8 @@ NO que grite "yiiijaa!" o algo parecido al coger la maquina de cafe NO o que diga DIMONIS! en un globo de texto que se evapore NO podrian salir comentarios aleatoriamente o con ciertos eventos (falta ver si no estorbará) x que se vea el nivel de dificultad -poner un dibujito en la pantalla de game over al terminar el juego -x y quizas otro en la propia pantalla de game over \ No newline at end of file +x poner un dibujito en la pantalla de game over al terminar el juego +x y quizas otro en la propia pantalla de game over +x que las nubes al final se vuelva a frenar +quitar las cabezas powerup +x el modo 2P no arranca \ No newline at end of file