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

View File

@@ -32,7 +32,8 @@ private:
SDL_Window *mWindow; // La ventana donde dibujamos SDL_Window *mWindow; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana 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 Logo *mLogo; // Objeto para la sección del logo
Intro *mIntro; // Objeto para la sección de la intro Intro *mIntro; // Objeto para la sección de la intro

View File

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

View File

@@ -82,9 +82,10 @@ private:
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Renderer *mRenderer; // El renderizador de la ventana
std::string *mFileList; // Lista de ficheros con los recursos std::string *mFileList; // Lista de ficheros con los recursos
std::string *mTextStrings; // Vector con los textos del juego 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 Balloon *mBalloon[MAX_BALLOONS]; // Vector con los objetos globo
Bullet *mBullet[MAX_BULLETS]; // Vector con los objetos bala Bullet *mBullet[MAX_BULLETS]; // Vector con los objetos bala
@@ -96,10 +97,14 @@ private:
LTexture *mTextureGameBG; // Textura para el fondo del juego LTexture *mTextureGameBG; // Textura para el fondo del juego
LTexture *mTextureGameText; // Textura para los sprites con textos LTexture *mTextureGameText; // Textura para los sprites con textos
LTexture *mTextureItems; // Textura para los items LTexture *mTextureItems; // Textura para los items
LTexture *mTexturePlayerHead; // Textura para la cabeza del jugador LTexture *mTexturePlayer1Head; // Textura para la cabeza del jugador1
LTexture *mTexturePlayerBody; // Textura para el cuerpo del jugador LTexture *mTexturePlayer1Body; // Textura para el cuerpo del jugador1
LTexture *mTexturePlayerDeath; // Textura para la animación de muerte del jugador LTexture *mTexturePlayer1Death; // Textura para la animación de muerte del jugador1
LTexture *mTexturePlayerLegs; // Textura para las piernas del jugador 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 *mTextureText; // Textura para el texto
LTexture *mTextureText2; // Textura para el texto LTexture *mTextureText2; // Textura para el texto
@@ -202,7 +207,7 @@ private:
public: public:
// Constructor // 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 // Destructor
~Game(); ~Game();

View File

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