diff --git a/data/gfx/item/item_debian.ani b/data/gfx/item/item_debian.ani new file mode 100644 index 0000000..3922815 --- /dev/null +++ b/data/gfx/item/item_debian.ani @@ -0,0 +1,9 @@ +frame_width=20 +frame_height=20 + +[animation] +name=default +speed=10 +loop=0 +frames=0,1 +[/animation] \ No newline at end of file diff --git a/data/gfx/item/item_debian.png b/data/gfx/item/item_debian.png new file mode 100644 index 0000000..850892a Binary files /dev/null and b/data/gfx/item/item_debian.png differ diff --git a/data/gfx/tabe/tabe.ani b/data/gfx/tabe/tabe.ani index 08af04b..2a0a670 100644 --- a/data/gfx/tabe/tabe.ani +++ b/data/gfx/tabe/tabe.ani @@ -2,8 +2,15 @@ frame_width=32 frame_height=32 [animation] -name=default +name=fly speed=2 loop=0 frames=0,1 [/animation] + +[animation] +name=hit +speed=2 +loop=0 +frames=2,3 +[/animation] \ No newline at end of file diff --git a/data/gfx/tabe/tabe.png b/data/gfx/tabe/tabe.png index d168a88..485b950 100644 Binary files a/data/gfx/tabe/tabe.png and b/data/gfx/tabe/tabe.png differ diff --git a/source/director.cpp b/source/director.cpp index 79ae1cf..ffed3d6 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -494,6 +494,8 @@ void Director::setFileList() Asset::get()->add(prefix + "/data/gfx/item/item_clock.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_coffee.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_coffee.ani", AssetType::ANIMATION); + Asset::get()->add(prefix + "/data/gfx/item/item_debian.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/gfx/item/item_debian.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.ani", AssetType::ANIMATION); } diff --git a/source/game.cpp b/source/game.cpp index 655ba15..480fde6 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -140,6 +140,7 @@ void Game::setResources() game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_powerup")); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_one_hit")); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_stop")); + game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_100000_points")); } // Texturas - Items @@ -149,6 +150,7 @@ void Game::setResources() item_textures_.emplace_back(Resource::get()->getTexture("item_points3_pacmar.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_clock.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_coffee.png")); + item_textures_.emplace_back(Resource::get()->getTexture("item_debian.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_coffee_machine.png")); } @@ -181,6 +183,7 @@ void Game::setResources() item_animations_.emplace_back(Resource::get()->getAnimation("item_points3_pacmar.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_clock.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee.ani")); + item_animations_.emplace_back(Resource::get()->getAnimation("item_debian.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_coffee_machine.ani")); } } @@ -297,7 +300,7 @@ void Game::updateGameStateGameOver() updateSmartSprites(); updatePathSprites(); updateTimeStopped(); - checkBulletBalloonCollision(); + checkBulletCollision(); cleanVectors(); if (game_over_counter_ > 0) @@ -462,37 +465,36 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) case ItemType::DISK: { player->addScore(1000); - const auto x = - item->getPosX() + - (item->getWidth() - game_text_textures_[0]->getWidth()) / 2; - createItemText(x, game_text_textures_[0]); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(0)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(0)); break; } case ItemType::GAVINA: { player->addScore(2500); - const auto x = - item->getPosX() + - (item->getWidth() - game_text_textures_[1]->getWidth()) / 2; - createItemText(x, game_text_textures_[1]); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(1)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(1)); break; } case ItemType::PACMAR: { player->addScore(5000); - const auto x = - item->getPosX() + - (item->getWidth() - game_text_textures_[2]->getWidth()) / 2; - createItemText(x, game_text_textures_[2]); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(2)); + break; + } + case ItemType::DEBIAN: + { + player->addScore(100000); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(6)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(6)); break; } case ItemType::CLOCK: { enableTimeStopItem(); - const auto x = - item->getPosX() + - (item->getWidth() - game_text_textures_[5]->getWidth()) / 2; - createItemText(x, game_text_textures_[5]); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(5)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(5)); break; } case ItemType::COFFEE: @@ -500,18 +502,14 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) if (player->getCoffees() == 2) { player->addScore(5000); - const auto x = - item->getPosX() + - (item->getWidth() - game_text_textures_[2]->getWidth()) / 2; - createItemText(x, game_text_textures_[2]); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(2)); } else { player->giveExtraHit(); - const auto x = - item->getPosX() + - (item->getWidth() - game_text_textures_[4]->getWidth()) / 2; - createItemText(x, game_text_textures_[4]); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(4)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(4)); } JA_PlaySound(Resource::get()->getSound("voice_coffee.wav")); break; @@ -520,10 +518,8 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) { player->setPowerUp(); coffee_machine_enabled_ = false; - const auto x = - item->getPosX() + - (item->getWidth() - game_text_textures_[3]->getWidth()) / 2; - createItemText(x, game_text_textures_[3]); + const auto x = item->getPosX() + (item->getWidth() - game_text_textures_.at(3)->getWidth()) / 2; + createItemText(x, game_text_textures_.at(3)); JA_PlaySound(Resource::get()->getSound("voice_power_up.wav")); break; } @@ -539,11 +535,23 @@ void Game::checkPlayerItemCollision(std::shared_ptr &player) } } -// Comprueba y procesa la colisión entre las balas y los globos -void Game::checkBulletBalloonCollision() +// Comprueba y procesa la colisión de las balas +void Game::checkBulletCollision() { for (auto &bullet : bullets_) { + // Comprueba la colisión con el Tabe + if (bullet->isEnabled() && tabe_->isEnabled()) + if (checkCollision(bullet->getCollider(), tabe_->getCollider())) + { + tabe_->setState(TabeState::HIT); + bullet->disable(); + auto pos = tabe_->getCollider(); + createItem(tabe_->tryToGetBonus() ? ItemType::DEBIAN : ItemType::COFFEE, pos.x, pos.y); + break; + } + + // Comprueba la colisión con los globos for (auto &balloon : balloon_manager_->getBalloons()) { if (balloon->isEnabled() && (!balloon->isInvulnerable()) && bullet->isEnabled()) @@ -1246,7 +1254,8 @@ void Game::checkEvents() } case SDLK_7: // Flash { - screen_->flash(flash_color, 3); + // screen_->flash(flash_color, 3); + tabe_->setState(TabeState::HIT); break; } case SDLK_8: @@ -1941,7 +1950,7 @@ void Game::updateGameStatePlaying() updatePathSprites(); updateTimeStopped(); updateHelper(); - checkBulletBalloonCollision(); + checkBulletCollision(); updateMenace(); checkAndUpdateBalloonSpeed(); checkState(); diff --git a/source/game.h b/source/game.h index 4f44bb3..ae32daf 100644 --- a/source/game.h +++ b/source/game.h @@ -211,8 +211,8 @@ private: // Comprueba la colisión entre el jugador y los items void checkPlayerItemCollision(std::shared_ptr &player); - // Comprueba la colisión entre las balas y los globos - void checkBulletBalloonCollision(); + // Comprueba y procesa la colisión de las balas + void checkBulletCollision(); // Mueve las balas activas void updateBullets(); diff --git a/source/item.h b/source/item.h index 15025a7..27108d9 100644 --- a/source/item.h +++ b/source/item.h @@ -22,8 +22,9 @@ enum class ItemType : int PACMAR = 3, /**< Pacman */ CLOCK = 4, /**< Reloj */ COFFEE = 5, /**< Café */ - COFFEE_MACHINE = 6,/**< Máquina de café */ - NONE = 7, /**< Ninguno */ + DEBIAN = 6, /**< Debian */ + COFFEE_MACHINE = 7,/**< Máquina de café */ + NONE = 8, /**< Ninguno */ }; /** diff --git a/source/resource.cpp b/source/resource.cpp index 73e6a36..0fe7772 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -301,6 +301,7 @@ void Resource::createTextures() // Tamaño doble std::vector strings2X = { + NameAndText("game_text_100000_points", "100.000"), NameAndText("game_text_get_ready", lang::getText(75)), NameAndText("game_text_last_stage", lang::getText(79)), NameAndText("game_text_congratulations", lang::getText(50)), diff --git a/source/sprite.h b/source/sprite.h index 5534996..a8657e0 100644 --- a/source/sprite.h +++ b/source/sprite.h @@ -37,6 +37,7 @@ public: // Devuelve el rectangulo donde está el sprite SDL_Rect getPosition() const { return pos_; } + SDL_Rect &getRect() { return pos_; } // Establece la posición y el tamaño void setX(int x) { pos_.x = x; } diff --git a/source/tabe.cpp b/source/tabe.cpp index 3464593..3e00fc0 100644 --- a/source/tabe.cpp +++ b/source/tabe.cpp @@ -18,6 +18,7 @@ void Tabe::update() { sprite_->update(); move(); + updateState(); } } @@ -100,7 +101,8 @@ void Tabe::enable() if (!enabled_) { enabled_ = true; - y_ = 20.0f; + has_bonus_ = true; + y_ = param.game.game_area.rect.y + 20.0f; // Establece una dirección aleatoria destiny_ = direction_ = rand() % 2 == 0 ? TabeDirection::TO_THE_LEFT : TabeDirection::TO_THE_RIGHT; @@ -145,4 +147,52 @@ void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) default: break; } -} \ No newline at end of file +} + +// Establece el estado +void Tabe::setState(TabeState state) +{ + if (enabled_) + { + state_ = state; + + switch (state) + { + case TabeState::FLY: + sprite_->setCurrentAnimation("fly"); + break; + + case TabeState::HIT: + sprite_->setCurrentAnimation("hit"); + hit_counter = 5; + break; + + default: + break; + } + } +} + +// Actualiza el estado +void Tabe::updateState() +{ + if (state_ == TabeState::HIT) + { + --hit_counter; + if (hit_counter == 0) + { + setState(TabeState::FLY); + } + } +} + +// Intenta obtener el bonus +bool Tabe::tryToGetBonus() +{ + if (has_bonus_ && rand() % 10 == 0) + { + has_bonus_ = false; + return true; + } + return false; +} diff --git a/source/tabe.h b/source/tabe.h index 0ece92a..ad81be4 100644 --- a/source/tabe.h +++ b/source/tabe.h @@ -9,6 +9,12 @@ enum class TabeDirection : int TO_THE_RIGHT = 1, }; +enum class TabeState : int +{ + FLY = 0, + HIT = 1, +}; + // Clase Tabe class Tabe { @@ -21,15 +27,18 @@ private: std::unique_ptr sprite_; // Sprite con los graficos y animaciones // Variables - float x_ = 0; // Posición del objeto - float y_ = 0; // Posición del objeto - float speed_ = 0.0f; // Velocidad de movimiento del objeto - float accel_ = 0.0f; // Aceleración del objeto - int fly_distance_ = 0; // Distancia de vuelo - int waiting_counter_ = 0; // Tiempo que pasa quieto el objeto - bool enabled_ = false; // Indica si el objeto está activo - TabeDirection direction_; // Dirección del objeto - TabeDirection destiny_; // Destino del objeto + float x_ = 0; // Posición del objeto + float y_ = 0; // Posición del objeto + float speed_ = 0.0f; // Velocidad de movimiento del objeto + float accel_ = 0.0f; // Aceleración del objeto + int fly_distance_ = 0; // Distancia de vuelo + int waiting_counter_ = 0; // Tiempo que pasa quieto el objeto + bool enabled_ = false; // Indica si el objeto está activo + TabeDirection direction_; // Dirección del objeto + TabeDirection destiny_; // Destino del objeto + TabeState state_ = TabeState::FLY; // Estado + int hit_counter = 0; // Contador para el estado HIT + bool has_bonus_ = true; // Indica si el Tabe aun tiene el bonus para soltar // Mueve el objeto void move(); @@ -40,6 +49,9 @@ private: // Establece un vuelo aleatorio void setRandomFlyPath(TabeDirection direction, int lenght); + // Actualiza el estado + void updateState(); + public: // Constructor Tabe(); @@ -55,4 +67,16 @@ public: // Habilita el objeto void enable(); + + // Establece el estado + void setState(TabeState state); + + // Intenta obtener el bonus + bool tryToGetBonus(); + + // Obtiene el area de colisión + SDL_Rect &getCollider() { return sprite_->getRect(); } + + // Getters + bool isEnabled() const { return enabled_; } }; \ No newline at end of file