diff --git a/media/.DS_Store b/media/.DS_Store index 5c8baf3..3e05191 100644 Binary files a/media/.DS_Store and b/media/.DS_Store differ diff --git a/media/sound/credits.txt b/media/sound/credits.txt index 067168a..06815b1 100644 --- a/media/sound/credits.txt +++ b/media/sound/credits.txt @@ -42,8 +42,7 @@ stage_change.wav JailDoctor menu_cancel.wav -kenney_digitalaudio/lowRandom.ogg -kenney_digitalaudio/pepSound1.ogg <- +kenney_digitalaudio/pepSound1.ogg www.kenney.nl bubble1.wav @@ -60,4 +59,7 @@ JailDoctor clock.wav kenney_digitalaudio/switch2.ogg -www.kenney.nl \ No newline at end of file +www.kenney.nl + +powerball.wav +JailDoctor \ No newline at end of file diff --git a/media/sound/powerball.wav b/media/sound/powerball.wav new file mode 100644 index 0000000..d401237 Binary files /dev/null and b/media/sound/powerball.wav differ diff --git a/source/animatedsprite.cpp b/source/animatedsprite.cpp index a6d1985..44847c6 100644 --- a/source/animatedsprite.cpp +++ b/source/animatedsprite.cpp @@ -40,30 +40,29 @@ void AnimatedSprite::init(LTexture *texture, SDL_Renderer *renderer) // Calcula el frame correspondiente a la animación void AnimatedSprite::animate(int index) { - // Calculamos el frame actual a partir del contador - mCurrentFrame = mAnimationCounter / mAnimation[index].speed; - - // Si alcanzamos el final de la animación, reiniciamos el contador de la animación - // en función de la variable loop - if (mCurrentFrame >= mAnimation[index].numFrames) + if (mEnabled) { - if (mAnimation[index].loop) + // Calculamos el frame actual a partir del contador + mCurrentFrame = mAnimationCounter / mAnimation[index].speed; + + // Si alcanzamos el final de la animación, reiniciamos el contador de la animación + // en función de la variable loop + if (mCurrentFrame >= mAnimation[index].numFrames) { - mAnimationCounter = 0; + if (mAnimation[index].loop) + mAnimationCounter = 0; + else + mCurrentFrame = mAnimation[index].numFrames; } + // En caso contrario else { - mCurrentFrame = mAnimation[index].numFrames; - } - } - // En caso contrario - else - { - // Escogemos el frame correspondiente de la animación - setSpriteClip(mAnimation[index].frames[mCurrentFrame]); + // Escogemos el frame correspondiente de la animación + setSpriteClip(mAnimation[index].frames[mCurrentFrame]); - // Incrementamos el contador de la animacion - ++mAnimationCounter; + // Incrementamos el contador de la animacion + mAnimationCounter++; + } } } diff --git a/source/balloon.cpp b/source/balloon.cpp index e6c84e7..9b79f67 100644 --- a/source/balloon.cpp +++ b/source/balloon.cpp @@ -34,8 +34,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_1; - mHeight = BALLOON_SIZE_1; + mWidth = BALLOON_WIDTH_1; + mHeight = BALLOON_WIDTH_1; + mSize = BALLOON_SIZE_1; + mPower = 1; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -45,7 +47,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = 2.6f; // Puntos que da el globo al ser destruido - mScore = 50; + mScore = BALLOON_SCORE_1; // Amenaza que genera el globo mMenace = 1; @@ -66,8 +68,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_2; - mHeight = BALLOON_SIZE_2; + mWidth = BALLOON_WIDTH_2; + mHeight = BALLOON_WIDTH_2; + mSize = BALLOON_SIZE_2; + mPower = 3; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -77,7 +81,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = 3.5f; // Puntos que da el globo al ser destruido - mScore = 100; + mScore = BALLOON_SCORE_2; // Amenaza que genera el globo mMenace = 2; @@ -98,8 +102,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_3; - mHeight = BALLOON_SIZE_3; + mWidth = BALLOON_WIDTH_3; + mHeight = BALLOON_WIDTH_3; + mSize = BALLOON_SIZE_3; + mPower = 7; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -109,7 +115,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = 4.50f; // Puntos que da el globo al ser destruido - mScore = 200; + mScore = BALLOON_SCORE_3; // Amenaza que genera el globo mMenace = 4; @@ -130,8 +136,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_4; - mHeight = BALLOON_SIZE_4; + mWidth = BALLOON_WIDTH_4; + mHeight = BALLOON_WIDTH_4; + mSize = BALLOON_SIZE_4; + mPower = 15; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -141,7 +149,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = 4.95f; // Puntos que da el globo al ser destruido - mScore = 400; + mScore = BALLOON_SCORE_4; // Amenaza que genera el globo mMenace = 8; @@ -162,8 +170,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_1; - mHeight = BALLOON_SIZE_1; + mWidth = BALLOON_WIDTH_1; + mHeight = BALLOON_WIDTH_1; + mSize = BALLOON_SIZE_1; + mPower = 1; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -173,7 +183,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = abs(velx) * 2; // Puntos que da el globo al ser destruido - mScore = 50; + mScore = BALLOON_SCORE_1; // Amenaza que genera el globo mMenace = 1; @@ -194,8 +204,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_2; - mHeight = BALLOON_SIZE_2; + mWidth = BALLOON_WIDTH_2; + mHeight = BALLOON_WIDTH_2; + mSize = BALLOON_SIZE_2; + mPower = 3; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -205,7 +217,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = abs(velx) * 2; // Puntos que da el globo al ser destruido - mScore = 100; + mScore = BALLOON_SCORE_2; // Amenaza que genera el globo mMenace = 2; @@ -226,8 +238,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_3; - mHeight = BALLOON_SIZE_3; + mWidth = BALLOON_WIDTH_3; + mHeight = BALLOON_WIDTH_3; + mSize = BALLOON_SIZE_3; + mPower = 7; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -237,7 +251,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = abs(velx) * 2; // Puntos que da el globo al ser destruido - mScore = 200; + mScore = BALLOON_SCORE_3; // Amenaza que genera el globo mMenace = 4; @@ -258,8 +272,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_4; - mHeight = BALLOON_SIZE_4; + mWidth = BALLOON_WIDTH_4; + mHeight = BALLOON_WIDTH_4; + mSize = BALLOON_SIZE_4; + mPower = 15; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -269,7 +285,7 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mDefaultVelY = abs(velx) * 2; // Puntos que da el globo al ser destruido - mScore = 400; + mScore = BALLOON_SCORE_4; // Amenaza que genera el globo mMenace = 8; @@ -290,8 +306,10 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mEnabled = true; // Alto y ancho del objeto - mWidth = BALLOON_SIZE_4; - mHeight = BALLOON_SIZE_4; + mWidth = BALLOON_WIDTH_4; + mHeight = BALLOON_WIDTH_4; + mSize = 4; + mPower = 0; // Inicializa los valores de velocidad y gravedad mVelX = velx; @@ -311,11 +329,15 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, OFFSET_POWER_BALL, 37 * i, getWidth(), getHeight()); for (Uint8 i = 0; i < NUM_FRAMES_BALLON_BORN; i++) - mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, OFFSET_BLUE_BALLOONS, 37 * i, getWidth(), getHeight()); + mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, OFFSET_POWER_BALL, 37 * i, getWidth(), getHeight()); for (Uint8 i = 0; i < NUM_FRAMES_BALLON_POP; i++) mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, OFFSET_EXPLOSIONS, 37 * i, getWidth(), getHeight()); + // Añade rotación al sprite + mSprite->setRotate(false); + mSprite->setRotateSpeed(1); + mSprite->setRotateAmount(2.0); break; default: @@ -471,6 +493,9 @@ void Balloon::move() // Invierte sentido mVelX = -mVelX; + // Invierte la rotación + mSprite->switchRotate(); + // Activa el efecto de rebote bounceStart(); } @@ -539,33 +564,38 @@ void Balloon::move() // Deshabilita el globo y pone a cero todos los valores void Balloon::disable() { - mEnabled = false; - - mPosX = 0.0f; - mPosY = 0.0f; - mWidth = 0; - mHeight = 0; - mVelX = 0.0f; - mVelY = 0.0f; - mGravity = 0.0f; - mDefaultVelY = 0.0f; - mMaxVelY = 0.0f; mBeingCreated = false; mBlinking = false; - mInvulnerable = false; - mPopping = false; - mStopped = false; - mVisible = false; + mCollider.r = 0; mCollider.x = 0; mCollider.y = 0; - mCollider.r = 0; + mCounter = 0; mCreationCounter = 0; mCreationCounterIni = 0; + mDefaultVelY = 0.0f; + mEnabled = false; + mGravity = 0.0f; + mHeight = 0; + mInvulnerable = false; + mKind = 0; + mMaxVelY = 0.0f; + mMenace = 0; + mPopping = false; + mPosX = 0.0f; + mPosY = 0.0f; + mPower = 0; mScore = 0; + mSize = 0; + mSpeed = 0; + mStopped = false; mStoppedCounter = 0; mTimeToLive = 0; - mKind = 0; - mMenace = 0; + mTravelY = 0; + mVelX = 0.0f; + mVelY = 0.0f; + mVisible = false; + mWidth = 0; + mSprite->clear(); } // Explosiona el globo @@ -585,6 +615,7 @@ void Balloon::update() { if (mEnabled) { + mSprite->MovingSprite::update(); move(); updateAnimation(); updateColliders(); @@ -661,6 +692,14 @@ void Balloon::updateState() setStop(false); setVisible(true); setInvulnerable(false); + if (mKind == POWER_BALL) + { + mSprite->setRotate(true); + if (mVelX > 0.0f) + mSprite->setRotateAmount(2.0); + else + mSprite->setRotateAmount(-2.0); + } } } // Solo comprueba el estado detenido cuando no se está creando @@ -741,6 +780,12 @@ int Balloon::getKind() return mKind; } +// Obtiene del valor de la variable +Uint8 Balloon::getSize() +{ + return mSize; +} + // Obtiene la clase a la que pertenece el globo Uint8 Balloon::getClass() { @@ -877,6 +922,12 @@ Uint8 Balloon::getMenace() return 0; } +// Obtiene le valor de la variable +Uint8 Balloon::getPower() +{ + return mPower; +} + void Balloon::bounceStart() { mBouncing.enabled = true; diff --git a/source/balloon.h b/source/balloon.h index de6db8a..39db6a3 100644 --- a/source/balloon.h +++ b/source/balloon.h @@ -39,6 +39,8 @@ private: Uint32 mCounter; // Contador interno float mTravelY; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad float mSpeed; // Velocidad a la que se mueven los globos + Uint8 mSize; // Tamaño del globo + Uint8 mPower; // Cantidad de poder que alberga el globo struct bouncing // Estructura para las variables para el efecto de los rebotes { @@ -121,6 +123,9 @@ public: // Obtiene del valor de la variable int getKind(); + // Obtiene del valor de la variable + Uint8 getSize(); + // Obtiene la clase a la que pertenece el globo Uint8 getClass(); @@ -171,6 +176,9 @@ public: // Obtiene le valor de la variable Uint8 getMenace(); + + // Obtiene le valor de la variable + Uint8 getPower(); }; #endif diff --git a/source/const.h b/source/const.h index 52e275d..721c43b 100644 --- a/source/const.h +++ b/source/const.h @@ -7,7 +7,7 @@ // Textos #define WINDOW_CAPTION "Coffee Crisis" -#define TEXT_COPYRIGHT "@2020,2021 JAILDESIGNER (V1.4)" +#define TEXT_COPYRIGHT "@2020,2021 JAILDESIGNER (V1.5)" // Recursos #define BINFILE_SCORE 0 @@ -39,8 +39,9 @@ #define SOUND_STAGE_CHANGE 14 #define SOUND_TITLE 15 #define SOUND_CLOCK 16 +#define SOUND_POWERBALL 17 -#define TOTAL_SOUND 17 +#define TOTAL_SOUND 18 #define TEXTURE_BALLOON 0 #define TEXTURE_BULLET 1 @@ -151,6 +152,10 @@ const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3; #define TITLE_SECTION_3 2 #define TITLE_SECTION_INSTRUCTIONS 3 +// Modos +#define MODE_AUTO 0 +#define MODE_MANUAL 1 + // Estados de cada elemento que pertenece a un evento #define EVENT_WAITING 1 #define EVENT_RUNNING 2 @@ -211,6 +216,18 @@ const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2; #define HEXAGON_4 8 #define POWER_BALL 9 +// Puntos de globo +#define BALLOON_SCORE_1 50 +#define BALLOON_SCORE_2 100 +#define BALLOON_SCORE_3 200 +#define BALLOON_SCORE_4 400 + +// Tamaños de globo +#define BALLOON_SIZE_1 1 +#define BALLOON_SIZE_2 2 +#define BALLOON_SIZE_3 3 +#define BALLOON_SIZE_4 4 + // Clases de globo #define BALLOON_CLASS 0 #define HEXAGON_CLASS 1 @@ -235,10 +252,10 @@ const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2; #define BALLOON_SPEED_5 1.00f // Tamaño de los globos -#define BALLOON_SIZE_1 8 -#define BALLOON_SIZE_2 13 -#define BALLOON_SIZE_3 21 -#define BALLOON_SIZE_4 37 +#define BALLOON_WIDTH_1 8 +#define BALLOON_WIDTH_2 13 +#define BALLOON_WIDTH_3 21 +#define BALLOON_WIDTH_4 37 // Tipos de bala #define BULLET_UP 1 diff --git a/source/gamedirector.cpp b/source/gamedirector.cpp index cb3871f..8155d53 100644 --- a/source/gamedirector.cpp +++ b/source/gamedirector.cpp @@ -180,7 +180,8 @@ void GameDirector::initProg() // Inicializa el objeto con el menu del titulo mMenu.title->init("TITLE", 0, 15 * BLOCK, MENU_BACKGROUND_SOLID, mTexture[TEXTURE_MENU].texture, mRenderer, mText.white); mMenu.title->addItem("PLAY"); - mMenu.title->addItem("OPTIONS", 0, 5); + mMenu.title->addItem("OPTIONS"); + mMenu.title->addItem("HOW TO PLAY", 0, 5); mMenu.title->addItem("QUIT"); mMenu.title->setDefaultActionWhenCancel(2); mMenu.title->setBackgroundColor(0x30, 0x30, 0x40, 192); @@ -668,6 +669,13 @@ void GameDirector::initTitle(Uint8 subsection) // Carga los recursos loadMediaTitle(); + // Inicializa las variables + resetTitle(subsection); +} + +// Resetea las variables necesarias para la sección 'Title' +void GameDirector::resetTitle(Uint8 subsection) +{ // Inicializa variables mTitle.section = subsection; mTitle.counter = TITLE_COUNTER; @@ -900,7 +908,7 @@ void GameDirector::resetGame() mGame.remainingExplosions = REMAINING_EXPLOSIONS; mGame.remainingExplosionsCounter = REMAINING_EXPLOSIONS_COUNTER; mGame.timeStopped = false; - mGame.timeStoppedCounter = TIME_STOPPED_COUNTER; + mGame.timeStoppedCounter = 0; mGame.counter = 0; mGame.balloonsPopped = 0; mGame.lastEnemyDeploy = 0; @@ -909,6 +917,7 @@ void GameDirector::resetGame() mGame.effect.flash = false; mGame.effect.shake = false; mGame.effect.shakeCounter = SHAKE_COUNTER; + mGame.powerBallEabled = false; initGameStages(); // Sprites @@ -1046,6 +1055,7 @@ bool GameDirector::loadMediaGame() mSound[SOUND_BUBBLE3].sound = JA_LoadSound(mSound[SOUND_BUBBLE3].file.c_str()); mSound[SOUND_BUBBLE4].sound = JA_LoadSound(mSound[SOUND_BUBBLE4].file.c_str()); mSound[SOUND_CLOCK].sound = JA_LoadSound(mSound[SOUND_CLOCK].file.c_str()); + mSound[SOUND_POWERBALL].sound = JA_LoadSound(mSound[SOUND_POWERBALL].file.c_str()); // Musicas mMusic[MUSIC_PLAYING].music = JA_LoadMusic(mMusic[MUSIC_PLAYING].file.c_str()); @@ -1081,6 +1091,7 @@ void GameDirector::quitGame() JA_DeleteSound(mSound[SOUND_BUBBLE3].sound); JA_DeleteSound(mSound[SOUND_BUBBLE4].sound); JA_DeleteSound(mSound[SOUND_CLOCK].sound); + JA_DeleteSound(mSound[SOUND_POWERBALL].sound); // Musicas JA_DeleteMusic(mMusic[MUSIC_PLAYING].music); @@ -1189,6 +1200,7 @@ void GameDirector::setFileList() mSound[SOUND_STAGE_CHANGE].file = mProg.executablePath + "/" + "../media/sound/stage_change.wav"; mSound[SOUND_TITLE].file = mProg.executablePath + "/" + "../media/sound/title.wav"; mSound[SOUND_CLOCK].file = mProg.executablePath + "/" + "../media/sound/clock.wav"; + mSound[SOUND_POWERBALL].file = mProg.executablePath + "/" + "../media/sound/powerball.wav"; // Texturas mTexture[TEXTURE_BALLOON].file = mProg.executablePath + "/" + "../media/gfx/balloon.png"; @@ -1577,23 +1589,23 @@ void GameDirector::initEnemyFormations() { const int y4 = (PLAY_AREA_TOP - BLOCK); const int x4_0 = PLAY_AREA_LEFT; - //const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_4 / 2); - const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_4; + //const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_4 / 2); + const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_4; const int y3 = (PLAY_AREA_TOP - BLOCK); const int x3_0 = PLAY_AREA_LEFT; - //const int x3_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_3 / 2); - const int x3_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_3; + //const int x3_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_3 / 2); + const int x3_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_3; const int y2 = (PLAY_AREA_TOP - BLOCK); const int x2_0 = PLAY_AREA_LEFT; - //const int x2_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_2 / 2); - const int x2_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_2; + //const int x2_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_2 / 2); + const int x2_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_2; const int y1 = (PLAY_AREA_TOP - BLOCK); const int x1_0 = PLAY_AREA_LEFT; - const int x1_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_1 / 2); - const int x1_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_1; + const int x1_50 = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_1 / 2); + const int x1_100 = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_1; const Uint16 creationTime = 300; int incX = 0; @@ -1621,7 +1633,7 @@ void GameDirector::initEnemyFormations() incTime = 0; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { - mEnemyFormation[j].init[i].x = PLAY_AREA_CENTER_FIRST_QUARTER_X - (BALLOON_SIZE_4 / 2) + (i * incX); + mEnemyFormation[j].init[i].x = PLAY_AREA_CENTER_FIRST_QUARTER_X - (BALLOON_WIDTH_4 / 2) + (i * incX); mEnemyFormation[j].init[i].y = y4; mEnemyFormation[j].init[i].velX = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1); mEnemyFormation[j].init[i].kind = BALLOON_4; @@ -1631,7 +1643,7 @@ void GameDirector::initEnemyFormations() // #02 - Cuatro enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro j = 2; mEnemyFormation[j].numberOfEnemies = 4; - incX = BALLOON_SIZE_2 + 1; + incX = BALLOON_WIDTH_2 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1645,7 +1657,7 @@ void GameDirector::initEnemyFormations() // #03 - Cuatro enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro j = 3; mEnemyFormation[j].numberOfEnemies = 4; - incX = BALLOON_SIZE_2 + 1; + incX = BALLOON_WIDTH_2 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1659,7 +1671,7 @@ void GameDirector::initEnemyFormations() // #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha j = 4; mEnemyFormation[j].numberOfEnemies = 3; - incX = BALLOON_SIZE_3 * 2; + incX = BALLOON_WIDTH_3 * 2; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1673,7 +1685,7 @@ void GameDirector::initEnemyFormations() // #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda j = 5; mEnemyFormation[j].numberOfEnemies = 3; - incX = BALLOON_SIZE_3 * 2; + incX = BALLOON_WIDTH_3 * 2; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1687,7 +1699,7 @@ void GameDirector::initEnemyFormations() // #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha j = 6; mEnemyFormation[j].numberOfEnemies = 3; - incX = BALLOON_SIZE_3 + 1; + incX = BALLOON_WIDTH_3 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1701,7 +1713,7 @@ void GameDirector::initEnemyFormations() // #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda j = 7; mEnemyFormation[j].numberOfEnemies = 3; - incX = BALLOON_SIZE_3 + 1; + incX = BALLOON_WIDTH_3 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1715,7 +1727,7 @@ void GameDirector::initEnemyFormations() // #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha j = 8; mEnemyFormation[j].numberOfEnemies = 6; - incX = BALLOON_SIZE_1 + 1; + incX = BALLOON_WIDTH_1 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1729,7 +1741,7 @@ void GameDirector::initEnemyFormations() // #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda j = 9; mEnemyFormation[j].numberOfEnemies = 6; - incX = BALLOON_SIZE_1 + 1; + incX = BALLOON_WIDTH_1 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1743,7 +1755,7 @@ void GameDirector::initEnemyFormations() // #10 - Tres enemigos BALLOON4 seguidos desde la izquierda j = 10; mEnemyFormation[j].numberOfEnemies = 3; - incX = BALLOON_SIZE_4 + 1; + incX = BALLOON_WIDTH_4 + 1; incTime = 15; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1757,7 +1769,7 @@ void GameDirector::initEnemyFormations() // #11 - Tres enemigos BALLOON4 seguidos desde la derecha j = 11; mEnemyFormation[j].numberOfEnemies = 3; - incX = BALLOON_SIZE_4 + 1; + incX = BALLOON_WIDTH_4 + 1; incTime = 15; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1771,7 +1783,7 @@ void GameDirector::initEnemyFormations() // #12 - Seis enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro j = 12; mEnemyFormation[j].numberOfEnemies = 6; - incX = BALLOON_SIZE_2 + 1; + incX = BALLOON_WIDTH_2 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1785,7 +1797,7 @@ void GameDirector::initEnemyFormations() // #13 - Seis enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro j = 13; mEnemyFormation[j].numberOfEnemies = 6; - incX = BALLOON_SIZE_2 + 1; + incX = BALLOON_WIDTH_2 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1799,7 +1811,7 @@ void GameDirector::initEnemyFormations() // #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados j = 14; mEnemyFormation[j].numberOfEnemies = 5; - incX = BALLOON_SIZE_3 * 2; + incX = BALLOON_WIDTH_3 * 2; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1813,7 +1825,7 @@ void GameDirector::initEnemyFormations() // #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados j = 15; mEnemyFormation[j].numberOfEnemies = 5; - incX = BALLOON_SIZE_3 * 2; + incX = BALLOON_WIDTH_3 * 2; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1827,7 +1839,7 @@ void GameDirector::initEnemyFormations() // #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos j = 16; mEnemyFormation[j].numberOfEnemies = 5; - incX = BALLOON_SIZE_3 + 1; + incX = BALLOON_WIDTH_3 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1841,7 +1853,7 @@ void GameDirector::initEnemyFormations() // #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos j = 17; mEnemyFormation[j].numberOfEnemies = 5; - incX = BALLOON_SIZE_3 + 1; + incX = BALLOON_WIDTH_3 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1855,7 +1867,7 @@ void GameDirector::initEnemyFormations() // #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos j = 18; mEnemyFormation[j].numberOfEnemies = 12; - incX = BALLOON_SIZE_1 + 1; + incX = BALLOON_WIDTH_1 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1869,7 +1881,7 @@ void GameDirector::initEnemyFormations() // #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos j = 19; mEnemyFormation[j].numberOfEnemies = 12; - incX = BALLOON_SIZE_1 + 1; + incX = BALLOON_WIDTH_1 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1883,7 +1895,7 @@ void GameDirector::initEnemyFormations() // #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos j = 20; mEnemyFormation[j].numberOfEnemies = 4; - incX = BALLOON_SIZE_4 + 1; + incX = BALLOON_WIDTH_4 + 1; incTime = 0; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1906,7 +1918,7 @@ void GameDirector::initEnemyFormations() // #21 - Diez enemigos BALLOON2 uno detras del otro. Izquierda/derecha. Simetricos j = 21; mEnemyFormation[j].numberOfEnemies = 10; - incX = BALLOON_SIZE_2 + 1; + incX = BALLOON_WIDTH_2 + 1; incTime = 3; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1930,7 +1942,7 @@ void GameDirector::initEnemyFormations() // #22 - Diez enemigos BALLOON3. Hacia la derecha/izquierda. Separados. Simetricos j = 22; mEnemyFormation[j].numberOfEnemies = 10; - incX = BALLOON_SIZE_3 * 2; + incX = BALLOON_WIDTH_3 * 2; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -1954,7 +1966,7 @@ void GameDirector::initEnemyFormations() // #23 - Diez enemigos BALLOON3. Hacia la derecha. Juntos. Simetricos j = 23; mEnemyFormation[j].numberOfEnemies = 10; - incX = BALLOON_SIZE_3 + 1; + incX = BALLOON_WIDTH_3 + 1; incTime = 10; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -2002,7 +2014,7 @@ void GameDirector::initEnemyFormations() // #25 - Treinta enemigos BALLOON1. Del centro hacia adentro. Juntos. Simetricos j = 25; mEnemyFormation[j].numberOfEnemies = 30; - incX = BALLOON_SIZE_1 + 1; + incX = BALLOON_WIDTH_1 + 1; incTime = 5; for (Uint8 i = 0; i < mEnemyFormation[j].numberOfEnemies; i++) { @@ -2279,36 +2291,51 @@ void GameDirector::deployEnemyFormation() // Solo despliega una formación enemiga si ha pasado cierto tiempo desde la última if (mGame.enemyDeployCounter == 0) { - mGame.enemyDeployCounter = 255; - Uint8 set = (rand() % 10); - - if (set == mGame.lastEnemyDeploy) + // En este punto se decide entre crear una powerball o una formación enemiga + if ((rand() % 100 < 15) && (canPowerBallBeCreated())) { - set++; - set %= 10; + // Crea una powerball + createPowerBall(); + + mGame.enemyDeployCounter = 50; } - mGame.lastEnemyDeploy = set; + else + { - if (mDebug.enabled) - set = mDebug.enemySet; + // Elige una formación enemiga la azar + Uint8 set = (rand() % 10); - Uint8 numEnemies = mGame.stage[mGame.currentStage].enemyPool->set[set]->numberOfEnemies; - for (Uint8 i = 0; i < numEnemies; i++) - createNewBalloon(mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].x, - mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].y, - mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].kind, - mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].velX, - mGame.enemySpeed, - mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].creationCounter, - mTexture[TEXTURE_BALLOON].texture); + // Evita repetir la ultima formación enemiga desplegada + if (set == mGame.lastEnemyDeploy) + { + set++; + set %= 10; + } + mGame.lastEnemyDeploy = set; + + if (mDebug.enabled) + set = mDebug.enemySet; + + Uint8 numEnemies = mGame.stage[mGame.currentStage].enemyPool->set[set]->numberOfEnemies; + for (Uint8 i = 0; i < numEnemies; i++) + createNewBalloon(mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].x, + mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].y, + mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].kind, + mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].velX, + mGame.enemySpeed, + mGame.stage[mGame.currentStage].enemyPool->set[set]->init[i].creationCounter, + mTexture[TEXTURE_BALLOON].texture); + + mGame.enemyDeployCounter = 255; + } } } // Aumenta el poder de la fase -void GameDirector::increaseStageCurrentPower() +void GameDirector::increaseStageCurrentPower(Uint8 power) { - mGame.stage[mGame.currentStage].currentPower++; + mGame.stage[mGame.currentStage].currentPower += power; } // Establece el valor de la variable @@ -2602,14 +2629,15 @@ Uint8 GameDirector::createNewBalloon(float x, int y, Uint8 kind, float velx, flo // Crea una PowerBall void GameDirector::createPowerBall() { - const int y4 = (PLAY_AREA_TOP - BLOCK); - const int x4_0 = PLAY_AREA_LEFT; - const int x4_50 = PLAY_AREA_CENTER_X - (BALLOON_SIZE_4 / 2); - const int x4_100 = (PLAY_AREA_RIGHT)-BALLOON_SIZE_4; - const int x[3] = {x4_0, x4_50, x4_100}; - int x4 = x[rand() % 3]; + const int posY = (PLAY_AREA_TOP); + const int left = PLAY_AREA_LEFT; + const int center = PLAY_AREA_CENTER_X - (BALLOON_WIDTH_4 / 2); + const int right = (PLAY_AREA_RIGHT)-BALLOON_WIDTH_4; + const int x[3] = {left, center, right}; + int posX = x[rand() % 3]; - mGame.balloon[getBalloonFreeIndex()]->init(x4, y4, POWER_BALL, BALLOON_VELX_POSITIVE * (((rand() % 2) * 2) - 1), mGame.enemySpeed, 350, mTexture[TEXTURE_BALLOON].texture, mRenderer); + mGame.balloon[getBalloonFreeIndex()]->init(posX, posY, POWER_BALL, BALLOON_VELX_POSITIVE * (((rand() % 2) * 2) - 1), mGame.enemySpeed, 100, mTexture[TEXTURE_BALLOON].texture, mRenderer); + mGame.powerBallEabled = true; } // Establece a cero todos los valores del vector de objetos globo @@ -2688,88 +2716,115 @@ void GameDirector::updateBalloonSpeed() // Explosiona un globo. Lo destruye y crea otros dos si es el caso void GameDirector::popBalloon(Uint8 index) { - //if (mGame.balloon[index]->isActive()) + // Otorga los puntos correspondientes al globo + mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier())); + setScore(mGame.player->getScore()); + updateHiScore(); + + // Aumenta el poder de la fase + increaseStageCurrentPower(1); + mGame.balloonsPopped++; + + Uint8 kind = mGame.balloon[index]->getKind(); + Uint8 freeIndex = 0; + switch (kind) { - // Otorga los puntos correspondientes al globo - mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier())); - setScore(mGame.player->getScore()); - updateHiScore(); + // Si es del tipo más pequeño, simplemente elimina el globo + case BALLOON_1: + mGame.balloon[index]->pop(); + break; - // Aumenta el poder de la fase - increaseStageCurrentPower(); - mGame.balloonsPopped++; + case HEXAGON_1: + mGame.balloon[index]->pop(); + break; - Uint8 kind = mGame.balloon[index]->getKind(); - Uint8 freeIndex = 0; - switch (kind) - { - // Si es del tipo más pequeño, simplemente elimina el globo - case BALLOON_1: - mGame.balloon[index]->pop(); - break; + // Si es del tipo PowerBall, destruye todos los globos + case POWER_BALL: + destroyAllBalloons(); + mGame.powerBallEabled = false; + break; - case HEXAGON_1: - mGame.balloon[index]->pop(); - break; + // En cualquier otro caso, crea dos globos de un tipo inferior + default: + freeIndex = getBalloonFreeIndex(); + mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_NEGATIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer); + mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2)); + if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS) + mGame.balloon[freeIndex]->setVelY(-2.50f); + else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS) + mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE); - // Si es del tipo PowerBall, destruye todos los globos - case POWER_BALL: - destroyAllBalloons(); - break; + freeIndex = getBalloonFreeIndex(); + mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_POSITIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer); + mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2)); + if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS) + mGame.balloon[freeIndex]->setVelY(-2.50f); + else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS) + mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE); - // En cualquier otro caso, crea dos globos de un tipo inferior - default: - freeIndex = getBalloonFreeIndex(); - mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_NEGATIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer); - mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2)); - if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS) - mGame.balloon[freeIndex]->setVelY(-2.50f); - else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS) - mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE); - - freeIndex = getBalloonFreeIndex(); - mGame.balloon[freeIndex]->init(0, mGame.balloon[index]->getPosY(), mGame.balloon[index]->getKind() - 1, BALLOON_VELX_POSITIVE, mGame.enemySpeed, 0, mTexture[TEXTURE_BALLOON].texture, mRenderer); - mGame.balloon[freeIndex]->allignTo(mGame.balloon[index]->getPosX() + (mGame.balloon[index]->getWidth() / 2)); - if (mGame.balloon[freeIndex]->getClass() == BALLOON_CLASS) - mGame.balloon[freeIndex]->setVelY(-2.50f); - else if (mGame.balloon[freeIndex]->getClass() == HEXAGON_CLASS) - mGame.balloon[freeIndex]->setVelY(BALLOON_VELX_NEGATIVE); - - // Elimina el globo - mGame.balloon[index]->pop(); - break; - } - - // Recalcula el nivel de amenaza - setMenace(); + // Elimina el globo + mGame.balloon[index]->pop(); + break; } + + // Recalcula el nivel de amenaza + setMenace(); } // Explosiona un globo. Lo destruye void GameDirector::destroyBalloon(Uint8 index) { - //if (mGame.balloon[index]->isActive()) + int score = 0; + Uint8 power = 0; + // Calcula la puntuación y el poder que generaria el globo en caso de romperlo a él y a sus hijos + switch (mGame.balloon[index]->getSize()) { - // Otorga los puntos correspondientes al globo - mGame.player->addScore(Uint32(mGame.balloon[index]->getScore() * mGame.player->getScoreMultiplier())); - setScore(mGame.player->getScore()); - updateHiScore(); + case BALLOON_SIZE_4: + score = BALLOON_SCORE_4 + (2 * BALLOON_SCORE_3) + (4 * BALLOON_SCORE_2) + (8 * BALLOON_SCORE_1); + power = 15; + break; - // Aumenta el poder de la fase - increaseStageCurrentPower(); - mGame.balloonsPopped++; + case BALLOON_SIZE_3: + score = BALLOON_SCORE_3 + (2 * BALLOON_SCORE_2) + (4 * BALLOON_SCORE_1); + power = 7; + break; - // Destruye el globo - mGame.balloon[index]->pop(); + case BALLOON_SIZE_2: + score = BALLOON_SCORE_2 + (2 * BALLOON_SCORE_1); + power = 3; + break; - // Recalcula el nivel de amenaza - setMenace(); + case BALLOON_SIZE_1: + score = BALLOON_SCORE_1; + power = 1; + break; + + default: + score = 0; + power = 0; + break; } + + // Otorga los puntos correspondientes al globo + mGame.player->addScore(Uint32(score * mGame.player->getScoreMultiplier())); + setScore(mGame.player->getScore()); + updateHiScore(); + + // Aumenta el poder de la fase + increaseStageCurrentPower(power); + mGame.balloonsPopped += power; + + // Destruye el globo + mGame.balloon[index]->pop(); + + // Recalcula el nivel de amenaza + setMenace(); } // Explosiona todos los globos void GameDirector::popAllBalloons() { + /* int candidate[MAX_BALLOONS]; Uint8 j = 0; for (Uint8 i = 0; i < MAX_BALLOONS; i++) @@ -2783,26 +2838,22 @@ void GameDirector::popAllBalloons() for (Uint8 i = 0; i < MAX_BALLOONS; i++) if (candidate[i] >= 0) popBalloon(i); + */ + for (Uint8 i = 0; i < MAX_BALLOONS; i++) + if ((mGame.balloon[i]->isEnabled()) && (!mGame.balloon[i]->isPopping()) && (!mGame.balloon[i]->isBeingCreated())) + popBalloon(i); + JA_PlaySound(mSound[SOUND_BALLOON].sound); } // Destruye todos los globos void GameDirector::destroyAllBalloons() { - int candidate[MAX_BALLOONS]; - Uint8 j = 0; for (Uint8 i = 0; i < MAX_BALLOONS; i++) - { if ((mGame.balloon[i]->isEnabled()) && (!mGame.balloon[i]->isPopping()) && (!mGame.balloon[i]->isBeingCreated())) - candidate[j] = i; - else - candidate[j] = -1; - j++; - } - for (Uint8 i = 0; i < MAX_BALLOONS; i++) - if (candidate[i] >= 0) destroyBalloon(i); - JA_PlaySound(mSound[SOUND_BALLOON].sound); + + JA_PlaySound(mSound[SOUND_POWERBALL].sound); mGame.effect.flash = true; mGame.effect.shake = true; } @@ -2930,11 +2981,11 @@ void GameDirector::checkBulletBalloonCollision() Uint8 droppeditem = dropItem(); if ((droppeditem != NO_KIND) && !(mDemo.enabled) && !(mDemo.recording)) { - if (droppeditem == ITEM_POWER_BALL) + /*if (droppeditem == ITEM_POWER_BALL) { createPowerBall(); } - else + else*/ { createItem(mGame.balloon[i]->getPosX(), mGame.balloon[i]->getPosY(), droppeditem); JA_PlaySound(mSound[SOUND_ITEM_DROP].sound); @@ -3050,10 +3101,10 @@ void GameDirector::resetItems() // Devuelve un item en función del azar Uint8 GameDirector::dropItem() { - return ITEM_COFFEE; + //return ITEM_COFFEE; Uint8 luckyNumber = rand() % 99; - Uint8 item = rand() % 7; + Uint8 item = rand() % 6; switch (item) { case 0: @@ -3080,11 +3131,12 @@ Uint8 GameDirector::dropItem() if (luckyNumber < 5) return ITEM_COFFEE; break; - case 6: + /*case 6: if (luckyNumber < 5) if (countBalloons() > 10) - return ITEM_POWER_BALL; - break; + if (!mGame.powerBallEabled) + return ITEM_POWER_BALL; + break;*/ default: break; } @@ -3159,8 +3211,8 @@ void GameDirector::throwCoffee(int x, int y) mGame.smartSprite[index]->setEnabledTimer(1); mGame.smartSprite[index]->setSpriteClip(80, 16, 16, 16); mGame.smartSprite[index]->setRotate(true); - mGame.smartSprite[index]->setRotateSpeed(1); - mGame.smartSprite[index]->setRotateAmount(5.0); + mGame.smartSprite[index]->setRotateSpeed(10); + mGame.smartSprite[index]->setRotateAmount(90.0); } // Crea un SmartSprite para arrojar el item café al recibir un impacto @@ -3346,6 +3398,12 @@ void GameDirector::setTimeStoppedCounter(Uint16 value) mGame.timeStoppedCounter = value; } +// Incrementa el valor de la variable +void GameDirector::incTimeStoppedCounter(Uint16 value) +{ + mGame.timeStoppedCounter += value; +} + // Actualiza y comprueba el valor de la variable void GameDirector::updateTimeStoppedCounter() { @@ -4056,7 +4114,7 @@ void GameDirector::enableTimeStopItem() { stopAllBalloons(TIME_STOPPED_COUNTER); setTimeStopped(true); - setTimeStoppedCounter(TIME_STOPPED_COUNTER); + incTimeStoppedCounter(TIME_STOPPED_COUNTER); if (JA_GetMusicState() == JA_MUSIC_PLAYING) { JA_PauseMusic(); @@ -4067,7 +4125,8 @@ void GameDirector::enableTimeStopItem() void GameDirector::disableTimeStopItem() { mGame.timeStopped = false; - mGame.timeStoppedCounter = TIME_STOPPED_COUNTER; + setTimeStoppedCounter(0); + //mGame.timeStoppedCounter = TIME_STOPPED_COUNTER; startAllBalloons(); if (JA_GetMusicState() == JA_MUSIC_PAUSED) { @@ -4634,9 +4693,7 @@ void GameDirector::runTitle(Uint8 subsection) mTitle.coffeeBitmap->render(); mTitle.crisisBitmap->render(); if (mTitle.menuVisible == true) - { mMenu.active->render(); - } mTitle.dustBitmapR->animate(0); mTitle.dustBitmapL->animate(0); mTitle.dustBitmapR->render(); @@ -4673,27 +4730,36 @@ void GameDirector::runTitle(Uint8 subsection) { switch (mMenu.active->getItemSelected()) { - case 0: - setProgSection(PROG_SECTION_GAME); + case 0: // PLAY + JA_PlaySound(mSound[SOUND_MENU_SELECT].sound); mMenu.active->reset(); mMenu.keyPressed = false; - JA_PlaySound(mSound[SOUND_MENU_SELECT].sound); + setProgSection(PROG_SECTION_GAME); renderFade(1); JA_StopMusic(); disableDemoMode(); break; - case 1: + case 1: // OPTIONS JA_PlaySound(mSound[SOUND_MENU_SELECT].sound); mMenu.active->reset(); + mMenu.keyPressed = false; mMenu.active = mMenu.options; mOptions.fullScreenModePrevious = mOptions.fullScreenMode; mOptions.windowSizePrevious = mOptions.windowSize; break; - case 2: - mProg.quit = true; + case 2: // HOW TO PLAY + JA_PlaySound(mSound[SOUND_MENU_SELECT].sound); mMenu.active->reset(); mMenu.keyPressed = false; + mTitle.section = TITLE_SECTION_INSTRUCTIONS; + //runInstructions(MODE_MANUAL); + //setProgSection(PROG_SECTION_TITLE,TITLE_SECTION_INSTRUCTIONS); + break; + case 3: // QUIT JA_PlaySound(mSound[SOUND_MENU_CANCEL].sound); + mMenu.active->reset(); + mMenu.keyPressed = false; + mProg.quit = true; renderFade(1); JA_StopMusic(); break; @@ -4761,7 +4827,7 @@ void GameDirector::runTitle(Uint8 subsection) // Sección Instrucciones if (mTitle.section == TITLE_SECTION_INSTRUCTIONS) - runInstructions(); + runInstructions(MODE_AUTO); } quitTitle(); @@ -4879,7 +4945,9 @@ void GameDirector::runGame() // Volca el contenido de la textura en el renderizador SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL); + // Pinta la informacion de debug renderDebugInfo(); + // Actualiza la pantalla SDL_RenderPresent(mRenderer); } @@ -4965,22 +5033,22 @@ void GameDirector::runPausedGame() } // Bucle para la pantalla de instrucciones -void GameDirector::runInstructions() +void GameDirector::runInstructions(Uint8 mode) { SDL_Rect window = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}; Sprite *sprite = new Sprite(); - SDL_Rect rect1 = {60, 88, 16, 16}; // Disquito - SDL_Rect rect2 = {60, 104, 16, 16}; // Gavineixon - SDL_Rect rect3 = {60, 120, 16, 16}; // Pacmar - SDL_Rect rect4 = {60, 136, 16, 16}; // Time Stopper - SDL_Rect rect5 = {60, 152, 16, 16}; // Explosive - SDL_Rect rect6 = {60, 168, 16, 16}; // Coffee - SDL_Rect rect = {0, 0, 16, 16}; - sprite->init(rect1, mTexture[TEXTURE_ITEMS].texture, mRenderer); + SDL_Rect srcRect = {0, 0, 16, 16}; + + const SDL_Rect destRect1 = {60, 88 + (16 * 0), 16, 16}; // Disquito + const SDL_Rect destRect2 = {60, 88 + (16 * 1), 16, 16}; // Gavineixon + const SDL_Rect destRect3 = {60, 88 + (16 * 2), 16, 16}; // Pacmar + const SDL_Rect destRect4 = {60, 88 + (16 * 3), 16, 16}; // Time Stopper + const SDL_Rect destRect5 = {60, 88 + (16 * 4), 16, 16}; // Coffee + + sprite->init(destRect1, mTexture[TEXTURE_ITEMS].texture, mRenderer); while ((mTitle.section == TITLE_SECTION_INSTRUCTIONS) && (!exit())) { - int y = 0; // Comprueba los eventos que hay en la cola while (SDL_PollEvent(mEventHandler) != 0) { @@ -5012,40 +5080,44 @@ void GameDirector::runInstructions() mText.white->write(84, 108, "2.500 POINTS", 0); mText.white->write(84, 124, "5.000 POINTS", 0); mText.white->write(84, 140, "TIME STOPPER", 0); - mText.white->write(84, 156, "FOUR EXPLOSIONS", 0); - mText.white->write(84, 172, "EXTRA HIT", 0); + mText.white->write(84, 156, "EXTRA HIT", 0); - sprite->init(rect1, mTexture[TEXTURE_ITEMS].texture, mRenderer); - sprite->setSpriteClip(rect); - rect.x += rect.w; - rect.y = 16 * (((mTitle.instructionsCounter + 3) / 36) % 2); - sprite->render(); - sprite->init(rect2, mTexture[TEXTURE_ITEMS].texture, mRenderer); - sprite->setSpriteClip(rect); - rect.x += rect.w; - rect.y = 16 * (((mTitle.instructionsCounter + 6) / 36) % 2); - sprite->render(); - sprite->init(rect3, mTexture[TEXTURE_ITEMS].texture, mRenderer); - sprite->setSpriteClip(rect); - rect.x += rect.w; - rect.y = 16 * (((mTitle.instructionsCounter + 9) / 36) % 2); - sprite->render(); - sprite->init(rect4, mTexture[TEXTURE_ITEMS].texture, mRenderer); - sprite->setSpriteClip(rect); - rect.x += rect.w; - rect.y = 16 * (((mTitle.instructionsCounter + 12) / 36) % 2); - sprite->render(); - sprite->init(rect5, mTexture[TEXTURE_ITEMS].texture, mRenderer); - sprite->setSpriteClip(rect); - rect.x += rect.w; - rect.y = 16 * (((mTitle.instructionsCounter + 15) / 36) % 2); - sprite->render(); - sprite->init(rect6, mTexture[TEXTURE_ITEMS].texture, mRenderer); - sprite->setSpriteClip(rect); - rect.x = 0; - rect.y = 16 * (((mTitle.instructionsCounter + 0) / 36) % 2); + // Disquito + sprite->init(destRect1, mTexture[TEXTURE_ITEMS].texture, mRenderer); + srcRect.x = 0; + srcRect.y = 16 * (((mTitle.instructionsCounter + 0) / 36) % 2); + sprite->setSpriteClip(srcRect); sprite->render(); + // Gavineixon + sprite->init(destRect2, mTexture[TEXTURE_ITEMS].texture, mRenderer); + srcRect.x += srcRect.w; + srcRect.y = 16 * (((mTitle.instructionsCounter + 3) / 36) % 2); + sprite->setSpriteClip(srcRect); + sprite->render(); + + // Pacmar + sprite->init(destRect3, mTexture[TEXTURE_ITEMS].texture, mRenderer); + srcRect.x += srcRect.w; + srcRect.y = 16 * (((mTitle.instructionsCounter + 6) / 36) % 2); + sprite->setSpriteClip(srcRect); + sprite->render(); + + // Time Stopper + sprite->init(destRect4, mTexture[TEXTURE_ITEMS].texture, mRenderer); + srcRect.x += srcRect.w; + srcRect.y = 16 * (((mTitle.instructionsCounter + 9) / 36) % 2); + sprite->setSpriteClip(srcRect); + sprite->render(); + + // Coffee + sprite->init(destRect5, mTexture[TEXTURE_ITEMS].texture, mRenderer); + srcRect.x += (srcRect.w * 2); // Se salta el icono del TNT + srcRect.y = 16 * (((mTitle.instructionsCounter + 12) / 36) % 2); + sprite->setSpriteClip(srcRect); + sprite->render(); + + // Cambia el destino de renderizado SDL_SetRenderTarget(mRenderer, nullptr); // Limpia la pantalla @@ -5053,13 +5125,7 @@ void GameDirector::runInstructions() SDL_RenderClear(mRenderer); // Dibuja los objetos - y = SCREEN_HEIGHT - (INSTRUCTIONS_COUNTER - mTitle.instructionsCounter) + 100; - if (y < 0) - { - y = 0; - } - - window.y = y; + window.y = std::max(0, SCREEN_HEIGHT - (INSTRUCTIONS_COUNTER - mTitle.instructionsCounter) + 100); SDL_RenderCopy(mRenderer, mInstructionsSurface, NULL, &window); // Muestra la pantalla @@ -5069,9 +5135,17 @@ void GameDirector::runInstructions() if (mTitle.instructionsCounter == 0) { - mTitle.instructionsCounter = INSTRUCTIONS_COUNTER; - mTitle.section = TITLE_SECTION_1; + resetTitle(TITLE_SECTION_1); + mTitle.section = TITLE_SECTION_3; mTitle.nextProgSection = PROG_SECTION_LOGO; + + // Prepara las variables para la sección 3 del titulo + mTitle.dustBitmapL->setEnabled(false); + mTitle.dustBitmapR->setEnabled(false); + mTitle.menuVisible = true; + mTitle.coffeeBitmap->setPosY(11); + mTitle.crisisBitmap->setPosY(57); + mMenu.title->setSelectorPos(2); } } delete sprite; @@ -5201,4 +5275,27 @@ void GameDirector::renderDebugInfo() mText.white->writeShadowed(2, 2 + 8 * BLOCK, "balloonsPop: " + std::to_string(mGame.balloonsPopped), R, G, B); mText.white->writeShadowed(2, 2 + 9 * BLOCK, "(Z-X)ballSped:" + std::to_string(mGame.enemySpeed), R, G, B); } +} + +// Indica si se puede crear una powerball +bool GameDirector::canPowerBallBeCreated() +{ + bool success = false; + + if ((!mGame.powerBallEabled) && (calculateScreenPower() > 0)) + success = true; + else + success = false; + + return success; +} + +// Calcula el poder actual de los globos en pantalla +int GameDirector::calculateScreenPower() +{ + int power = 0; + for (Uint8 i = 0; i < MAX_BALLOONS; i++) + if (mGame.balloon[i]->isEnabled()) + power += mGame.balloon[i]->getPower(); + return power; } \ No newline at end of file diff --git a/source/gamedirector.h b/source/gamedirector.h index 42dae46..9570802 100644 --- a/source/gamedirector.h +++ b/source/gamedirector.h @@ -153,6 +153,7 @@ private: Uint8 enemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero float enemySpeed; // Velocidad a la que se mueven los enemigos effect_t effect; // Variable para gestionar los efectos visuales + bool powerBallEabled; // Indica si hay una powerball ya activa }; game_t mGame; // Variable con todas las variables usadas durante el juego @@ -300,6 +301,9 @@ public: // Inicializa las variables necesarias para la sección 'Title' void initTitle(Uint8 subsection = TITLE_SECTION_1); + // Resetea las variables necesarias para la sección 'Title' + void resetTitle(Uint8 subsection = TITLE_SECTION_1); + // Carga los recursos necesarios para la sección 'Title' bool loadMediaTitle(); @@ -364,7 +368,7 @@ public: void deployEnemyFormation(); // Aumenta el poder de la fase - void increaseStageCurrentPower(); + void increaseStageCurrentPower(Uint8 power); // Establece el valor de la variable void setScore(Uint32 score); @@ -553,6 +557,9 @@ public: // Establece el valor de la variable void setTimeStoppedCounter(Uint16 value); + // Incrementa el valor de la variable + void incTimeStoppedCounter(Uint16 value); + // Actualiza la variable EnemyDeployCounter void updateEnemyDeployCounter(); @@ -644,7 +651,7 @@ public: void runPausedGame(); // Bucle para la pantalla de instrucciones - void runInstructions(); + void runInstructions(Uint8 mode); // Bucle para la pantalla de game over void runGameOverScreen(); @@ -660,6 +667,12 @@ public: // Dibuja la informacion de debug en pantalla void renderDebugInfo(); + + // Indica si se puede crear una powerball + bool canPowerBallBeCreated(); + + // Calcula el poder actual de los globos en pantalla + int calculateScreenPower(); }; #endif diff --git a/source/menu.h b/source/menu.h index 3201c54..25e6df4 100644 --- a/source/menu.h +++ b/source/menu.h @@ -63,6 +63,9 @@ public: // Establece el indice del item que se usará por defecto al cancelar el menu void setDefaultActionWhenCancel(Uint8 item); + // Coloca el selector en una posición específica + void setSelectorPos(Uint8 index); + private: // Establece el valor de la variable void setTotalItems(int num); @@ -91,9 +94,6 @@ private: // Establece el destino del selector void setSelectorTarget(int value); - // Coloca el selector en una posición específica - void setSelectorPos(Uint8 index); - // Obtiene la anchura del elemento más ancho del menu Uint16 getWidestItem(); diff --git a/source/movingsprite.cpp b/source/movingsprite.cpp index 45aa286..70e4509 100644 --- a/source/movingsprite.cpp +++ b/source/movingsprite.cpp @@ -5,13 +5,35 @@ // Constructor MovingSprite::MovingSprite() { - init(0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr); + clear(); } // Destructor MovingSprite::~MovingSprite() { - init(0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr); + clear(); +} + +// Reinicia todas las variables +void MovingSprite::clear() +{ + mPosX = 0.0f; // Posición en el eje X + mPosY = 0.0f; // Posición en el eje Y + + mVelX = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse + mVelY = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse + + mAccelX = 0.0f; // Aceleración en el eje X. Variación de la velocidad + mAccelY = 0.0f; // Aceleración en el eje Y. Variación de la velocidad + + mZoomW = 1.0f; // Zoom aplicado a la anchura + mZoomH = 1.0f; // Zoom aplicado a la altura + + mAngle = 0.0; // Angulo para dibujarlo + mRotate = false; // Indica si ha de rotar + mRotateSpeed = 0; // Velocidad de giro + mRotateAmount = 0.0; // Cantidad de grados a girar en cada iteración + mCounter = 0; // Contador interno } // Iniciador @@ -40,6 +62,14 @@ void MovingSprite::init(float x, float y, int w, int h, float velx, float vely, // Establece el angulo con el que se dibujará setAngle(0.0); + // Establece los valores de rotacion + setRotate(false); + setRotateSpeed(0); + setRotateAmount(0.0); + + // Contador interno + mCounter = 0; + // Establece la textura donde están los gráficos para el sprite setTexture(texture); @@ -53,18 +83,21 @@ void MovingSprite::init(float x, float y, int w, int h, float velx, float vely, // Mueve el sprite void MovingSprite::move() { - mPosX += mVelX; - mPosY += mVelY; + if (mEnabled) + { + mPosX += mVelX; + mPosY += mVelY; - mVelX += mAccelX; - mVelY += mAccelY; + mVelX += mAccelX; + mVelY += mAccelY; + } } // Muestra el sprite por pantalla void MovingSprite::render() { - //mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip); - mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle); + if (mEnabled) + mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle); } // Obtiene el valor de la variable @@ -185,4 +218,63 @@ void MovingSprite::incAngle(double inc) void MovingSprite::decAngle(double dec) { mAngle -= dec; +} + +// Obtiene el valor de la variable +bool MovingSprite::getRotate() +{ + return mRotate; +} + +// Obtiene el valor de la variable +Uint16 MovingSprite::getRotateSpeed() +{ + return mRotateSpeed; +} + +// Establece la rotacion +void MovingSprite::rotate() +{ + if (mEnabled) + if (mRotate) + { + if (mCounter % mRotateSpeed == 0) + { + incAngle(mRotateAmount); + } + } +} + +// Establece el valor de la variable +void MovingSprite::setRotate(bool value) +{ + mRotate = value; +} + +// Establece el valor de la variable +void MovingSprite::setRotateSpeed(Uint16 value) +{ + mRotateSpeed = value; +} + +// Establece el valor de la variable +void MovingSprite::setRotateAmount(double value) +{ + mRotateAmount = value; +} + +// Actualiza las variables internas del objeto +void MovingSprite::update() +{ + move(); + rotate(); + + if (mEnabled) + ++mCounter %= 60000; +} + +// Cambia el sentido de la rotación +void MovingSprite::switchRotate() +{ + mRotateAmount *= -1; } \ No newline at end of file diff --git a/source/movingsprite.h b/source/movingsprite.h index 36e0299..c0a9d28 100644 --- a/source/movingsprite.h +++ b/source/movingsprite.h @@ -8,7 +8,7 @@ // Clase MovingSprite. Añade posicion y velocidad en punto flotante class MovingSprite : public Sprite { -private: +protected: float mPosX; // Posición en el eje X float mPosY; // Posición en el eje Y @@ -21,7 +21,11 @@ private: float mZoomW; // Zoom aplicado a la anchura float mZoomH; // Zoom aplicado a la altura - double mAngle; // Angulo para dibujarlo + double mAngle; // Angulo para dibujarlo + bool mRotate; // Indica si ha de rotar + Uint16 mRotateSpeed; // Velocidad de giro + double mRotateAmount; // Cantidad de grados a girar en cada iteración + Uint16 mCounter; // Contador interno public: // Constructor @@ -36,6 +40,15 @@ public: // Mueve el sprite void move(); + // Rota el sprite + void rotate(); + + // Actualiza las variables internas del objeto + void update(); + + // Reinicia todas las variables + void clear(); + // Muestra el sprite por pantalla void render(); @@ -66,6 +79,12 @@ public: // Obten el valor de la variable double getAngle(); + // Obtiene el valor de la variable + bool getRotate(); + + // Obtiene el valor de la variable + Uint16 getRotateSpeed(); + // Establece el valor de la variable void setPosX(float x); @@ -98,6 +117,18 @@ public: // Decrementa el valor de la variable void decAngle(double dec); + + // Establece el valor de la variable + void setRotate(bool value); + + // Establece el valor de la variable + void setRotateSpeed(Uint16 value); + + // Establece el valor de la variable + void setRotateAmount(double value); + + // Cambia el sentido de la rotación + void switchRotate(); }; #endif diff --git a/source/smartsprite.cpp b/source/smartsprite.cpp index a5eb314..a5ea765 100644 --- a/source/smartsprite.cpp +++ b/source/smartsprite.cpp @@ -92,24 +92,6 @@ void SmartSprite::setDestY(int value) mDestY = value; } -// Establece el valor de la variable -void SmartSprite::setRotate(bool value) -{ - mRotate = value; -} - -// Establece el valor de la variable -void SmartSprite::setRotateSpeed(Uint16 value) -{ - mRotateSpeed = value; -} - -// Establece el valor de la variable -void SmartSprite::setRotateAmount(double value) -{ - mRotateAmount = value; -} - // Obtiene el valor de la variable int SmartSprite::getDestX() { @@ -122,37 +104,12 @@ int SmartSprite::getDestY() return mDestY; } -// Obtiene el valor de la variable -bool SmartSprite::getRotate() -{ - return mRotate; -} - -// Obtiene el valor de la variable -Uint16 SmartSprite::getRotateSpeed() -{ - return mRotateSpeed; -} - -// Establece la rotacion -void SmartSprite::rotate() -{ - if (mRotate) - { - if (mCounter % mRotateSpeed == 0) - { - incAngle(mRotateAmount); - } - } -} - // Actualiza la posición y comprueba si ha llegado a su destino bool SmartSprite::update() { if (mEnabled) { - move(); - rotate(); + MovingSprite::update(); // Comprueba si se desplaza en el eje X hacia la derecha if ((getAccelX() > 0) || ((getAccelX() == 0) && (getVelX() > 0))) @@ -168,7 +125,6 @@ bool SmartSprite::update() setAccelX(0.0f); } } - // Comprueba si se desplaza en el eje X hacia la izquierda else if ((getAccelX() < 0) || ((getAccelX() == 0) && (getVelX() < 0))) { @@ -244,9 +200,6 @@ bool SmartSprite::update() } } } - - mCounter++; - mCounter %= 65000; } return mIsOnDestination; diff --git a/source/smartsprite.h b/source/smartsprite.h index c1ca798..12463a8 100644 --- a/source/smartsprite.h +++ b/source/smartsprite.h @@ -11,15 +11,11 @@ class SmartSprite : public AnimatedSprite private: bool mEnabled; // Indica si esta habilitado bool mIsOnDestination; // Indica si está en el destino - bool mRotate; // Indica si ha de rotar int mDestX; // Posicion de destino en el eje X int mDestY; // Posicion de destino en el eje Y int mId; // Identificador - Uint16 mCounter; // Contador interno Uint16 mEnabledCounter; // Contador para deshabilitarlo - Uint16 mRotateSpeed; // Velocidad de giro Uint8 *mIntroEvents; // Dirección del array de eventos donde notificar el estado - double mRotateAmount; // Cantidad de grados a girar en cada iteración public: // Constructor @@ -52,30 +48,12 @@ public: // Establece el valor de la variable void setDestY(int value); - // Establece el valor de la variable - void setRotate(bool value); - - // Establece el valor de la variable - void setRotateSpeed(Uint16 value); - - // Establece el valor de la variable - void setRotateAmount(double value); - // Obtiene el valor de la variable int getDestX(); // Obtiene el valor de la variable int getDestY(); - // Obtiene el valor de la variable - bool getRotate(); - - // Obtiene el valor de la variable - Uint16 getRotateSpeed(); - - // Establece la rotacion - void rotate(); - // Actualiza la posición y comprueba si ha llegado a su destino bool update(); diff --git a/source/sprite.cpp b/source/sprite.cpp index dd4344f..a032c51 100644 --- a/source/sprite.cpp +++ b/source/sprite.cpp @@ -32,6 +32,9 @@ void Sprite::init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *r // Establece el rectangulo de donde coger la imagen setSpriteClip(0, 0, w, h); + + // Habilita el objeto + setEnabled(true); } // Inicializador @@ -58,7 +61,8 @@ void Sprite::init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer) // Muestra el sprite por pantalla void Sprite::render() { - mTexture->render(mRenderer, mPosX, mPosY, &mSpriteClip); + if (mEnabled) + mTexture->render(mRenderer, mPosX, mPosY, &mSpriteClip); } // Obten el valor de la variable @@ -146,4 +150,16 @@ void Sprite::setTexture(LTexture *texture) void Sprite::setRenderer(SDL_Renderer *renderer) { mRenderer = renderer; +} + +// Establece el valor de la variable +void Sprite::setEnabled(bool value) +{ + mEnabled = value; +} + +// Comprueba si el objeto está habilitado +bool Sprite::isEnabled() +{ + return mEnabled; } \ No newline at end of file diff --git a/source/sprite.h b/source/sprite.h index 9654ed8..b0d0b3e 100644 --- a/source/sprite.h +++ b/source/sprite.h @@ -8,44 +8,56 @@ // Clase sprite class Sprite { +protected: + int mPosX; // Posición en el eje X donde dibujar el sprite + int mPosY; // Posición en el eje Y donde dibujar el sprite + Uint16 mWidth; // Ancho del sprite + Uint16 mHeight; // Alto del sprite + + SDL_Renderer *mRenderer; // Puntero al renderizador de la ventana + LTexture *mTexture; // Textura donde estan todos los dibujos del sprite + SDL_Rect mSpriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla + + bool mEnabled; // Indica si el sprite esta habilitado + public: - // Constructor - Sprite(); + // Constructor + Sprite(); // Destructor ~Sprite(); - // Inicializador - void init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer); + // Inicializador + void init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer); void init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer); // Muestra el sprite por pantalla void render(); - + // Obten el valor de la variable int getPosX(); - + // Obten el valor de la variable int getPosY(); - + // Obten el valor de la variable int getWidth(); - + // Obten el valor de la variable int getHeight(); - + // Establece el valor de la variable void setPosX(int x); - + // Establece el valor de la variable void setPosY(int y); - + // Establece el valor de la variable void setWidth(int w); - + // Establece el valor de la variable void setHeight(int h); - + // Obten el valor de la variable SDL_Rect getSpriteClip(); @@ -56,32 +68,19 @@ public: void setSpriteClip(int x, int y, int w, int h); // Obten el valor de la variable - LTexture* getTexture(); + LTexture *getTexture(); // Establece el valor de la variable void setTexture(LTexture *texture); - // Establece el valor de la variable + // Establece el valor de la variable void setRenderer(SDL_Renderer *renderer); + // Establece el valor de la variable + void setEnabled(bool value); -protected: - // Posición X,Y donde dibujar el sprite - int mPosX; - int mPosY; - - // Alto y ancho del sprite - Uint16 mWidth; - Uint16 mHeight; - - // Puntero al renderizador de la ventana - SDL_Renderer *mRenderer; - - // Textura donde estan todos los dibujos del sprite - LTexture *mTexture; - - // Rectangulo de la textura que se dibujará en pantalla - SDL_Rect mSpriteClip; + // Comprueba si el objeto está habilitado + bool isEnabled(); }; #endif