Files
jaildoctors_dilemma/source/game.cpp

323 lines
9.2 KiB
C++

#include "game.h"
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#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;
}