diff --git a/CMakeLists.txt b/CMakeLists.txt index 3514672..8c90621 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,9 @@ set(GAME_OBJECTS GameObjects/Entities/Towers/magic_tower.cpp GameObjects/Entities/Towers/cannon_tower.cpp GameObjects/explosion.cpp + GameObjects/Entities/Traps/bear_trap.cpp + GameObjects/Entities/Traps/bomb.cpp + GameObjects/Interface/coin.cpp GameObjects/Entities/Projectiles/linear_autoguided_projectile.cpp GameObjects/Entities/Projectiles/linear_test_projectile.cpp) diff --git a/Controller/controller.cpp b/Controller/controller.cpp index bacfa7e..bdee8b8 100644 --- a/Controller/controller.cpp +++ b/Controller/controller.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "GameObjects/Entities/Mobs/skeleton.h" #include "GameObjects/Entities/Mobs/hedgehog.h" @@ -99,8 +100,25 @@ void Controller::TickAllTickables() { base_hp_ = 0; emit GameOver(); } + RegulateMoney(); + std::cout << balance_ << '\n'; } void Controller::DealDamageToBase(int damage) { // damage_per_current_tick_ += damage; } + +void Controller::RegulateMoney() { + if (scene_->GetCoinsCount() > coins_count_) { + balance_ += Costs::kCoinCost; + } + coins_count_ = scene_->GetCoinsCount(); + if (scene_->GetCannonTowersCount() > cannon_tower_count_) { + balance_ -= Costs::kCannonTowerCost; + } + cannon_tower_count_ = scene_->GetCannonTowersCount(); + if (scene_->GetMagicTowersCount() > magic_tower_count_) { + balance_ -= Costs::kMagicTowerCost; + } + magic_tower_count_ = scene_->GetMagicTowersCount(); +} diff --git a/Controller/controller.h b/Controller/controller.h index cea6ea8..e049eda 100644 --- a/Controller/controller.h +++ b/Controller/controller.h @@ -5,9 +5,11 @@ #include #include "GameObjects/Interface/entity.h" +#include "GameObjects/Interface/coin.h" #include "game_view.h" #include "game_scene.h" #include "level.h" +#include "constants.h" class Controller : public QObject { Q_OBJECT @@ -35,11 +37,18 @@ class Controller : public QObject { void SetupScene(); void LaunchTickTimer(); + void RegulateMoney(); + GameScene* scene_; GameView* view_; QTimer* tick_timer_; Level* level_; + int balance_ = kStartBalance; int base_hp_; int damage_per_current_tick_; + + int coins_count_ = 0; + int cannon_tower_count_ = 0; + int magic_tower_count_ = 0; }; diff --git a/GameObjects/Entities/Mobs/Basis/mob.cpp b/GameObjects/Entities/Mobs/Basis/mob.cpp index df5e5ac..36aa6cd 100644 --- a/GameObjects/Entities/Mobs/Basis/mob.cpp +++ b/GameObjects/Entities/Mobs/Basis/mob.cpp @@ -3,6 +3,9 @@ #include #include "Controller/controller.h" +#include "GameObjects/Interface/coin.h" +#include "Utilities/Resources/pixmap_loader.h" +#include "constants.h" Mob::Mob(const VectorF& coordinates, Animation* animation, @@ -58,6 +61,10 @@ Mob::~Mob() { if (route_ != nullptr) { route_->RemoveEntity(this); } + if (rand() % Entities::kCoinAppearChance == 1) { //NOLINT + scene()->addItem(new Coin(VectorF(pos().x(), pos().y()), + PixmapLoader::Pixmaps::kCoinAnimations)); + } } QRectF Mob::boundingRect() const { diff --git a/GameObjects/Entities/Towers/TowerSlots/tower_slot.cpp b/GameObjects/Entities/Towers/TowerSlots/tower_slot.cpp index b8733d7..97e5880 100644 --- a/GameObjects/Entities/Towers/TowerSlots/tower_slot.cpp +++ b/GameObjects/Entities/Towers/TowerSlots/tower_slot.cpp @@ -12,10 +12,12 @@ bool TowerSlot::IsTakenUp() const { void TowerSlot::TakeUpArea(Tower* tower) { tower_ = tower; + scene()->IncMagicTowersCount(); } void TowerSlot::ClearArea() { tower_ = nullptr; +// scene()->DecCannonTowersCount(); } TowerSlot::TowerSlot(const VectorF& coordinates) diff --git a/GameObjects/Entities/Towers/cannon_tower.cpp b/GameObjects/Entities/Towers/cannon_tower.cpp index 52ca7a0..6575878 100644 --- a/GameObjects/Entities/Towers/cannon_tower.cpp +++ b/GameObjects/Entities/Towers/cannon_tower.cpp @@ -16,7 +16,6 @@ CannonTower::CannonTower(const VectorF& coordinates) : void CannonTower::Upgrade() { Tower::Upgrade(); - ++Tower::current_level_; if (current_level_ == 2) { Tower::cooldown_ = Entities::CannonTower::kAttackCooldownLevel2; @@ -37,3 +36,4 @@ void CannonTower::Upgrade() { void CannonTower::mousePressEvent(QGraphicsSceneMouseEvent* event) { Upgrade(); } + diff --git a/GameObjects/Entities/Towers/magic_tower.cpp b/GameObjects/Entities/Towers/magic_tower.cpp index 875410c..873f37b 100644 --- a/GameObjects/Entities/Towers/magic_tower.cpp +++ b/GameObjects/Entities/Towers/magic_tower.cpp @@ -10,7 +10,8 @@ MagicTower::MagicTower(const VectorF& coordinates) : Entities::MagicTower::kAttackCooldownLevel1, Entities::MagicTower::kAttackRangeLevel1, Entities::MagicTower::kMaxLevel, - Entities::MagicTower::kPrice) {} + Entities::MagicTower::kPrice) { +} void MagicTower::Upgrade() { Tower::Upgrade(); diff --git a/GameObjects/Entities/Traps/bear_trap.cpp b/GameObjects/Entities/Traps/bear_trap.cpp new file mode 100644 index 0000000..688cd99 --- /dev/null +++ b/GameObjects/Entities/Traps/bear_trap.cpp @@ -0,0 +1,83 @@ +#include "bear_trap.h" +#include "Utilities/Resources/pixmap_loader.h" +#include "constants.h" + +#include +#include +#include + +QRectF BearTrap::boundingRect() const { + return QRectF(QPointF(-15, -15), QSize(30, 30)); +} + +BearTrap::BearTrap(const VectorF& coordinates, QPixmap* pixmap) + : BearTrap(coordinates, + new Animation( + PixmapLoader::Pixmaps::kBearTrapIdle, + 50_ms)) { + attacking_animation_ = new Animation( + PixmapLoader::Pixmaps::kBearTrapAttacking, + 50_ms);; + idle_animation_ = new Animation( + PixmapLoader::Pixmaps::kBearTrapIdle, + 50_ms); + broken_animation_ = new Animation( + PixmapLoader::Pixmaps::kBearTrapBroken, + 50_ms); + repairing_animation_ = new Animation( + PixmapLoader::Pixmaps::kBearTrapBroken, + 50_ms); + setFlag(QGraphicsItem::ItemIsFocusable, true); + setScale(2.5); +} + +BearTrap::BearTrap(const VectorF& coordinates, Animation* animation) + : Entity(coordinates, animation) {} + +void BearTrap::Tick(Time delta) { + if (animation_->WasEndedDuringPreviousUpdate()) { + if (is_broken_) { + animation_ = repairing_animation_; + } else { + animation_ = idle_animation_; + } + } + Entity::Tick(delta); + std::vector mobs = scene()->Mobs(); + for (auto mob : mobs) { + if (mob->sceneBoundingRect().intersects(this->sceneBoundingRect()) + && !is_broken_) { + mob->ApplyDamage(Damage(mob->GetHealth())); + animation_ = attacking_animation_; + is_broken_ = true; + } + } +} + +void BearTrap::paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget) { + Entity::paint(painter, option, widget); +} + +void BearTrap::mousePressEvent(QGraphicsSceneMouseEvent* event) { + if (event->button() != Qt::LeftButton) { + return; + } + RepairTrap(); +} + +void BearTrap::RepairTrap() { + is_broken_ = false; + animation_ = repairing_animation_; + update(); +} + +BearTrap::~BearTrap() { + delete idle_animation_; + delete broken_animation_; + delete attacking_animation_; + delete repairing_animation_; +} + + diff --git a/GameObjects/Entities/Traps/bear_trap.h b/GameObjects/Entities/Traps/bear_trap.h new file mode 100644 index 0000000..7788ada --- /dev/null +++ b/GameObjects/Entities/Traps/bear_trap.h @@ -0,0 +1,27 @@ +#pragma once + +#include "GameObjects/Entities/Mobs/Basis/mob.h" + +class BearTrap : public Entity { + public: + BearTrap(const VectorF& coordinates, QPixmap* pixmap); + BearTrap(const VectorF& coordinates, Animation* animation); + ~BearTrap(); + + [[nodiscard]] QRectF boundingRect() const; + void paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget); + void Tick(Time delta); + void RepairTrap(); + + void mousePressEvent(QGraphicsSceneMouseEvent* event) override; + + private: + Animation* idle_animation_; + Animation* attacking_animation_; + Animation* broken_animation_; + Animation* repairing_animation_; + + bool is_broken_ = false; +}; diff --git a/GameObjects/Entities/Traps/bomb.cpp b/GameObjects/Entities/Traps/bomb.cpp new file mode 100644 index 0000000..7c33d62 --- /dev/null +++ b/GameObjects/Entities/Traps/bomb.cpp @@ -0,0 +1,73 @@ +#include "bomb.h" +#include "Utilities/Resources/pixmap_loader.h" + +#include "constants.h" + +#include +#include +#include + +QRectF Bomb::boundingRect() const { + return QRectF(QPointF(-15, -15), QSize(30, 30)); +} + +Bomb::Bomb(const VectorF& coordinates, QPixmap* pixmap) + : Bomb(coordinates, new Animation( + PixmapLoader::Pixmaps::kBombIdle, + 50_ms)) { + idle_animation_ = new Animation( + PixmapLoader::Pixmaps::kBombIdle, + 50_ms); + explosion_animation_ = new Animation( + PixmapLoader::Pixmaps::kBombExplosion, + 50_ms); + setFlag(QGraphicsItem::ItemIsFocusable, true); + setScale(2.5); +} + +Bomb::Bomb(const VectorF& coordinates, Animation* animation) + : Entity(coordinates, animation) {} + +void Bomb::Tick(Time delta) { + if (animation_->WasEndedDuringPreviousUpdate()) { + if (activated_) { + animation_ = explosion_animation_; + } + } + + Entity::Tick(delta); + if (activated_ && animation_->WasEndedDuringPreviousUpdate()) { + std::vector mobs = scene()->Mobs(); + for (auto mob : mobs) { + if (mob->sceneBoundingRect().intersects(this->sceneBoundingRect())) { + mob->ApplyDamage(Damage(mob->GetHealth())); + animation_ = explosion_animation_; + } + } + delete this; + } +} + +void Bomb::paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget) { + Entity::paint(painter, option, widget); +} + +void Bomb::mousePressEvent(QGraphicsSceneMouseEvent* event) { + if (event->button() != Qt::LeftButton) { + return; + } + Explode(); +} + +Bomb::~Bomb() { + delete idle_animation_; + delete explosion_animation_; +} + +void Bomb::Explode() { + activated_ = true; +} + + diff --git a/GameObjects/Entities/Traps/bomb.h b/GameObjects/Entities/Traps/bomb.h new file mode 100644 index 0000000..a27c370 --- /dev/null +++ b/GameObjects/Entities/Traps/bomb.h @@ -0,0 +1,26 @@ +#pragma once + +#include "GameObjects/Entities/Mobs/Basis/mob.h" + +class Bomb : public Entity { + public: + Bomb(const VectorF& coordinates, QPixmap* pixmap); + Bomb(const VectorF& coordinates, Animation* animation); + ~Bomb(); + + [[nodiscard]] QRectF boundingRect() const; + void paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget); + void Tick(Time delta); + + void Explode(); + + void mousePressEvent(QGraphicsSceneMouseEvent* event) override; + + private: + Animation* idle_animation_; + Animation* explosion_animation_; + + bool activated_ = false; +}; diff --git a/GameObjects/Interface/coin.cpp b/GameObjects/Interface/coin.cpp new file mode 100644 index 0000000..f01bbb6 --- /dev/null +++ b/GameObjects/Interface/coin.cpp @@ -0,0 +1,60 @@ +#include "coin.h" +#include "Utilities/Resources/pixmap_loader.h" +#include "constants.h" + +#include +#include +#include + +Coin::Coin(const VectorF& coordinates, QPixmap* pixmap) + : Coin(coordinates, new Animation( + PixmapLoader::Pixmaps::kCoinIdle, + 50_ms)) { + idle_animation_ = new Animation( + PixmapLoader::Pixmaps::kCoinIdle, + 50_ms); + collecting_route_ = nullptr; + speed_ = 300; + setFlag(QGraphicsItem::ItemIsFocusable, true); + setScale(2.5); +} + +Coin::Coin(const VectorF& coordinates, Animation* animation) + : Entity(coordinates, animation) {} + +void Coin::Tick(Time delta) { + if (animation_->WasEndedDuringPreviousUpdate()) { + animation_ = idle_animation_; + } + if (collecting_route_ != nullptr) { + collecting_route_->Move(this, delta.ms() * speed_); + } + Entity::Tick(delta); +} + +void Coin::paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget) { + Entity::paint(painter, option, widget); +} + +void Coin::mousePressEvent(QGraphicsSceneMouseEvent* event) { + scene()->IncCoinsCount(); + update(); + SetRoute(); + delete this; +} + +Coin::~Coin() { + delete idle_animation_; +// scene()->DecCoinsCount(); +} + +void Coin::SetRoute() { + std::vector points; + points.emplace_back(this->pos().x(), this->pos().y()); + points.emplace_back(50, 50); + collecting_route_ = new Route(points); + collecting_route_->AddEntity(this); +} + diff --git a/GameObjects/Interface/coin.h b/GameObjects/Interface/coin.h new file mode 100644 index 0000000..c413fd3 --- /dev/null +++ b/GameObjects/Interface/coin.h @@ -0,0 +1,24 @@ +#pragma once + +#include "GameObjects/Entities/Mobs/Basis/mob.h" + +class Coin : public Entity { + public: + Coin(const VectorF& coordinates, QPixmap* pixmap); + Coin(const VectorF& coordinates, Animation* animation); + ~Coin(); + + void paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget); + void Tick(Time delta); + + void SetRoute(); + + void mousePressEvent(QGraphicsSceneMouseEvent* event) override; + + private: + Animation* idle_animation_; + Route* collecting_route_; + qreal speed_; +}; diff --git a/Resources/images/bear_trap.png b/Resources/images/bear_trap.png new file mode 100644 index 0000000..11f3160 Binary files /dev/null and b/Resources/images/bear_trap.png differ diff --git a/Resources/images/bomb0.png b/Resources/images/bomb0.png new file mode 100644 index 0000000..6d01084 Binary files /dev/null and b/Resources/images/bomb0.png differ diff --git a/Resources/images/bomb1.png b/Resources/images/bomb1.png new file mode 100644 index 0000000..5c03b8b Binary files /dev/null and b/Resources/images/bomb1.png differ diff --git a/Resources/images/bomb2.png b/Resources/images/bomb2.png new file mode 100644 index 0000000..65af93c Binary files /dev/null and b/Resources/images/bomb2.png differ diff --git a/Resources/images/bomb3.png b/Resources/images/bomb3.png new file mode 100644 index 0000000..a9445b7 Binary files /dev/null and b/Resources/images/bomb3.png differ diff --git a/Resources/images/bomb4.png b/Resources/images/bomb4.png new file mode 100644 index 0000000..ebb6942 Binary files /dev/null and b/Resources/images/bomb4.png differ diff --git a/Resources/images/bomb5.png b/Resources/images/bomb5.png new file mode 100644 index 0000000..6660275 Binary files /dev/null and b/Resources/images/bomb5.png differ diff --git a/Resources/images/coin.png b/Resources/images/coin.png new file mode 100644 index 0000000..6bce34c Binary files /dev/null and b/Resources/images/coin.png differ diff --git a/Resources/resources.qrc b/Resources/resources.qrc index 12e01fb..9a8e09c 100644 --- a/Resources/resources.qrc +++ b/Resources/resources.qrc @@ -28,7 +28,14 @@ images/explosion.png - + images/bear_trap.png + images/bomb0.png + images/bomb1.png + images/bomb2.png + images/bomb3.png + images/bomb4.png + images/bomb5.png + images/coin.png GUI/Textured boxes/Default/top_left_corner.png GUI/Textured boxes/Default/top_right_corner.png diff --git a/Utilities/Resources/pixmap_loader.cpp b/Utilities/Resources/pixmap_loader.cpp index e7734c6..0e60df2 100644 --- a/Utilities/Resources/pixmap_loader.cpp +++ b/Utilities/Resources/pixmap_loader.cpp @@ -17,6 +17,27 @@ QPixmap* P::kTowerSlot; std::vector P::kLevelMaps; QPixmap* P::kEmpty; +QPixmap* P::kBombIdleFrame; +QPixmap* P::kBomb0; +QPixmap* P::kBomb1; +QPixmap* P::kBomb2; +QPixmap* P::kBomb3; +QPixmap* P::kBomb4; +QPixmap* P::kBomb5; +std::vector P::kBombExplosion; +std::vector P::kBombIdle; + +QPixmap* P::kBearTrap; +QPixmap* P::kBearTrapAnimations; +std::vector P::kBearTrapIdle; +std::vector P::kBearTrapAttacking; +std::vector P::kBearTrapBroken; +std::vector P::kBearTrapRepairing; + +std::vector P::kCoinIdle; +QPixmap* P::kCoinAnimations; + + QPixmap* P::FireTotem::kAnimations; std::vector P::FireTotem::kIdle; std::vector P::FireTotem::kDisappear; @@ -49,6 +70,7 @@ TexturedBoxPixmaps PixmapLoader::kButtonTexturedBoxPixmaps; void PixmapLoader::LoadPixmaps() { P::kBackground = new QPixmap(":images/background.png"); P::kTestBullet = new QPixmap(":images/test_bullet.png"); + P::kBearTrap = new QPixmap(":images/bear_trap.png"); P::kTowerSlot = new QPixmap(":images/tower_slot.png"); P::kMagicTowerLevel1 = new QPixmap(":images/magic_tower_level1.png"); P::kMagicTowerLevel2 = new QPixmap(":images/magic_tower_level2.png"); @@ -63,6 +85,9 @@ void PixmapLoader::LoadPixmaps() { } P::kEmpty = new QPixmap(); + LoadBearTrapAnimations(); + LoadBombAnimations(); + LoadCoinAnimations(); LoadFireTotemAnimations(); LoadSkeletonAnimations(); LoadCobraAnimations(); @@ -357,3 +382,103 @@ void PixmapLoader::LoadButtonTextureBox() { new QPixmap(":GUI/Textured boxes/Button/inside.png") }; } + +void PixmapLoader::LoadBearTrapAnimations() { + // file size - 128x32 + // 1 frame row, 4 frame columns + const int frame_width = 128 / 4; + const int frame_height = 32; + const int idle_animation_frames_count = 1; + const int attack_animation_frames_count = 3; + const int broken_animation_frames_count = 1; + const int repairing_animation_frames_count = 1; + // row and column start from 0 + const int idle_animation_row = 0; + const int idle_animation_column = 0; + const int attack_animation_row = 0; + const int attack_animation_column = 1; + const int broken_animation_row = 0; + const int broken_animation_column = 3; + const int repairing_animation_row = 0; + const int repairing_animation_column = 0; + + P::kBearTrapAnimations = new QPixmap(":images/bear_trap.png"); + + P::kBearTrapIdle = CreateHorizontalFramesVector( + P::kBearTrapAnimations, + frame_width, + frame_height, + idle_animation_frames_count, + idle_animation_column * frame_width, + idle_animation_row * frame_height); + + P::kBearTrapBroken = CreateHorizontalFramesVector( + P::kBearTrapAnimations, + frame_width, + frame_height, + broken_animation_frames_count, + broken_animation_column * frame_width, + broken_animation_row * frame_height); + + P::kBearTrapAttacking = CreateHorizontalFramesVector( + P::kBearTrapAnimations, + frame_width, + frame_height, + attack_animation_frames_count, + attack_animation_column * frame_width, + attack_animation_row * frame_height); + + P::kBearTrapAttacking = CreateHorizontalFramesVector( + P::kBearTrapAnimations, + frame_width, + frame_height, + attack_animation_frames_count, + attack_animation_column * frame_width, + attack_animation_row * frame_height); + + P::kBearTrapRepairing = CreateHorizontalFramesVector( + P::kBearTrapAnimations, + frame_width, + frame_height, + repairing_animation_frames_count, + repairing_animation_column * frame_width, + repairing_animation_row * frame_height); +} + +void PixmapLoader::LoadBombAnimations() { + P::kBombIdleFrame = new QPixmap(":images/bomb0.png"); + P::kBomb0 = new QPixmap(":images/bomb0.png"); + P::kBomb1 = new QPixmap(":images/bomb1.png"); + P::kBomb2 = new QPixmap(":images/bomb2.png"); + P::kBomb3 = new QPixmap(":images/bomb3.png"); + P::kBomb4 = new QPixmap(":images/bomb4.png"); + P::kBomb5 = new QPixmap(":images/bomb5.png"); + P::kBombExplosion.push_back(P::kBomb0); + P::kBombExplosion.push_back(P::kBomb1); + P::kBombExplosion.push_back(P::kBomb2); + P::kBombExplosion.push_back(P::kBomb3); + P::kBombExplosion.push_back(P::kBomb4); + P::kBombExplosion.push_back(P::kBomb5); + P::kBombIdle.push_back(P::kBombIdleFrame); +} + +void PixmapLoader::LoadCoinAnimations() { + // file size - 224x16 + // 1 frame rows, 14 frame columns + const int frame_width = 224 / 14; + const int frame_height = 16; + const int idle_animation_frames_count = 14; + // row and column start from 0 + const int idle_animation_row = 0; + const int idle_animation_column = 0; + + P::kCoinAnimations = new QPixmap(":images/coin.png"); + + P::kCoinIdle = CreateHorizontalFramesVector( + P::kCoinAnimations, + frame_width, + frame_height, + idle_animation_frames_count, + idle_animation_column * frame_width, + idle_animation_row * frame_height); +} diff --git a/Utilities/Resources/pixmap_loader.h b/Utilities/Resources/pixmap_loader.h index 95de2b3..5a9e569 100644 --- a/Utilities/Resources/pixmap_loader.h +++ b/Utilities/Resources/pixmap_loader.h @@ -24,6 +24,26 @@ class PixmapLoader { static std::vector kLevelMaps; static QPixmap* kEmpty; + static QPixmap* kBearTrap; + static QPixmap* kBearTrapAnimations; + static std::vector kBearTrapIdle; + static std::vector kBearTrapAttacking; + static std::vector kBearTrapBroken; + static std::vector kBearTrapRepairing; + + static std::vector kCoinIdle; + static QPixmap* kCoinAnimations; + + static QPixmap* kBomb0; + static QPixmap* kBomb1; + static QPixmap* kBomb2; + static QPixmap* kBomb3; + static QPixmap* kBomb4; + static QPixmap* kBomb5; + static std::vector kBombExplosion; + static std::vector kBombIdle; + static QPixmap* kBombIdleFrame; + class FireTotem { public: static QPixmap* kAnimations; @@ -84,6 +104,9 @@ class PixmapLoader { static void LoadHedgehogAnimations(); static void LoadDwarfAnimations(); static void LoadExplosionAnimation(); + static void LoadBearTrapAnimations(); + static void LoadBombAnimations(); + static void LoadCoinAnimations(); static void LoadUI(); static void LoadDefaultTextureBox(); diff --git a/constants.cpp b/constants.cpp index 09cf1d3..aaa7768 100644 --- a/constants.cpp +++ b/constants.cpp @@ -3,6 +3,7 @@ const bool kDebugMode = false; const int kFPS = 60; +const int kStartBalance = 1000; namespace Scene { const qreal kWidth = 1920; @@ -33,11 +34,11 @@ const qreal kZValue = 2000; namespace Entities { const int kCircleAttackAreaApproximationPointsCount = 10; -const QString kTestMobId = "TestMob"; const QString kSkeletonId = "Skeleton"; const QString kCobraId = "Cobra"; const QString kHedgehogId = "Hedgehog"; const QString kDwarfId = "Dwarf"; +const int kCoinAppearChance = 3; namespace MagicTower { const qreal kAttackRangeLevel1 = 300; @@ -100,3 +101,9 @@ const Time kCrossAccelerationCycleDuration = 1500_ms; const qreal kMaxCrossAcceleration = 600; } } // namespace Entities + +namespace Costs { +const int kCoinCost = 50; +const int kCannonTowerCost = 500; +const int kMagicTowerCost = 500; +} diff --git a/constants.h b/constants.h index 0fe2898..4136db7 100644 --- a/constants.h +++ b/constants.h @@ -8,6 +8,13 @@ extern const bool kDebugMode; extern const int kFPS; +extern const int kStartBalance; + +namespace Costs { +extern const int kCoinCost; +extern const int kCannonTowerCost; +extern const int kMagicTowerCost; +} namespace Scene { extern const qreal kWidth; @@ -34,11 +41,11 @@ extern const qreal kZValue; namespace Entities { extern const int kCircleAttackAreaApproximationPointsCount; -extern const QString kTestMobId; extern const QString kSkeletonId; extern const QString kCobraId; extern const QString kHedgehogId; extern const QString kDwarfId; +extern const int kCoinAppearChance; namespace MagicTower { extern const qreal kAttackRangeLevel1; diff --git a/game_scene.cpp b/game_scene.cpp index b62349e..c34f8ec 100644 --- a/game_scene.cpp +++ b/game_scene.cpp @@ -56,3 +56,43 @@ std::vector GameScene::Projectiles() const { return result; } +void GameScene::IncCoinsCount() { + ++coins_count_; +} + +void GameScene::DecCoinsCount() { + if (coins_count_ > 0) { + --coins_count_; + } +} + +void GameScene::IncCannonTowersCount() { + ++cannon_tower_count_; +} + +void GameScene::DecCannonTowersCount() { + if (cannon_tower_count_ > 0) { + --cannon_tower_count_; + } +} + +int GameScene::GetCoinsCount() { + return coins_count_; +} + +int GameScene::GetCannonTowersCount() { + return cannon_tower_count_; +} + +void GameScene::IncMagicTowersCount() { + ++magic_tower_count_; +} + +void GameScene::DecMagicTowersCount() { + --magic_tower_count_; +} + +int GameScene::GetMagicTowersCount() { + return magic_tower_count_; +} + diff --git a/game_scene.h b/game_scene.h index 906cd51..8cd3c4e 100644 --- a/game_scene.h +++ b/game_scene.h @@ -19,8 +19,28 @@ class GameScene : public QGraphicsScene { GameView* view(); + void IncCoinsCount(); + void DecCoinsCount(); + int GetCoinsCount(); + + void IncCannonTowersCount(); + void DecCannonTowersCount(); + int GetCannonTowersCount(); + + void IncMagicTowersCount(); + void DecMagicTowersCount(); + int GetMagicTowersCount(); + + + + [[nodiscard]] std::vector Mobs() const; [[nodiscard]] std::vector Towers() const; [[nodiscard]] std::vector TowerSlots() const; [[nodiscard]] std::vector Projectiles() const; + + private: + int coins_count_ = 0; + int cannon_tower_count_ = 0; + int magic_tower_count_ = 0; }; diff --git a/level.cpp b/level.cpp index 9c5304b..a912eef 100644 --- a/level.cpp +++ b/level.cpp @@ -15,7 +15,7 @@ Level::Level(int level_number) : level_number_(level_number) { QFile file(":Levels/Level" + - QString::fromStdString(std::to_string(level_number)) + "/level.json"); + QString::fromStdString(std::to_string(level_number)) + "/level.json"); if (!file.open(QIODevice::ReadOnly)) { throw std::invalid_argument("There is no such level"); @@ -44,6 +44,14 @@ Level::Level(int level_number) : level_number_(level_number) { tower_slots_.push_back( new TowerSlot(VectorF(tower_slot_x, tower_slot_y))); } + { + bear_traps_.push_back(new BearTrap(VectorF(150, 150), + PixmapLoader::Pixmaps::kTowerSlot)); + } + { + bombs_.push_back(new Bomb(VectorF(0, 150), + PixmapLoader::Pixmaps::kTowerSlot)); // test + } QJsonArray routes = root.value("routes").toArray(); routes_.reserve(routes.size()); @@ -109,6 +117,12 @@ void Level::AddObjectsToScene(GameScene* scene) { for (auto tower_slot : tower_slots_) { scene->addItem(tower_slot); } + for (auto bear_trap : bear_traps_) { + scene->addItem(bear_trap); + } + for (auto bomb : bombs_) { + scene->addItem(bomb); + } } void Level::Tick(Time delta) { @@ -134,12 +148,11 @@ int Level::GetStartMoney() const { } Level::SpawnEntry::SpawnEntry(QJsonObject* spawn_root_object) - : start_time_(Time(spawn_root_object->value("startTime").toInt())), - mob_type_(spawn_root_object->value("mobType").toString()), - count_(spawn_root_object->value("count").toInt()), - entry_duration_(Time(spawn_root_object->value("entryDuration").toInt())), - route_index_(spawn_root_object->value("routeIndex").toInt()) - {} + : start_time_(Time(spawn_root_object->value("startTime").toInt())), + mob_type_(spawn_root_object->value("mobType").toString()), + count_(spawn_root_object->value("count").toInt()), + entry_duration_(Time(spawn_root_object->value("entryDuration").toInt())), + route_index_(spawn_root_object->value("routeIndex").toInt()) {} void Level::SpawnEntry::AddMobsToWave( std::map* mobs, diff --git a/level.h b/level.h index ee099b7..c957ced 100644 --- a/level.h +++ b/level.h @@ -10,6 +10,8 @@ #include "GameObjects/Entities/Towers/TowerSlots/tower_slot.h" #include "Utilities/route.h" #include "Utilities/wave.h" +#include "GameObjects/Entities/Traps/bear_trap.h" +#include "GameObjects/Entities/Traps/bomb.h" class Level { public: @@ -41,6 +43,8 @@ class Level { int route_index_; }; + std::vector bear_traps_{}; + std::vector bombs_{}; std::vector tower_slots_{}; std::vector routes_{}; std::vector waves_{};