diff --git a/media/.DS_Store b/media/.DS_Store index 913ab0a..ef9c65c 100644 Binary files a/media/.DS_Store and b/media/.DS_Store differ diff --git a/media/gfx/player_body.png b/media/gfx/player_body.png index 6612800..a082434 100644 Binary files a/media/gfx/player_body.png and b/media/gfx/player_body.png differ diff --git a/source/gamedirector.cpp b/source/gamedirector.cpp index 4e848e8..3dfa035 100644 --- a/source/gamedirector.cpp +++ b/source/gamedirector.cpp @@ -35,18 +35,18 @@ GameDirector::GameDirector(std::string path) setFileList(); checkFileList(); + // Inicializa SDL + initSDL(); + + // Inicializa JailAudio + initJailAudio(); + // Carga recursos loadMediaProg(); loadScoreFile(); loadConfigFile(); loadDemoFile(); - // Inicializa JailAudio - initJailAudio(); - - // Inicializa SDL - initSDL(); - // Inicializa el resto de variables initProg(); } @@ -596,7 +596,7 @@ void GameDirector::quitIntro() } // Inicializa las variables necesarias para la sección 'Title' -void GameDirector::initTitle(Uint8 section) +void GameDirector::initTitle(Uint8 subsection) { // Reserva memoria para los punteros mTexture[TEXTURE_TITLE].texture = new LTexture(); @@ -611,7 +611,7 @@ void GameDirector::initTitle(Uint8 section) loadMediaTitle(); // Inicializa variables - mTitle.section = section; + mTitle.section = subsection; mTitle.counter = TITLE_COUNTER; mTitle.backgroundCounter = 0; mTitle.backgroundMode = rand() % 2; @@ -696,10 +696,6 @@ void GameDirector::initTitle(Uint8 section) // Inicializa el vector de eventos de la pantalla de titulo for (Uint8 i = 0; i < TITLE_TOTAL_EVENTS; i++) mTitle.events[i] = EVENT_WAITING; - - // El tile de fondo - mTitle.tile->init(0, 0, 64, 64, mTexture[TEXTURE_TITLE].texture, mRenderer); - mTitle.tile->setSpriteClip(192, 0, 64, 64); } // Carga los recursos necesarios para la sección 'Title' @@ -724,6 +720,9 @@ bool GameDirector::loadMediaTitle() SDL_SetRenderTarget(mRenderer, mTitleSurface); SDL_SetRenderDrawColor(mRenderer, 0x43, 0x43, 0x4F, 0xFF); SDL_RenderClear(mRenderer); + + mTitle.tile->init(0, 0, 64, 64, mTexture[TEXTURE_TITLE].texture, mRenderer); + mTitle.tile->setSpriteClip(192, 0, 64, 64); for (Uint8 i = 0; i < 8; i++) for (Uint8 j = 0; j < 6; j++) { @@ -731,6 +730,7 @@ bool GameDirector::loadMediaTitle() mTitle.tile->setPosY(j * 64); mTitle.tile->render(); } + mTitle.backgroundWindow.x = 0; mTitle.backgroundWindow.y = 0; mTitle.backgroundWindow.w = SCREEN_WIDTH; @@ -821,6 +821,13 @@ void GameDirector::initGame() loadMediaGame(); // Inicializa variables + resetGame(); +} + +// Inicializa las variables especificas de la sección 'Game' para empezar una nueva partida +void GameDirector::resetGame() +{ + // Inicializa las variables mGame.section = GAME_SECTION_PLAY; mGame.menaceLevelCurrent = 0; mGame.menaceLevelThreshold = 0; @@ -834,7 +841,6 @@ void GameDirector::initGame() mGame.remainingExplosionsCounter = REMAINING_EXPLOSIONS_COUNTER; mGame.timeStopped = false; mGame.timeStoppedCounter = TIME_STOPPED_COUNTER; - mGame.playFieldDrawOnly = true; mProg.debug = false; mGame.counter = 0; @@ -855,13 +861,13 @@ void GameDirector::initGame() mGame.grass->setPosY(154); // Objeto jugador - mGame.player->init(PLAY_AREA_CENTER_X - 12, PLAY_AREA_BOTTOM - 24, mTexture[TEXTURE_PLAYER_LEGS].texture, mTexture[TEXTURE_PLAYER_BODY].texture, mRenderer); + mGame.player->init(PLAY_AREA_CENTER_X - 11, PLAY_AREA_BOTTOM - 24, mTexture[TEXTURE_PLAYER_LEGS].texture, mTexture[TEXTURE_PLAYER_BODY].texture, mRenderer); // Establece a cero todos los valores del vector de objetos globo resetBalloons(); // Crea objetos globo y los centra en el area de juego - mGame.balloon[0]->init(0, BLOCK, BALLOON_4, BALLOON_VELX_POSITIVE, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer); + mGame.balloon[0]->init(0, BLOCK, BALLOON_4, BALLOON_VELX_POSITIVE, 100, mTexture[TEXTURE_BALLOON].texture, mRenderer); mGame.balloon[0]->allignTo(PLAY_AREA_CENTER_X); // Con los globos creados, calcula el nivel de amenaza @@ -887,7 +893,7 @@ void GameDirector::initGame() mGame.getReadyBitmap->setAccelX(0.00f); mGame.getReadyBitmap->setAccelY(0.0f); mGame.getReadyBitmap->setSpriteClip(0, 0, 109, 20); - mGame.getReadyBitmap->setEnabled(true); + mGame.getReadyBitmap->setEnabled(!mDemo.enabled); mGame.getReadyBitmap->setEnabledTimer(0); mGame.getReadyBitmap->setDestX(PLAY_AREA_RIGHT); mGame.getReadyBitmap->setDestY(PLAY_AREA_CENTER_Y - 10); @@ -2313,18 +2319,6 @@ Uint8 GameDirector::getMenaceLevel() return mGame.menaceLevelCurrent; } -// Obtiene el valor de la variable -bool GameDirector::isPlayFieldDrawOnly() -{ - return mGame.playFieldDrawOnly; -} - -// Establece el valor de la variable -void GameDirector::setPlayFieldDrawOnly(bool state) -{ - mGame.playFieldDrawOnly = state; -} - // Establece el valor de la variable void GameDirector::setTimeStopped(bool value) { @@ -2405,14 +2399,15 @@ void GameDirector::updateRemainingExplosionsCounter() // Actualiza el campo de juego void GameDirector::updatePlayField() { - if (isPlayFieldDrawOnly() == false) - { // Comprueba el teclado/mando checkGameInput(); // Actualiza el jugador mGame.player->update(); + // Actualiza el fondo + updateBackground(); + // Mueve los globos moveBalloons(); @@ -2455,12 +2450,8 @@ void GameDirector::updatePlayField() killPlayer(); } } - } - else - { // Actualiza el mensaje de GetReady mGame.getReadyBitmap->update(); - } } // Actualiza el fondo @@ -2499,7 +2490,6 @@ void GameDirector::renderBackground() alpha = 0; } - updateBackground(); mGame.gradient->setSpriteClip(SCREEN_WIDTH, 192, SCREEN_WIDTH, SCREEN_HEIGHT); mTexture[TEXTURE_GAME_BG].texture->setAlpha(255); mGame.gradient->render(); @@ -3004,8 +2994,6 @@ void GameDirector::renderMessages() { // GETREADY! mGame.getReadyBitmap->render(); - if (!mGame.getReadyBitmap->isEnabled()) - setPlayFieldDrawOnly(false); // Time Stopped if (mGame.timeStopped) @@ -3147,7 +3135,7 @@ void GameDirector::runLogo() { initLogo(); - while (mProg.section == PROG_SECTION_LOGO) + while ((mProg.section == PROG_SECTION_LOGO) && (!exit())) { // Comprueba los eventos que hay en la cola while (SDL_PollEvent(mEventHandler) != 0) @@ -3242,7 +3230,7 @@ void GameDirector::runIntro() JA_PlayMusic(mMusic[MUSIC_INTRO].music, false); } - while (mProg.section == PROG_SECTION_INTRO) + while ((mProg.section == PROG_SECTION_INTRO) && (!exit())) { if (SDL_GetTicks() - mProg.ticks > mProg.ticksSpeed) { @@ -3407,15 +3395,15 @@ void GameDirector::runIntro() } // Bucle para el titulo del juego -void GameDirector::runTitle(Uint8 section) +void GameDirector::runTitle(Uint8 subsection) { Uint8 R = 0x27; Uint8 G = 0x27; Uint8 B = 0x36; - initTitle(); + initTitle(subsection); - while (mProg.section == PROG_SECTION_TITLE) + while ((mProg.section == PROG_SECTION_TITLE) && (!exit())) { // Sección 1 - Titulo desplazandose if (mTitle.section == TITLE_SECTION_1) @@ -3595,7 +3583,7 @@ void GameDirector::runTitle(Uint8 section) mText.white->writeCentered(SCREEN_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, "PRESS ANY KEY!", 0); } - // texto con el copyright y versión + // Texto con el copyright y versión mText.black->writeCentered(SCREEN_CENTER_X + 1, SCREEN_HEIGHT - (BLOCK * 2) + 1, TEXT_COPYRIGHT, 0); mText.white->writeCentered(SCREEN_CENTER_X, SCREEN_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 0); @@ -3722,7 +3710,7 @@ void GameDirector::runGame() { initGame(); - while (mProg.section == PROG_SECTION_GAME) + while ((mProg.section == PROG_SECTION_GAME) && (!exit())) { // Sección juego en pausa if (mGame.section == GAME_SECTION_PAUSE) @@ -3798,8 +3786,8 @@ void GameDirector::runGame() SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL); // Actualiza la pantalla - if (mProg.section == PROG_SECTION_GAME) - SDL_RenderPresent(mRenderer); + //if (mProg.section == PROG_SECTION_GAME) + SDL_RenderPresent(mRenderer); } } @@ -3809,7 +3797,7 @@ void GameDirector::runGame() // Bucle para el menu de pausa del juego void GameDirector::runPausedGame() { - while (mGame.section == GAME_SECTION_PAUSE) + while ((mGame.section == GAME_SECTION_PAUSE) && (mProg.section == PROG_SECTION_GAME)) { // Comprueba los eventos que hay en la cola while (SDL_PollEvent(mEventHandler) != 0) @@ -3997,7 +3985,7 @@ void GameDirector::runInstructions() // Bucle para la pantalla de game over void GameDirector::runGameOverScreen() { - while (mGame.section == GAME_SECTION_GAMEOVER) + while ((mGame.section == GAME_SECTION_GAMEOVER) && (mProg.section == PROG_SECTION_GAME)) { // Comprueba los eventos que hay en la cola while (SDL_PollEvent(mEventHandler) != 0) @@ -4050,12 +4038,14 @@ void GameDirector::runGameOverScreen() { case 0: setProgSection(PROG_SECTION_GAME); + mGame.section = GAME_SECTION_PLAY; mMenu.gameOver->reset(); mMenu.keyPressed = false; JA_PlaySound(mSound[SOUND_MENU_SELECT].sound); JA_StopMusic(); renderFade(1); disableDemoMode(); + resetGame(); break; case 1: setProgSection(PROG_SECTION_TITLE); @@ -4091,14 +4081,14 @@ void GameDirector::renderDebugInfo() void GameDirector::enableDemoMode() { mDemo.enabled = true; - mGame.getReadyBitmap->setEnabled(false); + //mGame.getReadyBitmap->setEnabled(false); } // Desactiva el modo Demo void GameDirector::disableDemoMode() { mDemo.enabled = false; - mGame.getReadyBitmap->setEnabled(true); + //mGame.getReadyBitmap->setEnabled(true); } // Actualiza el proximo estado del juego despues del titulo diff --git a/source/gamedirector.h b/source/gamedirector.h index 5821539..a096c68 100644 --- a/source/gamedirector.h +++ b/source/gamedirector.h @@ -81,7 +81,6 @@ private: Uint8 deathIndex; // Indice del vector de smartsprites que contiene el sprite del jugador Uint8 menaceLevelCurrent; // Nivel de amenaza actual Uint8 menaceLevelThreshold; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el numero de globos - bool playFieldDrawOnly; // Indica si el bucle de juego avanza o solo pinta bool timeStopped; // Indica si el tiempo está detenido Uint16 timeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido Uint8 remainingExplosions; // Cantidad de explosiones restantes @@ -242,7 +241,7 @@ public: void quitIntro(); // Inicializa las variables necesarias para la sección 'Title' - void initTitle(Uint8 section = TITLE_SECTION_1); + void initTitle(Uint8 subsection = TITLE_SECTION_1); // Carga los recursos necesarios para la sección 'Title' bool loadMediaTitle(); @@ -253,6 +252,9 @@ public: // Inicializa las variables necesarias para la sección 'Game' void initGame(); + // Inicializa las variables especificas de la sección 'Game' para empezar una nueva partida + void resetGame(); + // Carga los recursos necesarios para la sección 'Game' bool loadMediaGame(); @@ -437,12 +439,6 @@ public: // Obtiene el valor de la variable Uint8 getMenaceLevel(); - // Obtiene el valor de la variable - bool isPlayFieldDrawOnly(); - - // Establece el valor de la variable - void setPlayFieldDrawOnly(bool state); - // Establece el valor de la variable void setTimeStopped(bool value); @@ -525,7 +521,7 @@ public: void runIntro(); // Bucle para el titulo del juego - void runTitle(Uint8 section = TITLE_SECTION_1); + void runTitle(Uint8 subsection = TITLE_SECTION_1); // Bucle para el juego void runGame(); diff --git a/source/player.cpp b/source/player.cpp index 83a0cf1..3582683 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -32,6 +32,7 @@ void Player::init(float x, int y, LTexture *textureLegs, LTexture *textureBody, mInvulnerableCounter = PLAYER_INVULNERABLE_COUNTER; mExtraHit = false; mCoffees = 0; + mInput = true; // Establece la altura y el ancho del jugador mWidth = 3 * BLOCK; @@ -726,16 +727,40 @@ bool Player::hasExtraHit() void Player::giveExtraHit() { mExtraHit = true; + mCoffees++; + if (mCoffees > 2) + mCoffees = 2; } // Quita el toque extra al jugador void Player::removeExtraHit() { - mExtraHit = false; + if (mCoffees > 0) + mCoffees--; + if (mCoffees == 0) + mExtraHit = false; mInvulnerable = true; mInvulnerableCounter = PLAYER_INVULNERABLE_COUNTER; } +// Habilita la entrada de ordenes +void Player::enableInput() +{ + mInput = true; +} + +// Deshabilita la entrada de ordenes +void Player::disableInput() +{ + mInput = false; +} + +// Devuelve el numero de cafes actuales +Uint8 Player::getCoffees() +{ + return mCoffees; +} + // Obtiene el circulo de colisión Circle &Player::getCollider() { diff --git a/source/player.h b/source/player.h index 322b67d..60ad831 100644 --- a/source/player.h +++ b/source/player.h @@ -32,6 +32,7 @@ private: Uint16 mInvulnerableCounter; // Temporizador para la invulnerabilidad bool mExtraHit; // Indica si el jugador tiene un toque extra Uint8 mCoffees; // Indica cuantos cafes lleva acumulados + bool mInput; // Indica si puede recibir ordenes de entrada AnimatedSprite *mSpriteLegs; // Sprite para dibujar las piernas AnimatedSprite *mSpriteBody; // Sprite para dibujar el cuerpo @@ -141,6 +142,15 @@ public: // Quita el toque extra al jugador void removeExtraHit(); + // Habilita la entrada de ordenes + void enableInput(); + + // Deshabilita la entrada de ordenes + void disableInput(); + + // Devuelve el numero de cafes actuales + Uint8 getCoffees(); + // Obtiene el circulo de colisión Circle &getCollider(); };