From e37ff585f763d8838847410198ac78191e7009e1 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Sat, 25 Dec 2021 08:46:23 +0300 Subject: [PATCH] lesson 2 withot destroy --- SBomber/include/Bomb.h | 16 +- SBomber/include/GameObject.h | 44 +- SBomber/include/SBomber.h | 29 +- SBomber/main.cpp | 48 +- SBomber/src/Bomb.cpp | 23 + SBomber/src/SBomber.cpp | 775 ++++++++++++++++--------- hw2.patch | 1030 ++++++++++++++++++++++++++++++++++ 7 files changed, 1622 insertions(+), 343 deletions(-) create mode 100644 hw2.patch diff --git a/SBomber/include/Bomb.h b/SBomber/include/Bomb.h index d122e7a..85aef44 100644 --- a/SBomber/include/Bomb.h +++ b/SBomber/include/Bomb.h @@ -6,7 +6,7 @@ class Bomb : public DynamicObject { public: - static const uint16_t BombCost = 10; // + static const uint16_t BombCost = 10; void Draw() const override; @@ -14,3 +14,17 @@ private: }; +class BombDecorator: public DynamicObject +{ +public: + BombDecorator(DynamicObject *bomb) : m_bomb(bomb) + { + } + void Move(uint16_t time) override; + void Draw() const override; + + void SetPos(double nx, double ny) override; + uint16_t GetWidth() const override; +private: + DynamicObject *m_bomb; +}; diff --git a/SBomber/include/GameObject.h b/SBomber/include/GameObject.h index 1d56d2e..cd7589a 100644 --- a/SBomber/include/GameObject.h +++ b/SBomber/include/GameObject.h @@ -2,25 +2,41 @@ #include -class GameObject { +class GameObject +{ public: - GameObject() : x(0.0), y(0.0), width(0) {} - virtual ~GameObject() = default; + GameObject() : x(0.0), y(0.0), width(0) + { + } + virtual ~GameObject() = default; - virtual void Draw() const = 0; + virtual void Draw() const = 0; - inline void SetPos(double nx, double ny) { - x = nx; - y = ny; - } + virtual inline void SetPos(double nx, double ny) + { + x = nx; + y = ny; + } - inline double GetY() const { return y; } - inline double GetX() const { return x; } + virtual inline double GetY() const + { + return y; + } + virtual inline double GetX() const + { + return x; + } - inline void SetWidth(uint16_t widthN) { width = widthN; } - inline uint16_t GetWidth() const { return width; } + virtual inline void SetWidth(uint16_t widthN) + { + width = widthN; + } + virtual inline uint16_t GetWidth() const + { + return width; + } protected: - double x, y; - uint16_t width; + double x, y; + uint16_t width; }; diff --git a/SBomber/include/SBomber.h b/SBomber/include/SBomber.h index 3ce1b9c..f6534f8 100644 --- a/SBomber/include/SBomber.h +++ b/SBomber/include/SBomber.h @@ -11,11 +11,13 @@ class SBomber { public: - SBomber(); ~SBomber(); - - inline bool GetExitFlag() const { return exitFlag; } + + inline bool GetExitFlag() const + { + return exitFlag; + } void ProcessKBHit(); void TimeStart(); @@ -25,29 +27,30 @@ public: void MoveObjects(); void CheckObjects(); -private: + void run(); +private: void CheckPlaneAndLevelGUI(); void CheckBombsAndGround(); - void CheckDestoyableObjects(Bomb* pBomb); + void CheckDestoyableObjects(Bomb *pBomb); - void DeleteDynamicObj(DynamicObject * pBomb); - void DeleteStaticObj(GameObject* pObj); +// void DeleteDynamicObj(DynamicObject *pBomb); +// void DeleteStaticObj(GameObject *pObj); - Ground * FindGround() const; - Plane * FindPlane() const; - LevelGUI * FindLevelGUI() const; + Ground* FindGround() const; + Plane* FindPlane() const; + LevelGUI* FindLevelGUI() const; std::vector FindDestoyableGroundObjects() const; std::vector FindAllBombs() const; - void DropBomb(); +// void DropBomb(); std::vector vecDynamicObj; std::vector vecStaticObj; - + bool exitFlag; uint64_t startTime, finishTime, passedTime; uint16_t bombsNumber, deltaTime, fps; int16_t score; -}; \ No newline at end of file +}; diff --git a/SBomber/main.cpp b/SBomber/main.cpp index aa0028a..9edd27d 100644 --- a/SBomber/main.cpp +++ b/SBomber/main.cpp @@ -2,58 +2,12 @@ #include "MyTools.h" #include "ScreenSingleton.h" -#include -#include -#include -#include -#include -#include - -int _kbhit() -{ - static const int STDIN = 0; - static bool initialized = false; - - if (!initialized) - { - // Use termios to turn off line buffering - termios term; - tcgetattr(STDIN, &term); - term.c_lflag &= ~ICANON; - tcsetattr(STDIN, TCSANOW, &term); - setbuf(stdin, NULL); - initialized = true; - } - - int bytesWaiting; - ioctl(STDIN, FIONREAD, &bytesWaiting); - return bytesWaiting; -} - int main(void) { MyTools::LoggerSingleton::getInstance().OpenLogFile("log.txt"); SBomber game; - - do - { - game.TimeStart(); - - if (_kbhit()) - { - game.ProcessKBHit(); - } - - ScreenSingleton::getInstance().ClrScr(); - - game.DrawFrame(); - game.MoveObjects(); - game.CheckObjects(); - - game.TimeFinish(); - - } while (!game.GetExitFlag()); + game.run(); MyTools::LoggerSingleton::getInstance().CloseLogFile(); diff --git a/SBomber/src/Bomb.cpp b/SBomber/src/Bomb.cpp index 4bc10d4..537e917 100644 --- a/SBomber/src/Bomb.cpp +++ b/SBomber/src/Bomb.cpp @@ -7,3 +7,26 @@ void Bomb::Draw() const { ScreenSingleton::getInstance().GotoXY(x, y); std::cout << "*"; } + +void BombDecorator::Move(uint16_t time) +{ + m_bomb->Move(time * 1.6); +} + +void BombDecorator::Draw() const +{ + m_bomb->Draw(); + // Некоторое изменение внешнего вида бомбы + ScreenSingleton::getInstance().GotoXY(m_bomb->GetX(), m_bomb->GetY() - 1); + std::cout << "|"; +} + +void BombDecorator::SetPos(double nx, double ny) +{ + m_bomb->SetPos(nx, ny); +} + +uint16_t BombDecorator::GetWidth() const +{ + return m_bomb->GetWidth(); +} diff --git a/SBomber/src/SBomber.cpp b/SBomber/src/SBomber.cpp index 40a93bf..92359e8 100644 --- a/SBomber/src/SBomber.cpp +++ b/SBomber/src/SBomber.cpp @@ -1,4 +1,3 @@ - #include "MyTools.h" #include "SBomber.h" #include "Bomb.h" @@ -10,302 +9,542 @@ #include #include -SBomber::SBomber() - : exitFlag(false), startTime(0), finishTime(0), deltaTime(0), passedTime(0), - fps(0), bombsNumber(10), score(0) { - MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); +#include +#include +#include +#include +#include +#include - Plane* p = new Plane; - p->SetDirection(1, 0.1); - p->SetSpeed(4); - p->SetPos(5, 10); - vecDynamicObj.push_back(p); +int _kbhit() +{ + static const int STDIN = 0; + static bool initialized = false; - LevelGUI* pGUI = new LevelGUI; - pGUI->SetParam(passedTime, fps, bombsNumber, score); - const uint16_t maxX = ScreenSingleton::getInstance().GetMaxX(); - const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); - const uint16_t offset = 3; - const uint16_t width = maxX - 7; - pGUI->SetPos(offset, offset); - pGUI->SetWidth(width); - pGUI->SetHeight(maxY - 4); - pGUI->SetFinishX(offset + width - 4); - vecStaticObj.push_back(pGUI); + if (!initialized) + { + // Use termios to turn off line buffering + termios term; + tcgetattr(STDIN, &term); + term.c_lflag &= ~ICANON; + tcsetattr(STDIN, TCSANOW, &term); + setbuf(stdin, NULL); + initialized = true; + } - Ground* pGr = new Ground; - const uint16_t groundY = maxY - 5; - pGr->SetPos(offset + 1, groundY); - pGr->SetWidth(width - 2); - vecStaticObj.push_back(pGr); - - Tank* pTank = new Tank; - pTank->SetWidth(13); - pTank->SetPos(30, groundY - 1); - vecStaticObj.push_back(pTank); - - pTank = new Tank; - pTank->SetWidth(13); - pTank->SetPos(50, groundY - 1); - vecStaticObj.push_back(pTank); - - House* pHouse = new House; - pHouse->SetWidth(13); - pHouse->SetPos(80, groundY - 1); - vecStaticObj.push_back(pHouse); - - /* - Bomb* pBomb = new Bomb; - pBomb->SetDirection(0.3, 1); - pBomb->SetSpeed(2); - pBomb->SetPos(51, 5); - pBomb->SetSize(SMALL_CRATER_SIZE); - vecDynamicObj.push_back(pBomb); - */ + int bytesWaiting; + ioctl(STDIN, FIONREAD, &bytesWaiting); + return bytesWaiting; } -SBomber::~SBomber() { - for (size_t i = 0; i < vecDynamicObj.size(); i++) { - if (vecDynamicObj[i] != nullptr) { - delete vecDynamicObj[i]; - } - } +class IFactory +{ +public: + virtual ~IFactory() {} - for (size_t i = 0; i < vecStaticObj.size(); i++) { - if (vecStaticObj[i] != nullptr) { - delete vecStaticObj[i]; + DynamicObject* createPlane() const + { + Plane *p = createPlaneInstance(); + p->SetDirection(1, 0.1); + p->SetSpeed(4); + p->SetPos(5, 10); + return p; } - } -} -void SBomber::MoveObjects() { - MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); - - for (size_t i = 0; i < vecDynamicObj.size(); i++) { - if (vecDynamicObj[i] != nullptr) { - vecDynamicObj[i]->Move(deltaTime); + DynamicObject* createBomb(const double x, const double y) const + { + Bomb *pBomb = createBombInstance(); + pBomb->SetDirection(0.3, 1); + pBomb->SetSpeed(2); + pBomb->SetPos(x, y); + pBomb->SetWidth(SMALL_CRATER_SIZE); + return pBomb; } - } + + GameObject* createUI(const uint64_t passedTime, const uint64_t fps, const uint16_t bombsNumber, const int16_t score) const + { + LevelGUI *pGUI = createUIInstance(); + pGUI->SetParam(passedTime, fps, bombsNumber, score); + const uint16_t maxX = ScreenSingleton::getInstance().GetMaxX(); + const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); + const uint16_t offset = 3; + const uint16_t width = maxX - 7; + pGUI->SetPos(offset, offset); + pGUI->SetWidth(width); + pGUI->SetHeight(maxY - 4); + pGUI->SetFinishX(offset + width - 4); + return pGUI; + } + + virtual GameObject* createHouse(double posX) const + { + const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); + const uint16_t groundY = maxY - 5; + House *pHouse = createHouseInstance(); + pHouse->SetWidth(13); + pHouse->SetPos(posX, groundY - 1); + return pHouse; + } + + virtual GameObject* createGround() const + { + const uint16_t maxX = ScreenSingleton::getInstance().GetMaxX(); + const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); + const uint16_t offset = 3; + const uint16_t width = maxX - 7; + Ground *pGr = createGroundInstance(); + const uint16_t groundY = maxY - 5; + pGr->SetPos(offset + 1, groundY); + pGr->SetWidth(width - 2); + return pGr; + } + + virtual GameObject* createTank(double posX) const + { + const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); + const uint16_t groundY = maxY - 5; + Tank *pTank = createTankInstance(); + pTank->SetWidth(13); + pTank->SetPos(posX, groundY - 1); + return pTank; + } +private: + virtual Plane* createPlaneInstance() const = 0; + virtual Bomb* createBombInstance() const = 0; + virtual LevelGUI* createUIInstance() const = 0; + virtual Ground* createGroundInstance() const = 0; + virtual Tank* createTankInstance() const = 0; + virtual House* createHouseInstance() const = 0; }; -void SBomber::CheckObjects() { - MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); +class RegularFactory : public IFactory +{ + Plane* createPlaneInstance() const override + { + return new Plane; + } - CheckPlaneAndLevelGUI(); - CheckBombsAndGround(); + Bomb* createBombInstance() const override + { + return new Bomb; + } + + LevelGUI* createUIInstance() const override + { + return new LevelGUI; + } + Ground* createGroundInstance() const override + { + return new Ground; + } + + Tank* createTankInstance() const override + { + return new Tank; + } + + House* createHouseInstance() const override + { + return new House; + } }; -void SBomber::CheckPlaneAndLevelGUI() { - if (FindPlane()->GetX() > FindLevelGUI()->GetFinishX()) { - exitFlag = true; - } -} +class Command +{ +public: + virtual ~Command() {} + virtual void Execute() = 0; +}; -void SBomber::CheckBombsAndGround() { - std::vector vecBombs = FindAllBombs(); - Ground* pGround = FindGround(); - const double y = pGround->GetY(); - for (size_t i = 0; i < vecBombs.size(); i++) { - if (vecBombs[i]->GetY() >= y) { - pGround->AddCrater(vecBombs[i]->GetX()); - CheckDestoyableObjects(vecBombs[i]); - DeleteDynamicObj(vecBombs[i]); +template +class DeleteCommand : public Command +{ +public: + DeleteCommand(std::vector& vecObj) : m_vecObj(vecObj), m_pObj(nullptr) {} + void setObj(Object *pObj) + { + m_pObj = pObj; } - } -} + void Execute() + { + if (!m_pObj) + { + return; + } -void SBomber::CheckDestoyableObjects(Bomb* pBomb) { - std::vector vecDestoyableObjects = - FindDestoyableGroundObjects(); - const double size = pBomb->GetWidth(); - const double size_2 = size / 2; - for (size_t i = 0; i < vecDestoyableObjects.size(); i++) { - const double x1 = pBomb->GetX() - size_2; - const double x2 = x1 + size; - if (vecDestoyableObjects[i]->isInside(x1, x2)) { - score += vecDestoyableObjects[i]->GetScore(); - DeleteStaticObj(vecDestoyableObjects[i]); + auto it = m_vecObj.begin(); + for (; it != m_vecObj.end(); it++) + { + if (*it == m_pObj) + { + m_vecObj.erase(it); + break; + } + } } - } -} +private: + std::vector& m_vecObj; + Object *m_pObj; +}; -void SBomber::DeleteDynamicObj(DynamicObject* pObj) { - auto it = vecDynamicObj.begin(); - for (; it != vecDynamicObj.end(); it++) { - if (*it == pObj) { - vecDynamicObj.erase(it); - break; +class DropCommand : public Command +{ +public: + DropCommand(std::vector& vecDynamicObj) : m_vecDynamicObj(vecDynamicObj), m_pPlane(nullptr), m_bombsNumber(nullptr), m_score(nullptr) {} + void setParams(Plane *pPlane, uint16_t *bombsNumber, int16_t *score) + { + m_pPlane = pPlane; + m_bombsNumber = bombsNumber; + m_score = score; } - } -} + void Execute() + { + if (*m_bombsNumber > 0) + { + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); -void SBomber::DeleteStaticObj(GameObject* pObj) { - auto it = vecStaticObj.begin(); - for (; it != vecStaticObj.end(); it++) { - if (*it == pObj) { - vecStaticObj.erase(it); - break; + double x = m_pPlane->GetX() + 4; + double y = m_pPlane->GetY() + 2; + + auto pFactory = new RegularFactory; + m_vecDynamicObj.push_back(pFactory->createBomb(x, y)); + delete pFactory; + + (*m_bombsNumber)--; + *m_score -= Bomb::BombCost; + } } - } -} +private: + std::vector& m_vecDynamicObj; + Plane *m_pPlane; + uint16_t *m_bombsNumber; + int16_t *m_score; +}; -std::vector SBomber::FindDestoyableGroundObjects() const { - std::vector vec; - Tank* pTank; - House* pHouse; - for (size_t i = 0; i < vecStaticObj.size(); i++) { - pTank = dynamic_cast(vecStaticObj[i]); - if (pTank != nullptr) { - vec.push_back(pTank); - continue; +class DropBigCommand : public Command +{ +public: + DropBigCommand(std::vector& vecDynamicObj) : m_vecDynamicObj(vecDynamicObj), m_pPlane(nullptr), m_bombsNumber(nullptr), m_score(nullptr) {} + void setParams(Plane *pPlane, uint16_t *bombsNumber, int16_t *score) + { + m_pPlane = pPlane; + m_bombsNumber = bombsNumber; + m_score = score; } + void Execute() + { + if (*m_bombsNumber > 0) + { + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); - pHouse = dynamic_cast(vecStaticObj[i]); - if (pHouse != nullptr) { - vec.push_back(pHouse); - continue; + double x = m_pPlane->GetX() + 4; + double y = m_pPlane->GetY() + 2; + + auto pFactory = new RegularFactory; + m_vecDynamicObj.push_back(new BombDecorator(pFactory->createBomb(x, y))); + delete pFactory; + + (*m_bombsNumber)--; + *m_score -= Bomb::BombCost; + } } - } +private: + std::vector& m_vecDynamicObj; + Plane *m_pPlane; + uint16_t *m_bombsNumber; + int16_t *m_score; +}; - return vec; -} - -Ground* SBomber::FindGround() const { - Ground* pGround; - - for (size_t i = 0; i < vecStaticObj.size(); i++) { - pGround = dynamic_cast(vecStaticObj[i]); - if (pGround != nullptr) { - return pGround; - } - } - - return nullptr; -} - -std::vector SBomber::FindAllBombs() const { - std::vector vecBombs; - - for (size_t i = 0; i < vecDynamicObj.size(); i++) { - Bomb* pBomb = dynamic_cast(vecDynamicObj[i]); - if (pBomb != nullptr) { - vecBombs.push_back(pBomb); - } - } - - return vecBombs; -} - -Plane* SBomber::FindPlane() const { - for (size_t i = 0; i < vecDynamicObj.size(); i++) { - Plane* p = dynamic_cast(vecDynamicObj[i]); - if (p != nullptr) { - return p; - } - } - - return nullptr; -} - -LevelGUI* SBomber::FindLevelGUI() const { - for (size_t i = 0; i < vecStaticObj.size(); i++) { - LevelGUI* p = dynamic_cast(vecStaticObj[i]); - if (p != nullptr) { - return p; - } - } - - return nullptr; -} - -void SBomber::ProcessKBHit() { - int c = getchar(); - - if (c == 224) { - c = getchar(); - } - - MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked. key = ", c); - - switch (c) { - - case 27: // esc - exitFlag = true; - break; - - case 72: // up - FindPlane()->ChangePlaneY(-0.25); - break; - - case 80: // down - FindPlane()->ChangePlaneY(0.25); - break; - - case 'b': - DropBomb(); - break; - - case 'B': - DropBomb(); - break; - - default: - break; - } -} - -void SBomber::DrawFrame() { - MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); - - for (size_t i = 0; i < vecDynamicObj.size(); i++) { - if (vecDynamicObj[i] != nullptr) { - vecDynamicObj[i]->Draw(); - } - } - - for (size_t i = 0; i < vecStaticObj.size(); i++) { - if (vecStaticObj[i] != nullptr) { - vecStaticObj[i]->Draw(); - } - } - - ScreenSingleton::getInstance().GotoXY(0, 0); - fps++; - - FindLevelGUI()->SetParam(passedTime, fps, bombsNumber, score); -} - -void SBomber::TimeStart() { - MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); - startTime = std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()).count(); -} - -void SBomber::TimeFinish() { - finishTime = std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()).count(); - deltaTime = uint16_t(finishTime - startTime); - passedTime += deltaTime; - - MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " deltaTime = ", (int)deltaTime); -} - -void SBomber::DropBomb() { - if (bombsNumber > 0) { +SBomber::SBomber() : exitFlag(false), startTime(0), finishTime(0), deltaTime(0), passedTime(0), fps(0), bombsNumber(10), score(0) +{ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); - Plane* pPlane = FindPlane(); - double x = pPlane->GetX() + 4; - double y = pPlane->GetY() + 2; + auto pFactory = new RegularFactory; - Bomb* pBomb = new Bomb; - pBomb->SetDirection(0.3, 1); - pBomb->SetSpeed(2); - pBomb->SetPos(x, y); - pBomb->SetWidth(SMALL_CRATER_SIZE); + vecDynamicObj.push_back(pFactory->createPlane()); + vecStaticObj.push_back(pFactory->createUI(passedTime, fps, bombsNumber, score)); + vecStaticObj.push_back(pFactory->createGround()); + vecStaticObj.push_back(pFactory->createTank(30)); + vecStaticObj.push_back(pFactory->createTank(50)); + vecStaticObj.push_back(pFactory->createHouse(80)); - vecDynamicObj.push_back(pBomb); - bombsNumber--; - score -= Bomb::BombCost; - } + delete pFactory; +} + +SBomber::~SBomber() +{ + for (size_t i = 0; i < vecDynamicObj.size(); i++) + { + if (vecDynamicObj[i] != nullptr) + { + delete vecDynamicObj[i]; + } + } + + for (size_t i = 0; i < vecStaticObj.size(); i++) + { + if (vecStaticObj[i] != nullptr) + { + delete vecStaticObj[i]; + } + } +} + +void SBomber::MoveObjects() +{ + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + + for (size_t i = 0; i < vecDynamicObj.size(); i++) + { + if (vecDynamicObj[i] != nullptr) + { + vecDynamicObj[i]->Move(deltaTime); + } + } +} +; + +void SBomber::CheckObjects() +{ + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + + CheckPlaneAndLevelGUI(); + CheckBombsAndGround(); +} +; + +void SBomber::CheckPlaneAndLevelGUI() +{ + if (FindPlane()->GetX() > FindLevelGUI()->GetFinishX()) + { + exitFlag = true; + } +} + +void SBomber::CheckBombsAndGround() +{ + std::vector vecBombs = FindAllBombs(); + Ground *pGround = FindGround(); + const double y = pGround->GetY(); + for (size_t i = 0; i < vecBombs.size(); i++) + { + if (vecBombs[i]->GetY() >= y) + { + pGround->AddCrater(vecBombs[i]->GetX()); + CheckDestoyableObjects(vecBombs[i]); + + DeleteCommand delCom(SBomber::vecDynamicObj); + delCom.setObj(vecBombs[i]); + delCom.Execute(); + } + } +} + +void SBomber::CheckDestoyableObjects(Bomb *pBomb) +{ + std::vector vecDestoyableObjects = FindDestoyableGroundObjects(); + const double size = pBomb->GetWidth(); + const double size_2 = size / 2; + for (size_t i = 0; i < vecDestoyableObjects.size(); i++) + { + const double x1 = pBomb->GetX() - size_2; + const double x2 = x1 + size; + if (vecDestoyableObjects[i]->isInside(x1, x2)) + { + score += vecDestoyableObjects[i]->GetScore(); + + DeleteCommand delCom(SBomber::vecStaticObj); + delCom.setObj(vecDestoyableObjects[i]); + delCom.Execute(); + } + } +} + +std::vector SBomber::FindDestoyableGroundObjects() const +{ + std::vector vec; + Tank *pTank; + House *pHouse; + for (size_t i = 0; i < vecStaticObj.size(); i++) + { + pTank = dynamic_cast(vecStaticObj[i]); + if (pTank != nullptr) + { + vec.push_back(pTank); + continue; + } + + pHouse = dynamic_cast(vecStaticObj[i]); + if (pHouse != nullptr) + { + vec.push_back(pHouse); + continue; + } + } + + return vec; +} + +Ground* SBomber::FindGround() const +{ + Ground *pGround; + + for (size_t i = 0; i < vecStaticObj.size(); i++) + { + pGround = dynamic_cast(vecStaticObj[i]); + if (pGround != nullptr) + { + return pGround; + } + } + + return nullptr; +} + +std::vector SBomber::FindAllBombs() const +{ + std::vector vecBombs; + + for (size_t i = 0; i < vecDynamicObj.size(); i++) + { + Bomb *pBomb = dynamic_cast(vecDynamicObj[i]); + if (pBomb != nullptr) + { + vecBombs.push_back(pBomb); + } + } + + return vecBombs; +} + +Plane* SBomber::FindPlane() const +{ + for (size_t i = 0; i < vecDynamicObj.size(); i++) + { + Plane *p = dynamic_cast(vecDynamicObj[i]); + if (p != nullptr) + { + return p; + } + } + + return nullptr; +} + +LevelGUI* SBomber::FindLevelGUI() const +{ + for (size_t i = 0; i < vecStaticObj.size(); i++) + { + LevelGUI *p = dynamic_cast(vecStaticObj[i]); + if (p != nullptr) + { + return p; + } + } + + return nullptr; +} + +void SBomber::ProcessKBHit() +{ + int c = getchar(); + + if (c == 224) + { + c = getchar(); + } + + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked. key = ", c); + + switch (c) + { + case 27: // esc + exitFlag = true; + break; + case 72: // up + FindPlane()->ChangePlaneY(-0.25); + break; + case 80: // down + FindPlane()->ChangePlaneY(0.25); + break; + case 'b': + { + DropCommand dropCom(SBomber::vecDynamicObj); + dropCom.setParams(FindPlane(), &bombsNumber, &score); + dropCom.Execute(); + break; + } + case 'B': + { + DropBigCommand dropCom(SBomber::vecDynamicObj); + dropCom.setParams(FindPlane(), &bombsNumber, &score); + dropCom.Execute(); + break; + } + default: + break; + } +} + +void SBomber::DrawFrame() +{ + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + + for (size_t i = 0; i < vecDynamicObj.size(); i++) + { + if (vecDynamicObj[i] != nullptr) + { + vecDynamicObj[i]->Draw(); + } + } + + for (size_t i = 0; i < vecStaticObj.size(); i++) + { + if (vecStaticObj[i] != nullptr) + { + vecStaticObj[i]->Draw(); + } + } + + ScreenSingleton::getInstance().GotoXY(0, 0); + fps++; + + FindLevelGUI()->SetParam(passedTime, fps, bombsNumber, score); +} + +void SBomber::TimeStart() +{ + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + startTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); +} + +void SBomber::TimeFinish() +{ + finishTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + deltaTime = uint16_t(finishTime - startTime); + passedTime += deltaTime; + + MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " deltaTime = ", (int) deltaTime); +} + +void SBomber::run() +{ + do + { + TimeStart(); + + if (_kbhit()) + { + ProcessKBHit(); + } + + ScreenSingleton::getInstance().ClrScr(); + + DrawFrame(); + MoveObjects(); + CheckObjects(); + + TimeFinish(); + + } while (!GetExitFlag()); } diff --git a/hw2.patch b/hw2.patch new file mode 100644 index 0000000..43b4539 --- /dev/null +++ b/hw2.patch @@ -0,0 +1,1030 @@ +diff --git a/SBomber/include/Bomb.h b/SBomber/include/Bomb.h +index d122e7a..85aef44 100644 +--- a/SBomber/include/Bomb.h ++++ b/SBomber/include/Bomb.h +@@ -6,7 +6,7 @@ class Bomb : public DynamicObject + { + public: + +- static const uint16_t BombCost = 10; // ++ static const uint16_t BombCost = 10; + + void Draw() const override; + +@@ -14,3 +14,17 @@ private: + + }; + ++class BombDecorator: public DynamicObject ++{ ++public: ++ BombDecorator(DynamicObject *bomb) : m_bomb(bomb) ++ { ++ } ++ void Move(uint16_t time) override; ++ void Draw() const override; ++ ++ void SetPos(double nx, double ny) override; ++ uint16_t GetWidth() const override; ++private: ++ DynamicObject *m_bomb; ++}; +diff --git a/SBomber/include/GameObject.h b/SBomber/include/GameObject.h +index 1d56d2e..cd7589a 100644 +--- a/SBomber/include/GameObject.h ++++ b/SBomber/include/GameObject.h +@@ -2,25 +2,41 @@ + + #include + +-class GameObject { ++class GameObject ++{ + public: +- GameObject() : x(0.0), y(0.0), width(0) {} +- virtual ~GameObject() = default; ++ GameObject() : x(0.0), y(0.0), width(0) ++ { ++ } ++ virtual ~GameObject() = default; + +- virtual void Draw() const = 0; ++ virtual void Draw() const = 0; + +- inline void SetPos(double nx, double ny) { +- x = nx; +- y = ny; +- } ++ virtual inline void SetPos(double nx, double ny) ++ { ++ x = nx; ++ y = ny; ++ } + +- inline double GetY() const { return y; } +- inline double GetX() const { return x; } ++ virtual inline double GetY() const ++ { ++ return y; ++ } ++ virtual inline double GetX() const ++ { ++ return x; ++ } + +- inline void SetWidth(uint16_t widthN) { width = widthN; } +- inline uint16_t GetWidth() const { return width; } ++ virtual inline void SetWidth(uint16_t widthN) ++ { ++ width = widthN; ++ } ++ virtual inline uint16_t GetWidth() const ++ { ++ return width; ++ } + + protected: +- double x, y; +- uint16_t width; ++ double x, y; ++ uint16_t width; + }; +diff --git a/SBomber/include/SBomber.h b/SBomber/include/SBomber.h +index 3ce1b9c..f6534f8 100644 +--- a/SBomber/include/SBomber.h ++++ b/SBomber/include/SBomber.h +@@ -11,11 +11,13 @@ + class SBomber + { + public: +- + SBomber(); + ~SBomber(); +- +- inline bool GetExitFlag() const { return exitFlag; } ++ ++ inline bool GetExitFlag() const ++ { ++ return exitFlag; ++ } + + void ProcessKBHit(); + void TimeStart(); +@@ -25,29 +27,30 @@ public: + void MoveObjects(); + void CheckObjects(); + +-private: ++ void run(); + ++private: + void CheckPlaneAndLevelGUI(); + void CheckBombsAndGround(); +- void CheckDestoyableObjects(Bomb* pBomb); ++ void CheckDestoyableObjects(Bomb *pBomb); + +- void DeleteDynamicObj(DynamicObject * pBomb); +- void DeleteStaticObj(GameObject* pObj); ++// void DeleteDynamicObj(DynamicObject *pBomb); ++// void DeleteStaticObj(GameObject *pObj); + +- Ground * FindGround() const; +- Plane * FindPlane() const; +- LevelGUI * FindLevelGUI() const; ++ Ground* FindGround() const; ++ Plane* FindPlane() const; ++ LevelGUI* FindLevelGUI() const; + std::vector FindDestoyableGroundObjects() const; + std::vector FindAllBombs() const; + +- void DropBomb(); ++// void DropBomb(); + + std::vector vecDynamicObj; + std::vector vecStaticObj; +- ++ + bool exitFlag; + + uint64_t startTime, finishTime, passedTime; + uint16_t bombsNumber, deltaTime, fps; + int16_t score; +-}; +\ No newline at end of file ++}; +diff --git a/SBomber/main.cpp b/SBomber/main.cpp +index aa0028a..9edd27d 100644 +--- a/SBomber/main.cpp ++++ b/SBomber/main.cpp +@@ -2,58 +2,12 @@ + #include "MyTools.h" + #include "ScreenSingleton.h" + +-#include +-#include +-#include +-#include +-#include +-#include +- +-int _kbhit() +-{ +- static const int STDIN = 0; +- static bool initialized = false; +- +- if (!initialized) +- { +- // Use termios to turn off line buffering +- termios term; +- tcgetattr(STDIN, &term); +- term.c_lflag &= ~ICANON; +- tcsetattr(STDIN, TCSANOW, &term); +- setbuf(stdin, NULL); +- initialized = true; +- } +- +- int bytesWaiting; +- ioctl(STDIN, FIONREAD, &bytesWaiting); +- return bytesWaiting; +-} +- + int main(void) + { + MyTools::LoggerSingleton::getInstance().OpenLogFile("log.txt"); + + SBomber game; +- +- do +- { +- game.TimeStart(); +- +- if (_kbhit()) +- { +- game.ProcessKBHit(); +- } +- +- ScreenSingleton::getInstance().ClrScr(); +- +- game.DrawFrame(); +- game.MoveObjects(); +- game.CheckObjects(); +- +- game.TimeFinish(); +- +- } while (!game.GetExitFlag()); ++ game.run(); + + MyTools::LoggerSingleton::getInstance().CloseLogFile(); + +diff --git a/SBomber/src/Bomb.cpp b/SBomber/src/Bomb.cpp +index 4bc10d4..537e917 100644 +--- a/SBomber/src/Bomb.cpp ++++ b/SBomber/src/Bomb.cpp +@@ -7,3 +7,26 @@ void Bomb::Draw() const { + ScreenSingleton::getInstance().GotoXY(x, y); + std::cout << "*"; + } ++ ++void BombDecorator::Move(uint16_t time) ++{ ++ m_bomb->Move(time * 1.6); ++} ++ ++void BombDecorator::Draw() const ++{ ++ m_bomb->Draw(); ++ // Некоторое изменение внешнего вида бомбы ++ ScreenSingleton::getInstance().GotoXY(m_bomb->GetX(), m_bomb->GetY() - 1); ++ std::cout << "|"; ++} ++ ++void BombDecorator::SetPos(double nx, double ny) ++{ ++ m_bomb->SetPos(nx, ny); ++} ++ ++uint16_t BombDecorator::GetWidth() const ++{ ++ return m_bomb->GetWidth(); ++} +diff --git a/SBomber/src/SBomber.cpp b/SBomber/src/SBomber.cpp +index 40a93bf..92359e8 100644 +--- a/SBomber/src/SBomber.cpp ++++ b/SBomber/src/SBomber.cpp +@@ -1,4 +1,3 @@ +- + #include "MyTools.h" + #include "SBomber.h" + #include "Bomb.h" +@@ -10,302 +9,542 @@ + #include + #include + +-SBomber::SBomber() +- : exitFlag(false), startTime(0), finishTime(0), deltaTime(0), passedTime(0), +- fps(0), bombsNumber(10), score(0) { +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); +- +- Plane* p = new Plane; +- p->SetDirection(1, 0.1); +- p->SetSpeed(4); +- p->SetPos(5, 10); +- vecDynamicObj.push_back(p); +- +- LevelGUI* pGUI = new LevelGUI; +- pGUI->SetParam(passedTime, fps, bombsNumber, score); +- const uint16_t maxX = ScreenSingleton::getInstance().GetMaxX(); +- const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); +- const uint16_t offset = 3; +- const uint16_t width = maxX - 7; +- pGUI->SetPos(offset, offset); +- pGUI->SetWidth(width); +- pGUI->SetHeight(maxY - 4); +- pGUI->SetFinishX(offset + width - 4); +- vecStaticObj.push_back(pGUI); +- +- Ground* pGr = new Ground; +- const uint16_t groundY = maxY - 5; +- pGr->SetPos(offset + 1, groundY); +- pGr->SetWidth(width - 2); +- vecStaticObj.push_back(pGr); +- +- Tank* pTank = new Tank; +- pTank->SetWidth(13); +- pTank->SetPos(30, groundY - 1); +- vecStaticObj.push_back(pTank); +- +- pTank = new Tank; +- pTank->SetWidth(13); +- pTank->SetPos(50, groundY - 1); +- vecStaticObj.push_back(pTank); +- +- House* pHouse = new House; +- pHouse->SetWidth(13); +- pHouse->SetPos(80, groundY - 1); +- vecStaticObj.push_back(pHouse); +- +- /* +- Bomb* pBomb = new Bomb; +- pBomb->SetDirection(0.3, 1); +- pBomb->SetSpeed(2); +- pBomb->SetPos(51, 5); +- pBomb->SetSize(SMALL_CRATER_SIZE); +- vecDynamicObj.push_back(pBomb); +- */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int _kbhit() ++{ ++ static const int STDIN = 0; ++ static bool initialized = false; ++ ++ if (!initialized) ++ { ++ // Use termios to turn off line buffering ++ termios term; ++ tcgetattr(STDIN, &term); ++ term.c_lflag &= ~ICANON; ++ tcsetattr(STDIN, TCSANOW, &term); ++ setbuf(stdin, NULL); ++ initialized = true; ++ } ++ ++ int bytesWaiting; ++ ioctl(STDIN, FIONREAD, &bytesWaiting); ++ return bytesWaiting; + } + +-SBomber::~SBomber() { +- for (size_t i = 0; i < vecDynamicObj.size(); i++) { +- if (vecDynamicObj[i] != nullptr) { +- delete vecDynamicObj[i]; ++class IFactory ++{ ++public: ++ virtual ~IFactory() {} ++ ++ DynamicObject* createPlane() const ++ { ++ Plane *p = createPlaneInstance(); ++ p->SetDirection(1, 0.1); ++ p->SetSpeed(4); ++ p->SetPos(5, 10); ++ return p; + } +- } + +- for (size_t i = 0; i < vecStaticObj.size(); i++) { +- if (vecStaticObj[i] != nullptr) { +- delete vecStaticObj[i]; ++ DynamicObject* createBomb(const double x, const double y) const ++ { ++ Bomb *pBomb = createBombInstance(); ++ pBomb->SetDirection(0.3, 1); ++ pBomb->SetSpeed(2); ++ pBomb->SetPos(x, y); ++ pBomb->SetWidth(SMALL_CRATER_SIZE); ++ return pBomb; + } +- } +-} + +-void SBomber::MoveObjects() { +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); ++ GameObject* createUI(const uint64_t passedTime, const uint64_t fps, const uint16_t bombsNumber, const int16_t score) const ++ { ++ LevelGUI *pGUI = createUIInstance(); ++ pGUI->SetParam(passedTime, fps, bombsNumber, score); ++ const uint16_t maxX = ScreenSingleton::getInstance().GetMaxX(); ++ const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); ++ const uint16_t offset = 3; ++ const uint16_t width = maxX - 7; ++ pGUI->SetPos(offset, offset); ++ pGUI->SetWidth(width); ++ pGUI->SetHeight(maxY - 4); ++ pGUI->SetFinishX(offset + width - 4); ++ return pGUI; ++ } + +- for (size_t i = 0; i < vecDynamicObj.size(); i++) { +- if (vecDynamicObj[i] != nullptr) { +- vecDynamicObj[i]->Move(deltaTime); ++ virtual GameObject* createHouse(double posX) const ++ { ++ const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); ++ const uint16_t groundY = maxY - 5; ++ House *pHouse = createHouseInstance(); ++ pHouse->SetWidth(13); ++ pHouse->SetPos(posX, groundY - 1); ++ return pHouse; + } +- } +-}; + +-void SBomber::CheckObjects() { +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); ++ virtual GameObject* createGround() const ++ { ++ const uint16_t maxX = ScreenSingleton::getInstance().GetMaxX(); ++ const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); ++ const uint16_t offset = 3; ++ const uint16_t width = maxX - 7; ++ Ground *pGr = createGroundInstance(); ++ const uint16_t groundY = maxY - 5; ++ pGr->SetPos(offset + 1, groundY); ++ pGr->SetWidth(width - 2); ++ return pGr; ++ } + +- CheckPlaneAndLevelGUI(); +- CheckBombsAndGround(); ++ virtual GameObject* createTank(double posX) const ++ { ++ const uint16_t maxY = ScreenSingleton::getInstance().GetMaxY(); ++ const uint16_t groundY = maxY - 5; ++ Tank *pTank = createTankInstance(); ++ pTank->SetWidth(13); ++ pTank->SetPos(posX, groundY - 1); ++ return pTank; ++ } ++private: ++ virtual Plane* createPlaneInstance() const = 0; ++ virtual Bomb* createBombInstance() const = 0; ++ virtual LevelGUI* createUIInstance() const = 0; ++ virtual Ground* createGroundInstance() const = 0; ++ virtual Tank* createTankInstance() const = 0; ++ virtual House* createHouseInstance() const = 0; + }; + +-void SBomber::CheckPlaneAndLevelGUI() { +- if (FindPlane()->GetX() > FindLevelGUI()->GetFinishX()) { +- exitFlag = true; +- } +-} ++class RegularFactory : public IFactory ++{ ++ Plane* createPlaneInstance() const override ++ { ++ return new Plane; ++ } + +-void SBomber::CheckBombsAndGround() { +- std::vector vecBombs = FindAllBombs(); +- Ground* pGround = FindGround(); +- const double y = pGround->GetY(); +- for (size_t i = 0; i < vecBombs.size(); i++) { +- if (vecBombs[i]->GetY() >= y) { +- pGround->AddCrater(vecBombs[i]->GetX()); +- CheckDestoyableObjects(vecBombs[i]); +- DeleteDynamicObj(vecBombs[i]); +- } +- } +-} ++ Bomb* createBombInstance() const override ++ { ++ return new Bomb; ++ } + +-void SBomber::CheckDestoyableObjects(Bomb* pBomb) { +- std::vector vecDestoyableObjects = +- FindDestoyableGroundObjects(); +- const double size = pBomb->GetWidth(); +- const double size_2 = size / 2; +- for (size_t i = 0; i < vecDestoyableObjects.size(); i++) { +- const double x1 = pBomb->GetX() - size_2; +- const double x2 = x1 + size; +- if (vecDestoyableObjects[i]->isInside(x1, x2)) { +- score += vecDestoyableObjects[i]->GetScore(); +- DeleteStaticObj(vecDestoyableObjects[i]); +- } +- } +-} ++ LevelGUI* createUIInstance() const override ++ { ++ return new LevelGUI; ++ } ++ Ground* createGroundInstance() const override ++ { ++ return new Ground; ++ } + +-void SBomber::DeleteDynamicObj(DynamicObject* pObj) { +- auto it = vecDynamicObj.begin(); +- for (; it != vecDynamicObj.end(); it++) { +- if (*it == pObj) { +- vecDynamicObj.erase(it); +- break; ++ Tank* createTankInstance() const override ++ { ++ return new Tank; + } +- } +-} + +-void SBomber::DeleteStaticObj(GameObject* pObj) { +- auto it = vecStaticObj.begin(); +- for (; it != vecStaticObj.end(); it++) { +- if (*it == pObj) { +- vecStaticObj.erase(it); +- break; ++ House* createHouseInstance() const override ++ { ++ return new House; + } +- } +-} ++}; ++ ++class Command ++{ ++public: ++ virtual ~Command() {} ++ virtual void Execute() = 0; ++}; + +-std::vector SBomber::FindDestoyableGroundObjects() const { +- std::vector vec; +- Tank* pTank; +- House* pHouse; +- for (size_t i = 0; i < vecStaticObj.size(); i++) { +- pTank = dynamic_cast(vecStaticObj[i]); +- if (pTank != nullptr) { +- vec.push_back(pTank); +- continue; ++template ++class DeleteCommand : public Command ++{ ++public: ++ DeleteCommand(std::vector& vecObj) : m_vecObj(vecObj), m_pObj(nullptr) {} ++ void setObj(Object *pObj) ++ { ++ m_pObj = pObj; ++ } ++ void Execute() ++ { ++ if (!m_pObj) ++ { ++ return; ++ } ++ ++ auto it = m_vecObj.begin(); ++ for (; it != m_vecObj.end(); it++) ++ { ++ if (*it == m_pObj) ++ { ++ m_vecObj.erase(it); ++ break; ++ } ++ } + } ++private: ++ std::vector& m_vecObj; ++ Object *m_pObj; ++}; + +- pHouse = dynamic_cast(vecStaticObj[i]); +- if (pHouse != nullptr) { +- vec.push_back(pHouse); +- continue; ++class DropCommand : public Command ++{ ++public: ++ DropCommand(std::vector& vecDynamicObj) : m_vecDynamicObj(vecDynamicObj), m_pPlane(nullptr), m_bombsNumber(nullptr), m_score(nullptr) {} ++ void setParams(Plane *pPlane, uint16_t *bombsNumber, int16_t *score) ++ { ++ m_pPlane = pPlane; ++ m_bombsNumber = bombsNumber; ++ m_score = score; ++ } ++ void Execute() ++ { ++ if (*m_bombsNumber > 0) ++ { ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); ++ ++ double x = m_pPlane->GetX() + 4; ++ double y = m_pPlane->GetY() + 2; ++ ++ auto pFactory = new RegularFactory; ++ m_vecDynamicObj.push_back(pFactory->createBomb(x, y)); ++ delete pFactory; ++ ++ (*m_bombsNumber)--; ++ *m_score -= Bomb::BombCost; ++ } + } +- } ++private: ++ std::vector& m_vecDynamicObj; ++ Plane *m_pPlane; ++ uint16_t *m_bombsNumber; ++ int16_t *m_score; ++}; + +- return vec; +-} ++class DropBigCommand : public Command ++{ ++public: ++ DropBigCommand(std::vector& vecDynamicObj) : m_vecDynamicObj(vecDynamicObj), m_pPlane(nullptr), m_bombsNumber(nullptr), m_score(nullptr) {} ++ void setParams(Plane *pPlane, uint16_t *bombsNumber, int16_t *score) ++ { ++ m_pPlane = pPlane; ++ m_bombsNumber = bombsNumber; ++ m_score = score; ++ } ++ void Execute() ++ { ++ if (*m_bombsNumber > 0) ++ { ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); ++ ++ double x = m_pPlane->GetX() + 4; ++ double y = m_pPlane->GetY() + 2; ++ ++ auto pFactory = new RegularFactory; ++ m_vecDynamicObj.push_back(new BombDecorator(pFactory->createBomb(x, y))); ++ delete pFactory; ++ ++ (*m_bombsNumber)--; ++ *m_score -= Bomb::BombCost; ++ } ++ } ++private: ++ std::vector& m_vecDynamicObj; ++ Plane *m_pPlane; ++ uint16_t *m_bombsNumber; ++ int16_t *m_score; ++}; ++ ++SBomber::SBomber() : exitFlag(false), startTime(0), finishTime(0), deltaTime(0), passedTime(0), fps(0), bombsNumber(10), score(0) ++{ ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + +-Ground* SBomber::FindGround() const { +- Ground* pGround; ++ auto pFactory = new RegularFactory; + +- for (size_t i = 0; i < vecStaticObj.size(); i++) { +- pGround = dynamic_cast(vecStaticObj[i]); +- if (pGround != nullptr) { +- return pGround; ++ vecDynamicObj.push_back(pFactory->createPlane()); ++ vecStaticObj.push_back(pFactory->createUI(passedTime, fps, bombsNumber, score)); ++ vecStaticObj.push_back(pFactory->createGround()); ++ vecStaticObj.push_back(pFactory->createTank(30)); ++ vecStaticObj.push_back(pFactory->createTank(50)); ++ vecStaticObj.push_back(pFactory->createHouse(80)); ++ ++ delete pFactory; ++} ++ ++SBomber::~SBomber() ++{ ++ for (size_t i = 0; i < vecDynamicObj.size(); i++) ++ { ++ if (vecDynamicObj[i] != nullptr) ++ { ++ delete vecDynamicObj[i]; ++ } + } +- } + +- return nullptr; ++ for (size_t i = 0; i < vecStaticObj.size(); i++) ++ { ++ if (vecStaticObj[i] != nullptr) ++ { ++ delete vecStaticObj[i]; ++ } ++ } + } + +-std::vector SBomber::FindAllBombs() const { +- std::vector vecBombs; ++void SBomber::MoveObjects() ++{ ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + +- for (size_t i = 0; i < vecDynamicObj.size(); i++) { +- Bomb* pBomb = dynamic_cast(vecDynamicObj[i]); +- if (pBomb != nullptr) { +- vecBombs.push_back(pBomb); ++ for (size_t i = 0; i < vecDynamicObj.size(); i++) ++ { ++ if (vecDynamicObj[i] != nullptr) ++ { ++ vecDynamicObj[i]->Move(deltaTime); ++ } + } +- } ++} ++; ++ ++void SBomber::CheckObjects() ++{ ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + +- return vecBombs; ++ CheckPlaneAndLevelGUI(); ++ CheckBombsAndGround(); + } ++; + +-Plane* SBomber::FindPlane() const { +- for (size_t i = 0; i < vecDynamicObj.size(); i++) { +- Plane* p = dynamic_cast(vecDynamicObj[i]); +- if (p != nullptr) { +- return p; ++void SBomber::CheckPlaneAndLevelGUI() ++{ ++ if (FindPlane()->GetX() > FindLevelGUI()->GetFinishX()) ++ { ++ exitFlag = true; + } +- } ++} + +- return nullptr; ++void SBomber::CheckBombsAndGround() ++{ ++ std::vector vecBombs = FindAllBombs(); ++ Ground *pGround = FindGround(); ++ const double y = pGround->GetY(); ++ for (size_t i = 0; i < vecBombs.size(); i++) ++ { ++ if (vecBombs[i]->GetY() >= y) ++ { ++ pGround->AddCrater(vecBombs[i]->GetX()); ++ CheckDestoyableObjects(vecBombs[i]); ++ ++ DeleteCommand delCom(SBomber::vecDynamicObj); ++ delCom.setObj(vecBombs[i]); ++ delCom.Execute(); ++ } ++ } + } + +-LevelGUI* SBomber::FindLevelGUI() const { +- for (size_t i = 0; i < vecStaticObj.size(); i++) { +- LevelGUI* p = dynamic_cast(vecStaticObj[i]); +- if (p != nullptr) { +- return p; ++void SBomber::CheckDestoyableObjects(Bomb *pBomb) ++{ ++ std::vector vecDestoyableObjects = FindDestoyableGroundObjects(); ++ const double size = pBomb->GetWidth(); ++ const double size_2 = size / 2; ++ for (size_t i = 0; i < vecDestoyableObjects.size(); i++) ++ { ++ const double x1 = pBomb->GetX() - size_2; ++ const double x2 = x1 + size; ++ if (vecDestoyableObjects[i]->isInside(x1, x2)) ++ { ++ score += vecDestoyableObjects[i]->GetScore(); ++ ++ DeleteCommand delCom(SBomber::vecStaticObj); ++ delCom.setObj(vecDestoyableObjects[i]); ++ delCom.Execute(); ++ } + } +- } ++} + +- return nullptr; ++std::vector SBomber::FindDestoyableGroundObjects() const ++{ ++ std::vector vec; ++ Tank *pTank; ++ House *pHouse; ++ for (size_t i = 0; i < vecStaticObj.size(); i++) ++ { ++ pTank = dynamic_cast(vecStaticObj[i]); ++ if (pTank != nullptr) ++ { ++ vec.push_back(pTank); ++ continue; ++ } ++ ++ pHouse = dynamic_cast(vecStaticObj[i]); ++ if (pHouse != nullptr) ++ { ++ vec.push_back(pHouse); ++ continue; ++ } ++ } ++ ++ return vec; + } + +-void SBomber::ProcessKBHit() { +- int c = getchar(); ++Ground* SBomber::FindGround() const ++{ ++ Ground *pGround; ++ ++ for (size_t i = 0; i < vecStaticObj.size(); i++) ++ { ++ pGround = dynamic_cast(vecStaticObj[i]); ++ if (pGround != nullptr) ++ { ++ return pGround; ++ } ++ } + +- if (c == 224) { +- c = getchar(); +- } ++ return nullptr; ++} + +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked. key = ", c); ++std::vector SBomber::FindAllBombs() const ++{ ++ std::vector vecBombs; ++ ++ for (size_t i = 0; i < vecDynamicObj.size(); i++) ++ { ++ Bomb *pBomb = dynamic_cast(vecDynamicObj[i]); ++ if (pBomb != nullptr) ++ { ++ vecBombs.push_back(pBomb); ++ } ++ } + +- switch (c) { ++ return vecBombs; ++} + +- case 27: // esc +- exitFlag = true; +- break; ++Plane* SBomber::FindPlane() const ++{ ++ for (size_t i = 0; i < vecDynamicObj.size(); i++) ++ { ++ Plane *p = dynamic_cast(vecDynamicObj[i]); ++ if (p != nullptr) ++ { ++ return p; ++ } ++ } + +- case 72: // up +- FindPlane()->ChangePlaneY(-0.25); +- break; ++ return nullptr; ++} + +- case 80: // down +- FindPlane()->ChangePlaneY(0.25); +- break; ++LevelGUI* SBomber::FindLevelGUI() const ++{ ++ for (size_t i = 0; i < vecStaticObj.size(); i++) ++ { ++ LevelGUI *p = dynamic_cast(vecStaticObj[i]); ++ if (p != nullptr) ++ { ++ return p; ++ } ++ } ++ ++ return nullptr; ++} + +- case 'b': +- DropBomb(); +- break; ++void SBomber::ProcessKBHit() ++{ ++ int c = getchar(); + +- case 'B': +- DropBomb(); +- break; ++ if (c == 224) ++ { ++ c = getchar(); ++ } + +- default: +- break; +- } ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked. key = ", c); ++ ++ switch (c) ++ { ++ case 27: // esc ++ exitFlag = true; ++ break; ++ case 72: // up ++ FindPlane()->ChangePlaneY(-0.25); ++ break; ++ case 80: // down ++ FindPlane()->ChangePlaneY(0.25); ++ break; ++ case 'b': ++ { ++ DropCommand dropCom(SBomber::vecDynamicObj); ++ dropCom.setParams(FindPlane(), &bombsNumber, &score); ++ dropCom.Execute(); ++ break; ++ } ++ case 'B': ++ { ++ DropBigCommand dropCom(SBomber::vecDynamicObj); ++ dropCom.setParams(FindPlane(), &bombsNumber, &score); ++ dropCom.Execute(); ++ break; ++ } ++ default: ++ break; ++ } + } + +-void SBomber::DrawFrame() { +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); ++void SBomber::DrawFrame() ++{ ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); + +- for (size_t i = 0; i < vecDynamicObj.size(); i++) { +- if (vecDynamicObj[i] != nullptr) { +- vecDynamicObj[i]->Draw(); ++ for (size_t i = 0; i < vecDynamicObj.size(); i++) ++ { ++ if (vecDynamicObj[i] != nullptr) ++ { ++ vecDynamicObj[i]->Draw(); ++ } + } +- } + +- for (size_t i = 0; i < vecStaticObj.size(); i++) { +- if (vecStaticObj[i] != nullptr) { +- vecStaticObj[i]->Draw(); ++ for (size_t i = 0; i < vecStaticObj.size(); i++) ++ { ++ if (vecStaticObj[i] != nullptr) ++ { ++ vecStaticObj[i]->Draw(); ++ } + } +- } + +- ScreenSingleton::getInstance().GotoXY(0, 0); +- fps++; ++ ScreenSingleton::getInstance().GotoXY(0, 0); ++ fps++; + +- FindLevelGUI()->SetParam(passedTime, fps, bombsNumber, score); ++ FindLevelGUI()->SetParam(passedTime, fps, bombsNumber, score); + } + +-void SBomber::TimeStart() { +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); +- startTime = std::chrono::duration_cast( +- std::chrono::high_resolution_clock::now().time_since_epoch()).count(); ++void SBomber::TimeStart() ++{ ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); ++ startTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + } + +-void SBomber::TimeFinish() { +- finishTime = std::chrono::duration_cast( +- std::chrono::high_resolution_clock::now().time_since_epoch()).count(); +- deltaTime = uint16_t(finishTime - startTime); +- passedTime += deltaTime; ++void SBomber::TimeFinish() ++{ ++ finishTime = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); ++ deltaTime = uint16_t(finishTime - startTime); ++ passedTime += deltaTime; + +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " deltaTime = ", (int)deltaTime); ++ MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " deltaTime = ", (int) deltaTime); + } + +-void SBomber::DropBomb() { +- if (bombsNumber > 0) { +- MyTools::LoggerSingleton::getInstance().WriteToLog(std::string(__func__) + " was invoked"); ++void SBomber::run() ++{ ++ do ++ { ++ TimeStart(); ++ ++ if (_kbhit()) ++ { ++ ProcessKBHit(); ++ } ++ ++ ScreenSingleton::getInstance().ClrScr(); + +- Plane* pPlane = FindPlane(); +- double x = pPlane->GetX() + 4; +- double y = pPlane->GetY() + 2; ++ DrawFrame(); ++ MoveObjects(); ++ CheckObjects(); + +- Bomb* pBomb = new Bomb; +- pBomb->SetDirection(0.3, 1); +- pBomb->SetSpeed(2); +- pBomb->SetPos(x, y); +- pBomb->SetWidth(SMALL_CRATER_SIZE); ++ TimeFinish(); + +- vecDynamicObj.push_back(pBomb); +- bombsNumber--; +- score -= Bomb::BombCost; +- } ++ } while (!GetExitFlag()); + }