working on 2players

This commit is contained in:
2021-08-22 19:50:55 +02:00
parent 2fd4334259
commit 943fb7bf27
5 changed files with 350 additions and 272 deletions

View File

@@ -11,7 +11,8 @@
Director::Director(std::string path)
{
// Crea los objetos
mInput = new Input();
mInput1 = new Input();
mInput2 = new Input();
mOptions = new options_t;
// Inicializa variables
@@ -45,8 +46,10 @@ Director::~Director()
{
saveConfigFile();
delete mInput;
mInput = nullptr;
delete mInput1;
mInput1 = nullptr;
delete mInput2;
mInput2 = nullptr;
delete mOptions;
mOptions = nullptr;
@@ -78,23 +81,41 @@ void Director::init()
initTextStrings(mTextStrings, mOptions->language);
// Teclado
mInput->bindKey(INPUT_UP, SDL_SCANCODE_UP);
mInput->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
mInput->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT);
mInput->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT);
mInput->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN);
mInput->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
mInput1->bindKey(INPUT_UP, SDL_SCANCODE_UP);
mInput1->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
mInput1->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT);
mInput1->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT);
mInput1->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN);
mInput1->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
#ifdef __MIPSEL__
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_LSHIFT);
mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_SPACE);
mInput->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_LCTRL);
mInput1->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_LSHIFT);
mInput1->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_SPACE);
mInput1->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_LCTRL);
#else
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q);
mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W);
mInput->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E);
mInput1->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q);
mInput1->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W);
mInput1->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E);
#endif
mInput->bindKey(INPUT_BUTTON_4, SDL_SCANCODE_ESCAPE); // PAUSE
mInput->bindKey(INPUT_BUTTON_5, SDL_SCANCODE_ESCAPE); // ESCAPE
mInput1->bindKey(INPUT_BUTTON_4, SDL_SCANCODE_ESCAPE); // PAUSE
mInput1->bindKey(INPUT_BUTTON_5, SDL_SCANCODE_ESCAPE); // ESCAPE
mInput2->bindKey(INPUT_UP, SDL_SCANCODE_UP);
mInput2->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
mInput2->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT);
mInput2->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT);
mInput2->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN);
mInput2->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
#ifdef __MIPSEL__
mInput2->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_LSHIFT);
mInput2->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_SPACE);
mInput2->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_LCTRL);
#else
mInput2->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q);
mInput2->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W);
mInput2->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E);
#endif
mInput2->bindKey(INPUT_BUTTON_4, SDL_SCANCODE_ESCAPE); // PAUSE
mInput2->bindKey(INPUT_BUTTON_5, SDL_SCANCODE_ESCAPE); // ESCAPE
}
// Inicializa JailAudio
@@ -439,14 +460,14 @@ void Director::runIntro()
void Director::runTitle()
{
mTitle = new Title(mWindow, mRenderer, mInput, mFileList, mOptions, mTextStrings);
mTitle = new Title(mWindow, mRenderer, mInput1, mFileList, mOptions, mTextStrings);
setSection(mTitle->run(mSection.subsection));
delete mTitle;
}
void Director::runGame()
{
mGame = new Game(mRenderer, mFileList, mTextStrings, mInput, false);
mGame = new Game(2, mRenderer, mFileList, mTextStrings, mInput1, mInput2, false);
setSection(mGame->run());
delete mGame;
}

View File

@@ -32,7 +32,8 @@ private:
SDL_Window *mWindow; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana
Input *mInput;
Input *mInput1; // Objeto Input para gestionar las entradas
Input *mInput2; // Objeto Input para gestionar las entradas
Logo *mLogo; // Objeto para la sección del logo
Intro *mIntro; // Objeto para la sección de la intro

View File

