323 lines
9.2 KiB
C++
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;
|
|
}
|