#include "game.h" #ifdef __MIPSEL__ #include #include #endif // Constructor Game::Game(SDL_Renderer *renderer, std::string *filelist, Lang *lang, Input *input) { // Copia los punteros mRenderer = renderer; mFileList = filelist; mLang = lang; mInput = input; mTextureText = new LTexture(); mText = new Text(mFileList[48], mTextureText, mRenderer); mFade = new Fade(mRenderer); mEventHandler = new SDL_Event(); } Game::~Game() { mRenderer = nullptr; mFileList = nullptr; mLang = nullptr; mInput = nullptr; mTextureText->unload(); delete mTextureText; mTextureText = nullptr; delete mText; mText = nullptr; delete mFade; mFade = nullptr; delete mEventHandler; mEventHandler = nullptr; } // Inicializa las variables necesarias para la sección 'Game' void Game::init() { // Carga los recursos loadMedia(); // Carga ficheros loadScoreFile(); loadDemoFile(); mTicks = 0; mTicksSpeed = 15; // Inicializa las variables switch (mDifficulty) { case DIFFICULTY_EASY: mDefaultEnemySpeed = BALLOON_SPEED_1; mDifficultyScoreMultiplier = 0.5f; break; case DIFFICULTY_NORMAL: mDefaultEnemySpeed = BALLOON_SPEED_1; mDifficultyScoreMultiplier = 1.0f; break; case DIFFICULTY_HARD: mDefaultEnemySpeed = BALLOON_SPEED_5; mDifficultyScoreMultiplier = 1.5f; break; default: break; } mGameCompleted = false; mGameCompletedCounter = 0; mSection.name = PROG_SECTION_GAME; mSection.subsection = GAME_SECTION_PLAY_1P; mMenaceCurrent = 0; mMenaceThreshold = 0; mHiScoreAchieved = false; mCurrentStage = 0; mStageBitmapCounter = STAGE_COUNTER; mDeathCounter = DEATH_COUNTER; mExplosionTime = false; mRemainingExplosions = REMAINING_EXPLOSIONS; mRemainingExplosionsCounter = REMAINING_EXPLOSIONS_COUNTER; mTimeStopped = false; mTimeStoppedCounter = 0; mCounter = 0; mBalloonsPopped = 0; mLastEnemyDeploy = 0; mEnemyDeployCounter = 0; mEnemySpeed = mDefaultEnemySpeed; mEffect.flash = false; mEffect.shake = false; mEffect.shakeCounter = SHAKE_COUNTER; mHelper.needCoffee = false; mHelper.needCoffeeMachine = false; mHelper.needPowerBall = false; mHelper.counter = HELP_COUNTER; mHelper.itemPoints1Odds = ITEM_POINTS_1_DISK_ODDS; mHelper.itemPoints2Odds = ITEM_POINTS_2_GAVINA_ODDS; mHelper.itemPoints3Odds = ITEM_POINTS_3_PACMAR_ODDS; mHelper.itemClockOdds = ITEM_CLOCK_ODDS; mHelper.itemCoffeeOdds = ITEM_COFFEE_ODDS; mHelper.itemCoffeeMachineOdds = ITEM_COFFEE_MACHINE_ODDS; mPowerBallEnabled = false; mPowerBallCounter = 0; mCoffeeMachineEnabled = false; mPostFade = 0; if (mDemo.enabled) { int num = rand() % 2; if (num == 0) { mBalloonsPopped = 1000; mCurrentStage = 3; } else { mBalloonsPopped = 1800; mCurrentStage = 6; } } initSin(); initPaths(); initEnemyFormations(); initEnemyPools(); initGameStages(); // BORRAR //mStage[mCurrentStage].currentPower = mStage[mCurrentStage].powerToComplete - 10; // Modo debug mDebug.enabled = false; mDebug.enemySet = 0; mDebug.gradR = mDebug.gradG = mDebug.gradB = 0; // Modo demo mDemo.recording = false; mDemo.counter = 0; // Iniciualiza el objeto para el fundido mFade->init(0x27, 0x27, 0x36); // Inicializa el objeto con el menu de pausa mMenuPause->init("PAUSE", 0, 12 * BLOCK, MENU_BACKGROUND_SOLID); mMenuPause->addItem(mLang->getText(46), 2); mMenuPause->addItem(mLang->getText(47), 0); mMenuPause->setDefaultActionWhenCancel(0); mMenuPause->setBackgroundColor(0x29, 0x39, 0x41, 240); mMenuPause->setSelectorColor(0xFF, 0x7A, 0x00, 255); mMenuPause->setSelectorTextColor(0xFF, 0xFF, 0xFF); mMenuPause->centerMenuOnX(SCREEN_CENTER_X); mMenuPause->centerMenuElementsOnX(); // Inicializa el objeto con el menu de la pantalla de game over mMenuGameOver->init("GAME OVER", 0, PLAY_AREA_CENTER_Y + BLOCK * 4, MENU_BACKGROUND_TRANSPARENT); mMenuGameOver->addItem(mLang->getText(48), 2); mMenuGameOver->addItem(mLang->getText(49)); mMenuGameOver->setDefaultActionWhenCancel(1); mMenuGameOver->setBackgroundColor(0, 0, 0, 255); mMenuGameOver->setSelectorColor(0x54, 0x6e, 0x7a, 255); mMenuGameOver->setSelectorColor(0x54, 0x6e, 0x7a, 0); mMenuGameOver->setSelectorTextColor(0xFF, 0xFF, 0xFF); mMenuGameOver->setSelectorTextColor(0xFF, 0xF1, 0x76); mMenuGameOver->setSelectorTextColor(0xFF, 0x7A, 0x00); mMenuGameOver->centerMenuOnX(SCREEN_CENTER_X); mMenuGameOver->centerMenuElementsOnX(); // Sprites mClouds1a->init(0, 0, 256, 52, -0.4f, 0.0f, 0.0f, 0.0f, mTextureGameBG, mRenderer); mClouds1a->setSpriteClip(256, 0, 256, 52); mClouds1b->init(256, 0, 256, 52, -0.4f, 0.0f, 0.0f, 0.0f, mTextureGameBG, mRenderer); mClouds1b->setSpriteClip(256, 0, 256, 52); mClouds2a->init(0, 52, 256, 32, -0.2f, 0.0f, 0.0f, 0.0f, mTextureGameBG, mRenderer); mClouds2a->setSpriteClip(256, 52, 256, 32); mClouds2b->init(256, 52, 256, 32, -0.2f, 0.0f, 0.0f, 0.0f, mTextureGameBG, mRenderer); mClouds2b->setSpriteClip(256, 52, 256, 32); mSpriteGrass->init(0, 85, SCREEN_WIDTH, 6, mTextureGameBG, mRenderer); mSpriteGrass->setPosY(154); mSpriteScoreBoard->init(0, 160, SCREEN_WIDTH, 32, mTextureGameBG, mRenderer); mSpriteScoreBoard->setSpriteClip(0, 160, 256, 32); mSpritePowerMeter->init(PLAY_AREA_CENTER_X - 20, 170, 40, 8, mTextureGameBG, mRenderer); mSpritePowerMeter->setSpriteClip(256, 192 - 8, 40, 8); // Vector de jugadores if (mNumPlayers == 1) mPlayer[0]->init(PLAY_AREA_CENTER_X - 11, PLAY_AREA_BOTTOM - 24, mTexturePlayer1Legs, mTexturePlayer1Body, mTexturePlayer1Head, mTexturePlayer1Death, mRenderer); if (mNumPlayers == 2) { mPlayer[0]->init((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((0 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, mTexturePlayer1Legs, mTexturePlayer1Body, mTexturePlayer1Head, mTexturePlayer1Death, mRenderer); mPlayer[1]->init((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((1 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, mTexturePlayer2Legs, mTexturePlayer2Body, mTexturePlayer2Head, mTexturePlayer2Death, mRenderer); } // Establece a cero todos los valores del vector de objetos globo resetBalloons(); // Con los globos creados, calcula el nivel de amenaza evaluateAndSetMenace(); // Establece a cero todos los valores del vector de objetos bala resetBullets(); // Establece a cero todos los valores del vector de objetos item resetItems(); // Establece a cero todos los valores del vector de objetos SmafrtSprite resetSmartSprites(); // Inicializa el bitmap de GetReady! mSpriteGetReady->init(0, PLAY_AREA_CENTER_Y - 10, 109, 20, mTextureGameText, mRenderer); mSpriteGetReady->setSpriteClip(0, 0, 109, 20); // Inicializa el bitmap de 1000 puntos m1000Bitmap->init(mTextureGameText, mRenderer); m1000Bitmap->setPosX(0); m1000Bitmap->setPosY(0); m1000Bitmap->setWidth(26); m1000Bitmap->setHeight(9); m1000Bitmap->setVelX(0.0f); m1000Bitmap->setVelY(-0.5f); m1000Bitmap->setAccelX(0.0f); m1000Bitmap->setAccelY(-0.1f); m1000Bitmap->setSpriteClip(0, 20, 26, 9); m1000Bitmap->setEnabled(false); m1000Bitmap->setEnabledTimer(0); m1000Bitmap->setDestX(0); m1000Bitmap->setDestY(0); // Inicializa el bitmap de 2500 puntos m2500Bitmap->init(mTextureGameText, mRenderer); m2500Bitmap->setPosX(0); m2500Bitmap->setPosY(0); m2500Bitmap->setWidth(28); m2500Bitmap->setHeight(9); m2500Bitmap->setVelX(0.0f); m2500Bitmap->setVelY(-0.5f); m2500Bitmap->setAccelX(0.0f); m2500Bitmap->setAccelY(-0.1f); m2500Bitmap->setSpriteClip(26, 20, 28, 9); m2500Bitmap->setEnabled(false); m2500Bitmap->setEnabledTimer(0); m2500Bitmap->setDestX(0); m2500Bitmap->setDestY(0); // Inicializa el bitmap de 5000 puntos m5000Bitmap->init(mTextureGameText, mRenderer); m5000Bitmap->setPosX(0); m5000Bitmap->setPosY(0); m5000Bitmap->setWidth(28); m5000Bitmap->setHeight(9); m5000Bitmap->setVelX(0.0f); m5000Bitmap->setVelY(-0.5f); m5000Bitmap->setAccelX(0.0f); m5000Bitmap->setAccelY(-0.1f); m5000Bitmap->setSpriteClip(54, 20, 28, 9); m5000Bitmap->setEnabled(false); m5000Bitmap->setEnabledTimer(0); m5000Bitmap->setDestX(0); m5000Bitmap->setDestY(0); // Los fondos mSpriteBackground->init(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, mTextureGameBG, mRenderer); mSpriteGradient->init(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, mTextureGameBG, mRenderer); mGradientRect[0] = {0, 192, SCREEN_WIDTH, SCREEN_HEIGHT}; mGradientRect[1] = {256, 192, SCREEN_WIDTH, SCREEN_HEIGHT}; mGradientRect[2] = {0, 384, SCREEN_WIDTH, SCREEN_HEIGHT}; mGradientRect[3] = {256, 384, SCREEN_WIDTH, SCREEN_HEIGHT}; } // Bucle para el juego section_t Game::run() { init(); while (mSection.name == PROG_SECTION_GAME) { // Sección juego jugando if ((mSection.subsection == GAME_SECTION_PLAY_1P) || (mSection.subsection == GAME_SECTION_PLAY_2P)) { // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego if (SDL_GetTicks() - mTicks > mTicksSpeed) { // Actualiza el contador de ticks mTicks = SDL_GetTicks(); // Comprueba los eventos que hay en la cola while (SDL_PollEvent(mEventHandler) != 0) { // Evento de salida de la aplicación if (mEventHandler->type == SDL_QUIT) { mSection.name = PROG_SECTION_QUIT; break; } } } // Limpia la pantalla SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF); SDL_RenderClear(mRenderer); // Actualiza la pantalla SDL_RenderPresent(mRenderer); } } return mSection; }