@@ -5,18 +5,20 @@
#endif
// Constructor
Game::Game(SDL_Renderer *renderer, std::string *filelist, std::string *textStrings, Input *input, bool demo)
Game::Game(int numPlayers, SDL_Renderer *renderer, std::string *filelist, std::string *textStrings, Input *input1, Input *input2, bool demo)
{
// Copia los punteros
mRenderer = renderer;
mFileList = filelist;
mTextStrings = textStrings;
mInput = input;
mInput[0] = input1;
mInput[1] = input2;
mDemo.enabled = demo;
mNumPlayers = numPlayers;
// Crea los objetos
mPlayer = new Player();
for (int i = 0; i < mNumPlayers; i++)
mPlayer[i] = new Player();
for (int i = 0; i < MAX_BALLOONS; i++)
mBalloon[i] = new Balloon();
for (int i = 0; i < MAX_BULLETS; i++)
@@ -31,18 +33,22 @@ Game::Game(SDL_Renderer *renderer, std::string *filelist, std::string *textStrin
mTextureGameBG = new LTexture();
mTextureGameText = new LTexture();
mTextureItems = new LTexture();
mTexturePlayerHead = new LTexture();
mTexturePlayerBody = new LTexture();
mTexturePlayerDeath = new LTexture();
mTexturePlayerLegs = new LTexture();
mTexturePlayer1Head = new LTexture();
mTexturePlayer1Body = new LTexture();
mTexturePlayer1Death = new LTexture();
mTexturePlayer1Legs = new LTexture();
mTexturePlayer2Head = new LTexture();
mTexturePlayer2Body = new LTexture();
mTexturePlayer2Death = new LTexture();
mTexturePlayer2Legs = new LTexture();
mTextureText = new LTexture();
mTextureText2 = new LTexture();
mText = new Text(mTextureText, mRenderer);
mTextX2 = new Text(mTextureText2, mRenderer);
mMenuGameOver = new Menu(mRenderer, mText, mInput, mFileList);
mMenuPause = new Menu(mRenderer, mText, mInput, mFileList);
mMenuGameOver = new Menu(mRenderer, mText, mInput[0], mFileList);
mMenuPause = new Menu(mRenderer, mText, mInput[0], mFileList);
mFade = new Fade(mRenderer);
mEventHandler = new SDL_Event();
@@ -78,11 +84,14 @@ Game::~Game()
{
mRenderer = nullptr;
mFileList = nullptr;
mInput = nullptr;
delete mPlayer;
mPlayer = nullptr;
mInput[0] = nullptr;
mInput[1] = nullptr;
for (int i = 0; i < mNumPlayers; i++)
{
delete mPlayer[i];
mPlayer[i] = nullptr;
}
for (int i = 0; i < MAX_BALLOONS; i++)
{
delete mBalloon[i];
@@ -124,21 +133,37 @@ Game::~Game()
delete mTextureItems;
mTextureItems = nullptr;
mTexturePlayerHead->unload();
delete mTexturePlayerHead;
mTexturePlayerHead = nullptr;
mTexturePlayer1Head->unload();
delete mTexturePlayer1Head;
mTexturePlayer1Head = nullptr;
mTexturePlayerBody->unload();
delete mTexturePlayerBody;
mTexturePlayerBody = nullptr;
mTexturePlayer1Body->unload();
delete mTexturePlayer1Body;
mTexturePlayer1Body = nullptr;
mTexturePlayerDeath->unload();
delete mTexturePlayerDeath;
mTexturePlayerDeath = nullptr;
mTexturePlayer1Death->unload();
delete mTexturePlayer1Death;
mTexturePlayer1Death = nullptr;
mTexturePlayerLegs->unload();
delete mTexturePlayerLegs;
mTexturePlayerLegs = nullptr;
mTexturePlayer1Legs->unload();
delete mTexturePlayer1Legs;
mTexturePlayer1Legs = nullptr;
mTexturePlayer2Head->unload();
delete mTexturePlayer2Head;
mTexturePlayer2Head = nullptr;
mTexturePlayer2Body->unload();
delete mTexturePlayer2Body;
mTexturePlayer2Body = nullptr;
mTexturePlayer2Death->unload();
delete mTexturePlayer2Death;
mTexturePlayer2Death = nullptr;
mTexturePlayer2Legs->unload();
delete mTexturePlayer2Legs;
mTexturePlayer2Legs = nullptr;
mTextureText->unload();
delete mTextureText;
@@ -368,8 +393,14 @@ void Game::init()
mSpritePowerMeter->init(PLAY_AREA_CENTER_THIRD_QUARTER_X - 20, HISCORE_NUMBER_Y + 4, 40, 8, mTextureGameBG, mRenderer);
mSpritePowerMeter->setSpriteClip(256, 192 - 8, 40, 8);
// Objeto jugador
mPlayer->init(PLAY_AREA_CENTER_X - 11, PLAY_AREA_BOTTOM - 24, mTexturePlayerLegs, mTexturePlayerBody, mTexturePlayerHead, mRenderer);
// Vector de jugadores
if (mNumPlayers == 1)
mPlayer[0]->init(PLAY_AREA_CENTER_X - 11, PLAY_AREA_BOTTOM - 24, mTexturePlayer1Legs, mTexturePlayer1Body, mTexturePlayer1Head, mRenderer);
if (mNumPlayers == 2)
{
mPlayer[0]->init((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((0 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, mTexturePlayer1Legs, mTexturePlayer1Body, mTexturePlayer1Head, mRenderer);
mPlayer[1]->init((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((1 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, mTexturePlayer2Legs, mTexturePlayer2Body, mTexturePlayer2Head, mRenderer);
}
// Establece a cero todos los valores del vector de objetos globo
resetBalloons();
@@ -455,10 +486,17 @@ bool Game::loadMedia()
// Texturas
success &= loadTextureFromFile(mTextureText, mFileList[30], mRenderer);
success &= loadTextureFromFile(mTextureText2, mFileList[29], mRenderer);
success &= loadTextureFromFile(mTexturePlayerLegs, mFileList[39], mRenderer);
success &= loadTextureFromFile(mTexturePlayerHead, mFileList[41], mRenderer);
success &= loadTextureFromFile(mTexturePlayerBody, mFileList[37], mRenderer);
success &= loadTextureFromFile(mTexturePlayerDeath, mFileList[38], mRenderer);
success &= loadTextureFromFile(mTexturePlayer1Legs, mFileList[39], mRenderer);
success &= loadTextureFromFile(mTexturePlayer1Head, mFileList[41], mRenderer);
success &= loadTextureFromFile(mTexturePlayer1Body, mFileList[37], mRenderer);
success &= loadTextureFromFile(mTexturePlayer1Death, mFileList[38], mRenderer);
success &= loadTextureFromFile(mTexturePlayer2Legs, mFileList[44], mRenderer);
success &= loadTextureFromFile(mTexturePlayer2Head, mFileList[45], mRenderer);
success &= loadTextureFromFile(mTexturePlayer2Body, mFileList[42], mRenderer);
success &= loadTextureFromFile(mTexturePlayer2Death, mFileList[43], mRenderer);
success &= loadTextureFromFile(mTextureBalloon, mFileList[24], mRenderer);
success &= loadTextureFromFile(mTextureBullet, mFileList[25], mRenderer);
success &= loadTextureFromFile(mTextureGameBG, mFileList[31], mRenderer);
@@ -1511,7 +1549,7 @@ void Game::renderScoreBoard()
color_t color = {0, 0, 0};
// Si el jugador esta muerto, no pintes el fondo del marcador, así que pase por encima cuando sale despedido
if (mPlayer->isAlive())
if (mPlayer[0]->isAlive())
mSpriteScoreBoard->render();
//if (!mDemo.enabled)
@@ -1529,9 +1567,9 @@ void Game::renderScoreBoard()
mText->writeColored(MULTIPLIER_WORD_X, MULTIPLIER_WORD_Y - 6, mTextStrings[41], color);
color.g = 192;
mTextX2->writeShadowed(PLAY_AREA_CENTER_X - 16, SCORE_WORD_Y + 5, std::to_string(mPlayer->getScoreMultiplier()).substr(0, 1), color, 1);
mTextX2->writeShadowed(PLAY_AREA_CENTER_X - 16, SCORE_WORD_Y + 5, std::to_string(mPlayer[0]->getScoreMultiplier()).substr(0, 1), color, 1);
mText->writeShadowed(PLAY_AREA_CENTER_X - 2, SCORE_WORD_Y + 12, ".", color);
mText->writeShadowed(PLAY_AREA_CENTER_X + 4, SCORE_WORD_Y + 12, std::to_string(mPlayer->getScoreMultiplier()).substr(2, 1), color);
mText->writeShadowed(PLAY_AREA_CENTER_X + 4, SCORE_WORD_Y + 12, std::to_string(mPlayer[0]->getScoreMultiplier()).substr(2, 1), color);
// STAGE
mText->writeCentered(PLAY_AREA_CENTER_FIRST_QUARTER_X, SCORE_NUMBER_Y + 4, mTextStrings[42] + std::to_string(mStage[mCurrentStage].number), 0);
@@ -1548,17 +1586,20 @@ void Game::renderScoreBoard()
// Actualiza las variables del jugador
void Game::updatePlayer()
{
mPlayer->update();
// Comprueba la colisión entre el jugador y los globos
if (checkPlayerBalloonCollision())
for (int i = 0; i < mNumPlayers; i++)
{
if (mPlayer->isAlive())
mPlayer[i]->update();
// Comprueba la colisión entre el jugador y los globos
if (checkPlayerBalloonCollision())
{
if (mDemo.enabled)
mSection = {PROG_SECTION_TITLE, TITLE_SECTION_INSTRUCTIONS};
else
killPlayer();
if (mPlayer[i]->isAlive())
{
if (mDemo.enabled)
mSection = {PROG_SECTION_TITLE, TITLE_SECTION_INSTRUCTIONS};
else
killPlayer();
}
}
}
}
@@ -1601,7 +1642,7 @@ void Game::updateStage()
// Actualiza el estado de muerte
void Game::updateDeath()
{
if (!mPlayer->isAlive())
if (!mPlayer[0]->isAlive())
{
if (mDeathCounter > 0)
{
@@ -1823,8 +1864,8 @@ void Game::updateBalloonSpeed()
void Game::popBalloon(Uint8 index)
{
// Otorga los puntos correspondientes al globo
mPlayer->addScore(Uint32(mBalloon[index]->getScore() * mPlayer->getScoreMultiplier()));
setScore(mPlayer->getScore());
mPlayer[0]->addScore(Uint32(mBalloon[index]->getScore() * mPlayer[0]->getScoreMultiplier()));
setScore(mPlayer[0]->getScore());
updateHiScore();
// Aumenta el poder de la fase
@@ -1914,8 +1955,8 @@ void Game::destroyBalloon(Uint8 index)
}
// Otorga los puntos correspondientes al globo
mPlayer->addScore(Uint32(score * mPlayer->getScoreMultiplier()));
setScore(mPlayer->getScore());
mPlayer[0]->addScore(Uint32(score * mPlayer[0]->getScoreMultiplier()));
setScore(mPlayer[0]->getScore());
updateHiScore();
// Aumenta el poder de la fase
@@ -1991,10 +2032,11 @@ Uint8 Game::countBalloons()
// Comprueba la colisión entre el jugador y los globos activos
bool Game::checkPlayerBalloonCollision()
{
for (int i = 0; i < MAX_BALLOONS; i++)
if ((mBalloon[i]->isEnabled()) && !(mBalloon[i]->isStopped()) && !(mBalloon[i]->isInvulnerable()))
if (checkCollision(mPlayer->getCollider(), mBalloon[i]->getCollider()))
return true;
for (int j = 0; j < mNumPlayers; j++)
for (int i = 0; i < MAX_BALLOONS; i++)
if ((mBalloon[i]->isEnabled()) && !(mBalloon[i]->isStopped()) && !(mBalloon[i]->isInvulnerable()))
if (checkCollision(mPlayer[j]->getCollider(), mBalloon[i]->getCollider()))
return true;
return false;
}
@@ -2002,57 +2044,59 @@ bool Game::checkPlayerBalloonCollision()
// Comprueba la colisión entre el jugador y los items
void Game::checkPlayerItemCollision()
{
if (mPlayer->isAlive())
for (int i = 0; i < MAX_ITEMS; i++)
{
if (mItem[i]->isEnabled())
{
if (checkCollision(mPlayer->getCollider(), mItem[i]->getCollider()))
{
switch (mItem[i]->getClass())
{
case ITEM_POINTS_1_DISK:
mPlayer->addScore(1000);
setScore(mPlayer->getScore());
updateHiScore();
createItemScoreSprite(mItem[i]->getPosX() + (mItem[i]->getWidth() / 2) - (m1000Bitmap->getWidth() / 2), mPlayer->getPosY(), m1000Bitmap);
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_POINTS_2_GAVINA:
mPlayer->addScore(2500);
setScore(mPlayer->getScore());
updateHiScore();
createItemScoreSprite(mItem[i]->getPosX() + (mItem[i]->getWidth() / 2) - (m2500Bitmap->getWidth() / 2), mPlayer->getPosY(), m2500Bitmap);
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_POINTS_3_PACMAR:
mPlayer->addScore(5000);
setScore(mPlayer->getScore());
updateHiScore();
createItemScoreSprite(mItem[i]->getPosX() + (mItem[i]->getWidth() / 2) - (m5000Bitmap->getWidth() / 2), mPlayer->getPosY(), m5000Bitmap);
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_CLOCK:
enableTimeStopItem();
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_COFFEE:
mPlayer->giveExtraHit();
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_COFFEE_MACHINE:
mPlayer->setPowerUp(true);
JA_PlaySound(mSoundItemPickup);
mCoffeeMachineEnabled = false;
break;
for (int j = 0; j < mNumPlayers; j++)
default:
break;
if (mPlayer[j]->isAlive())
for (int i = 0; i < MAX_ITEMS; i++)
{
if (mItem[i]->isEnabled())
{
if (checkCollision(mPlayer[j]->getCollider(), mItem[i]->getCollider()))
{
switch (mItem[i]->getClass())
{
case ITEM_POINTS_1_DISK:
mPlayer[j]->addScore(1000);
setScore(mPlayer[j]->getScore());
updateHiScore();
createItemScoreSprite(mItem[i]->getPosX() + (mItem[i]->getWidth() / 2) - (m1000Bitmap->getWidth() / 2), mPlayer[j]->getPosY(), m1000Bitmap);
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_POINTS_2_GAVINA:
mPlayer[j]->addScore(2500);
setScore(mPlayer[j]->getScore());
updateHiScore();
createItemScoreSprite(mItem[i]->getPosX() + (mItem[i]->getWidth() / 2) - (m2500Bitmap->getWidth() / 2), mPlayer[j]->getPosY(), m2500Bitmap);
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_POINTS_3_PACMAR:
mPlayer[j]->addScore(5000);
setScore(mPlayer[j]->getScore());
updateHiScore();
createItemScoreSprite(mItem[i]->getPosX() + (mItem[i]->getWidth() / 2) - (m5000Bitmap->getWidth() / 2), mPlayer[j]->getPosY(), m5000Bitmap);
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_CLOCK:
enableTimeStopItem();
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_COFFEE:
mPlayer[j]->giveExtraHit();
JA_PlaySound(mSoundItemPickup);
break;
case ITEM_COFFEE_MACHINE:
mPlayer[j]->setPowerUp(true);
JA_PlaySound(mSoundItemPickup);
mCoffeeMachineEnabled = false;
break;
default:
break;
}
mItem[i]->erase();
}
mItem[i]->erase();
}
}
}
}
// Comprueba y procesa la colisión entre las balas y los globos
@@ -2063,7 +2107,7 @@ void Game::checkBulletBalloonCollision()
if (mBalloon[i]->isEnabled() && (!mBalloon[i]->isInvulnerable()) && mBullet[j]->isActive())
if (checkCollision(mBalloon[i]->getCollider(), mBullet[j]->getCollider()))
{
mPlayer->incScoreMultiplier();
mPlayer[0]->incScoreMultiplier();
popBalloon(i);
if (!mDemo.enabled)
JA_PlaySound(mSoundBalloon);
@@ -2088,7 +2132,7 @@ void Game::moveBullets()
for (int i = 0; i < MAX_BULLETS; i++)
if (mBullet[i]->isActive())
if (mBullet[i]->move() == MSG_BULLET_OUT)
mPlayer->decScoreMultiplier();
mPlayer[0]->decScoreMultiplier();
}
// Pinta las balas activas
@@ -2296,7 +2340,7 @@ void Game::throwPlayer(int x, int y)
const int sentit = ((rand() % 2) ? 1 : -1);
mDeathIndex = getSmartSpriteFreeIndex();
mSmartSprite[mDeathIndex]->init(mTexturePlayerDeath, mRenderer);
mSmartSprite[mDeathIndex]->init(mTexturePlayer1Death, mRenderer);
mSmartSprite[mDeathIndex]->setPosX(x);
mSmartSprite[mDeathIndex]->setPosY(y);
mSmartSprite[mDeathIndex]->setWidth(24);
@@ -2346,26 +2390,28 @@ void Game::resetSmartSprites()
// Acciones a realizar cuando el jugador muere
void Game::killPlayer()
{
if (!mPlayer->isInvulnerable())
{
if (mPlayer->hasExtraHit())
for (int i = 0; i < mNumPlayers; i++)
if (!mPlayer[i]->isInvulnerable())
{
mPlayer->removeExtraHit();
throwCoffee(mPlayer->getPosX() + (mPlayer->getWidth() / 2), mPlayer->getPosY() + (mPlayer->getHeight() / 2));
JA_PlaySound(mSoundCoffeeOut);
if (mPlayer[i]->hasExtraHit())
{
mPlayer[i]->removeExtraHit();
throwCoffee(mPlayer[i]->getPosX() + (mPlayer[i]->getWidth() / 2), mPlayer[i]->getPosY() + (mPlayer[i]->getHeight() / 2));
JA_PlaySound(mSoundCoffeeOut);
}
else
{
stopAllBalloons(10);
JA_StopMusic();
JA_PlaySound(mSoundPlayerCollision);
shakeScreen();
SDL_Delay(500);
JA_PlaySound(mSoundCoffeeOut);
throwPlayer(mPlayer[i]->getPosX(), mPlayer[i]->getPosY());
mPlayer[i]->setAlive(false);
}
}
else
{
stopAllBalloons(10);
JA_StopMusic();
JA_PlaySound(mSoundPlayerCollision);
shakeScreen();
SDL_Delay(500);
JA_PlaySound(mSoundCoffeeOut);
throwPlayer(mPlayer->getPosX(), mPlayer->getPosY());
mPlayer->setAlive(false);
}
}
}
// Calcula y establece el valor de amenaza en funcion de los globos activos
@@ -2594,8 +2640,9 @@ void Game::renderPlayField()
renderItems();
renderSmartSprites();
renderScoreBoard();
mPlayer->render();
if ((mDeathCounter <= 150) && !mPlayer->isAlive())
for (int i = 0; i < mNumPlayers; i++)
mPlayer[i]->render();
if ((mDeathCounter <= 150) && !mPlayer[0]->isAlive())
renderDeathFade(150 - mDeathCounter);
if ((mGameCompleted) && (mGameCompletedCounter >= 300))
renderDeathFade(mGameCompletedCounter - 300);
@@ -2636,40 +2683,40 @@ void Game::checkGameInput()
if (mDemo.enabled)
{
if (mDemo.dataFile[mDemo.counter].left == 1)
mPlayer->setInput(INPUT_LEFT);
mPlayer[0]->setInput(INPUT_LEFT);
if (mDemo.dataFile[mDemo.counter].right == 1)
mPlayer->setInput(INPUT_RIGHT);
mPlayer[0]->setInput(INPUT_RIGHT);
if (mDemo.dataFile[mDemo.counter].noInput == 1)
mPlayer->setInput(NO_INPUT);
mPlayer[0]->setInput(NO_INPUT);
if (mDemo.dataFile[mDemo.counter].fire == 1)
if (mPlayer->canFire())
if (mPlayer[0]->canFire())
{
mPlayer->setInput(INPUT_FIRE_UP);
createBullet(mPlayer->getPosX() + (mPlayer->getWidth() / 2) - 4, mPlayer->getPosY() + (mPlayer->getHeight() / 2), BULLET_UP, mPlayer->isPowerUp());
mPlayer->setFireCooldown(10);
mPlayer[0]->setInput(INPUT_FIRE_UP);
createBullet(mPlayer[0]->getPosX() + (mPlayer[0]->getWidth() / 2) - 4, mPlayer[0]->getPosY() + (mPlayer[0]->getHeight() / 2), BULLET_UP, mPlayer[0]->isPowerUp());
mPlayer[0]->setFireCooldown(10);
}
if (mDemo.dataFile[mDemo.counter].fireLeft == 1)
if (mPlayer->canFire())
if (mPlayer[0]->canFire())
{
mPlayer->setInput(INPUT_FIRE_LEFT);
createBullet(mPlayer->getPosX() + (mPlayer->getWidth() / 2) - 4, mPlayer->getPosY() + (mPlayer->getHeight() / 2), BULLET_UP, mPlayer->isPowerUp());
mPlayer->setFireCooldown(10);
mPlayer[0]->setInput(INPUT_FIRE_LEFT);
createBullet(mPlayer[0]->getPosX() + (mPlayer[0]->getWidth() / 2) - 4, mPlayer[0]->getPosY() + (mPlayer[0]->getHeight() / 2), BULLET_UP, mPlayer[0]->isPowerUp());
mPlayer[0]->setFireCooldown(10);
}
if (mDemo.dataFile[mDemo.counter].fireRight == 1)
if (mPlayer->canFire())
if (mPlayer[0]->canFire())
{
mPlayer->setInput(INPUT_FIRE_RIGHT);
createBullet(mPlayer->getPosX() + (mPlayer->getWidth() / 2) - 4, mPlayer->getPosY() + (mPlayer->getHeight() / 2), BULLET_UP, mPlayer->isPowerUp());
mPlayer->setFireCooldown(10);
mPlayer[0]->setInput(INPUT_FIRE_RIGHT);
createBullet(mPlayer[0]->getPosX() + (mPlayer[0]->getWidth() / 2) - 4, mPlayer[0]->getPosY() + (mPlayer[0]->getHeight() / 2), BULLET_UP, mPlayer[0]->isPowerUp());
mPlayer[0]->setFireCooldown(10);
}
// Comprueba el input de pausa
if (mInput->checkInput(INPUT_PAUSE, REPEAT_FALSE))
if (mInput[0]->checkInput(INPUT_PAUSE, REPEAT_FALSE))
mSection.name = PROG_SECTION_TITLE;
// Incrementa el contador de la demo
@@ -2679,97 +2726,99 @@ void Game::checkGameInput()
mSection = {PROG_SECTION_TITLE, TITLE_SECTION_INSTRUCTIONS};
}
// Modo Demo no activo
else if (mPlayer->isAlive())
{
// Input a la izquierda
if (mInput->checkInput(INPUT_LEFT, REPEAT_TRUE))
{
mPlayer->setInput(INPUT_LEFT);
mDemo.keys.left = 1;
}
else
{
// Input a la derecha
if (mInput->checkInput(INPUT_RIGHT, REPEAT_TRUE))
else
for (int i = 0; i < mNumPlayers; i++)
if (mPlayer[i]->isAlive())
{
mPlayer->setInput(INPUT_RIGHT);
mDemo.keys.right = 1;
// Input a la izquierda
if (mInput[i]->checkInput(INPUT_LEFT, REPEAT_TRUE))
{
mPlayer[i]->setInput(INPUT_LEFT);
mDemo.keys.left = 1;
}
else
{
// Input a la derecha
if (mInput[i]->checkInput(INPUT_RIGHT, REPEAT_TRUE))
{
mPlayer[i]->setInput(INPUT_RIGHT);
mDemo.keys.right = 1;
}
else
{
// Ninguno de los dos inputs anteriores
mPlayer[i]->setInput(NO_INPUT);
mDemo.keys.noInput = 1;
}
}
// Comprueba el input de disparar al centro
if (mInput[i]->checkInput(INPUT_BUTTON_2, REPEAT_TRUE))
{
if (mPlayer[i]->canFire())
{
mPlayer[i]->setInput(INPUT_FIRE_UP);
createBullet(mPlayer[i]->getPosX() + (mPlayer[i]->getWidth() / 2) - 4, mPlayer[i]->getPosY() + (mPlayer[i]->getHeight() / 2), BULLET_UP, mPlayer[i]->isPowerUp());
mPlayer[i]->setFireCooldown(10);
// Reproduce el sonido de disparo
JA_PlaySound(mSoundBullet);
mDemo.keys.fire = 1;
}
}
// Comprueba el input de disparar a la izquierda
if (mInput[i]->checkInput(INPUT_BUTTON_1, REPEAT_TRUE))
{
if (mPlayer[i]->canFire())
{
mPlayer[i]->setInput(INPUT_FIRE_LEFT);
createBullet(mPlayer[i]->getPosX() + (mPlayer[i]->getWidth() / 2) - 4, mPlayer[i]->getPosY() + (mPlayer[i]->getHeight() / 2), BULLET_LEFT, mPlayer[i]->isPowerUp());
mPlayer[i]->setFireCooldown(10);
// Reproduce el sonido de disparo
JA_PlaySound(mSoundBullet);
mDemo.keys.fireLeft = 1;
}
}
// Comprueba el input de disparar a la derecha
if (mInput[i]->checkInput(INPUT_BUTTON_3, REPEAT_TRUE))
{
if (mPlayer[i]->canFire())
{
mPlayer[i]->setInput(INPUT_FIRE_RIGHT);
createBullet(mPlayer[i]->getPosX() + (mPlayer[i]->getWidth() / 2) - 4, mPlayer[i]->getPosY() + (mPlayer[i]->getHeight() / 2), BULLET_RIGHT, mPlayer[i]->isPowerUp());
mPlayer[i]->setFireCooldown(10);
// Reproduce el sonido de disparo
JA_PlaySound(mSoundBullet);
mDemo.keys.fireRight = 1;
}
}
// Comprueba el input de pausa
if (mInput[i]->checkInput(INPUT_CANCEL, REPEAT_FALSE))
{
mSection.subsection = GAME_SECTION_PAUSE;
if (JA_GetMusicState() == JA_MUSIC_PLAYING)
JA_PauseMusic();
}
if (mDemo.counter < TOTAL_DEMO_DATA)
{
if (mDemo.recording)
mDemo.dataFile[mDemo.counter] = mDemo.keys;
mDemo.counter++;
}
else if (mDemo.recording)
{
mSection.name = PROG_SECTION_QUIT;
}
}
else
{
// Ninguno de los dos inputs anteriores
mPlayer->setInput(NO_INPUT);
mDemo.keys.noInput = 1;
}
}
// Comprueba el input de disparar al centro
if (mInput->checkInput(INPUT_BUTTON_2, REPEAT_TRUE))
{
if (mPlayer->canFire())
{
mPlayer->setInput(INPUT_FIRE_UP);
createBullet(mPlayer->getPosX() + (mPlayer->getWidth() / 2) - 4, mPlayer->getPosY() + (mPlayer->getHeight() / 2), BULLET_UP, mPlayer->isPowerUp());
mPlayer->setFireCooldown(10);
// Reproduce el sonido de disparo
JA_PlaySound(mSoundBullet);
mDemo.keys.fire = 1;
}
}
// Comprueba el input de disparar a la izquierda
if (mInput->checkInput(INPUT_BUTTON_1, REPEAT_TRUE))
{
if (mPlayer->canFire())
{
mPlayer->setInput(INPUT_FIRE_LEFT);
createBullet(mPlayer->getPosX() + (mPlayer->getWidth() / 2) - 4, mPlayer->getPosY() + (mPlayer->getHeight() / 2), BULLET_LEFT, mPlayer->isPowerUp());
mPlayer->setFireCooldown(10);
// Reproduce el sonido de disparo
JA_PlaySound(mSoundBullet);
mDemo.keys.fireLeft = 1;
}
}
// Comprueba el input de disparar a la derecha
if (mInput->checkInput(INPUT_BUTTON_3, REPEAT_TRUE))
{
if (mPlayer->canFire())
{
mPlayer->setInput(INPUT_FIRE_RIGHT);
createBullet(mPlayer->getPosX() + (mPlayer->getWidth() / 2) - 4, mPlayer->getPosY() + (mPlayer->getHeight() / 2), BULLET_RIGHT, mPlayer->isPowerUp());
mPlayer->setFireCooldown(10);
// Reproduce el sonido de disparo
JA_PlaySound(mSoundBullet);
mDemo.keys.fireRight = 1;
}
}
// Comprueba el input de pausa
if (mInput->checkInput(INPUT_CANCEL, REPEAT_FALSE))
{
mSection.subsection = GAME_SECTION_PAUSE;
if (JA_GetMusicState() == JA_MUSIC_PLAYING)
JA_PauseMusic();
}
if (mDemo.counter < TOTAL_DEMO_DATA)
{
if (mDemo.recording)
mDemo.dataFile[mDemo.counter] = mDemo.keys;
mDemo.counter++;
}
else if (mDemo.recording)
{
mSection.name = PROG_SECTION_QUIT;
}
}
}
// Pinta diferentes mensajes en la pantalla
@@ -2864,7 +2913,8 @@ void Game::shakeScreen()
renderBalloons();
renderBullets();
renderItems();
mPlayer->render();
for (int i = 0; i < mNumPlayers; i++)
mPlayer[i]->render();
renderScoreBoard();
// Actualiza la pantalla
@@ -2896,7 +2946,7 @@ section_t Game::run()
{
// Reproduce la música
if (!mGameCompleted)
if (mPlayer->isAlive())
if (mPlayer[0]->isAlive())
JA_PlayMusic(mMusicPlaying);
}
@@ -2959,8 +3009,8 @@ section_t Game::run()
break;
case SDL_SCANCODE_I:
mPlayer->setInvulnerable(true);
mPlayer->setInvulnerableCounter(65000);
mPlayer[0]->setInvulnerable(true);
mPlayer[0]->setInvulnerableCounter(65000);
break;
case SDL_SCANCODE_M:
@@ -3039,7 +3089,8 @@ void Game::runPausedGame()
renderBackground();
renderBalloons();
renderBullets();
mPlayer->render();
for (int i = 0; i < mNumPlayers; i++)
mPlayer[i]->render();
renderScoreBoard();
mMenuPause->render();
mFade->render();
@@ -3130,7 +3181,7 @@ void Game::runGameOverScreen()
// Dibuja los objetos
mTextX2->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 4), mTextStrings[43], 0);
mText->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 1), mTextStrings[44] + std::to_string(mPlayer->getScore()), 0);
mText->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y - (BLOCK * 1), mTextStrings[44] + std::to_string(mPlayer[0]->getScore()), 0);
mText->writeCentered(PLAY_AREA_CENTER_X, PLAY_AREA_CENTER_Y + BLOCK * 2, mTextStrings[45], 0);
mMenuGameOver->render();
mFade->render();
@@ -3175,7 +3226,7 @@ void Game::renderDebugInfo()
mText->writeShadowed(2, 2 + 3 * BLOCK, "mCounter: " + std::to_string(mCounter), color);
mText->writeShadowed(2, 2 + 4 * BLOCK, "(R)enemyset: " + std::to_string(mDebug.enemySet), color);
mText->writeShadowed(2, 2 + 5 * BLOCK, "RGB: " + std::to_string(mDebug.gradR) + "," + std::to_string(mDebug.gradG) + "," + std::to_string(mDebug.gradB), color);
mText->writeShadowed(2, 2 + 6 * BLOCK, "(I)invuln: " + std::to_string(mPlayer->getInvulnerableCounter()), color);
mText->writeShadowed(2, 2 + 6 * BLOCK, "(I)invuln: " + std::to_string(mPlayer[0]->getInvulnerableCounter()), color);
mText->writeShadowed(2, 2 + 7 * BLOCK, "balloons: " + std::to_string(countBalloons()), color);
mText->writeShadowed(2, 2 + 8 * BLOCK, "balloonsPop: " + std::to_string(mBalloonsPopped), color);
mText->writeShadowed(2, 2 + 9 * BLOCK, "(Z-X)ballSped:" + std::to_string(mEnemySpeed), color);
@@ -3268,12 +3319,12 @@ void Game::updateHelper()
// Solo ofrece ayuda cuando la amenaza o la velocidad es elevada
if (mMenaceCurrent > 15)
{
if (mPlayer->getCoffees() == 0)
if (mPlayer[0]->getCoffees() == 0)
mHelper.needCoffee = true;
else
mHelper.needCoffee = false;
if (!mPlayer->isPowerUp())
if (!mPlayer[0]->isPowerUp())
mHelper.needCoffeeMachine = true;
else
mHelper.needCoffeeMachine = false;

View File

@@ -82,26 +82,31 @@ private:
SDL_Renderer *mRenderer; // El renderizador de la ventana
std::string *mFileList; // Lista de ficheros con los recursos
std::string *mTextStrings; // Vector con los textos del juego
Input *mInput; // Manejador de entrada
Input *mInput[2]; // Manejador de entrada
Player *mPlayer; // El jugador
int mNumPlayers; // Numero de jugadores
Player *mPlayer[2]; // Vector con los jugadores jugador
Balloon *mBalloon[MAX_BALLOONS]; // Vector con los objetos globo
Bullet *mBullet[MAX_BULLETS]; // Vector con los objetos bala
Item *mItem[MAX_ITEMS]; // Vector con los objetos item
SmartSprite *mSmartSprite[MAX_SMART_SPRITES]; // Vector para almacenar y gestionar SmartSprites
LTexture *mTextureBalloon; // Textura para los enemigos
LTexture *mTextureBullet; // Textura para las balas
LTexture *mTextureGameBG; // Textura para el fondo del juego
LTexture *mTextureGameText; // Textura para los sprites con textos
LTexture *mTextureItems; // Textura para los items
LTexture *mTexturePlayerHead; // Textura para la cabeza del jugador
LTexture *mTexturePlayerBody; // Textura para el cuerpo del jugador
LTexture *mTexturePlayerDeath; // Textura para la animación de muerte del jugador
LTexture *mTexturePlayerLegs; // Textura para las piernas del jugador
LTexture *mTextureText; // Textura para el texto
LTexture *mTextureText2; // Textura para el texto
LTexture *mTextureBalloon; // Textura para los enemigos
LTexture *mTextureBullet; // Textura para las balas
LTexture *mTextureGameBG; // Textura para el fondo del juego
LTexture *mTextureGameText; // Textura para los sprites con textos
LTexture *mTextureItems; // Textura para los items
LTexture *mTexturePlayer1Head; // Textura para la cabeza del jugador1
LTexture *mTexturePlayer1Body; // Textura para el cuerpo del jugador1
LTexture *mTexturePlayer1Death; // Textura para la animación de muerte del jugador1
LTexture *mTexturePlayer1Legs; // Textura para las piernas del jugador
LTexture *mTexturePlayer2Head; // Textura para la cabeza del jugador2
LTexture *mTexturePlayer2Body; // Textura para el cuerpo del jugador2
LTexture *mTexturePlayer2Death; // Textura para la animación de muerte del jugador2
LTexture *mTexturePlayer2Legs; // Textura para las piernas del jugador
LTexture *mTextureText; // Textura para el texto
LTexture *mTextureText2; // Textura para el texto
Text *mText; // Variable con todos los objetos de texto
Text *mTextX2; // Variable con todos los objetos de texto
@@ -202,7 +207,7 @@ private:
public:
// Constructor
Game(SDL_Renderer *renderer, std::string *filelist, std::string *textStrings, Input *input, bool demo);
Game(int numPlayers, SDL_Renderer *renderer, std::string *filelist, std::string *textStrings, Input *input1, Input *input2, bool demo);
// Destructor
~Game();

View File

@@ -684,7 +684,7 @@ void Title::runInstructions(Uint8 mode)
// Ejecuta el juego en modo demo
void Title::runDemoGame()
{
mDemoGame = new Game(mRenderer, mFileList, mTextStrings, mInput, true);
mDemoGame = new Game(1, mRenderer, mFileList, mTextStrings, mInput, mInput, true);
mDemoGame->run();
delete mDemoGame;
}