#ifndef APHISICS_H_ # define APHISICS_H_ #include #include #include #include "Core/Core.hh" /* * ----- * |A|B| * ----- * |C|D| * ----- */ namespace DamnCute { class APhysics { private: bool _physicallyActive; bool _destructible; bool _destructor; unsigned int _type; QuadTree, __DQUADTREE_COMPLEXITY__>* _quadTree; QuadTree, __DQUADTREE_COMPLEXITY__>::Array_Type_ _path; std::map*, std::list::iterator> _where; template inline QuadTree, __DQUADTREE_COMPLEXITY__>::Array_Type_&& _generateQuadTreePos(unsigned int x, unsigned int y) noexcept { unsigned int nodeX = sizeX / 2; unsigned int nodeY = sizeY / 2; for (unsigned short i = 0; i < iter; ++i) { if (x < nodeX && y > nodeY) { _path[i] = QuadTree, __DQUADTREE_COMPLEXITY__>::AZone; nodeX -= nodeX / 2; nodeY += nodeY / 2; } else if (x > nodeX && y > nodeY) { _path[i] = QuadTree, __DQUADTREE_COMPLEXITY__>::BZone; nodeX += nodeX / 2; nodeY += nodeY / 2; } else if (x < nodeX && y < nodeY) { _path[i] = QuadTree, __DQUADTREE_COMPLEXITY__>::CZone; nodeX -= nodeX / 2; nodeY -= nodeY / 2; } else { _path[i] = QuadTree, __DQUADTREE_COMPLEXITY__>::DZone; nodeX += nodeX / 2; nodeY -= nodeY / 2; } } return std::move(_path); } template inline std::list, __DQUADTREE_COMPLEXITY__>::Array_Type_>&& _generateQuadTreePos(unsigned int x, unsigned int y, unsigned int w, unsigned int h) noexcept { std::list, __DQUADTREE_COMPLEXITY__>::Array_Type_> list; unsigned int quadWidth = sizeX / (2 * __DQUADTREE_COMPLEXITY__); unsigned int quadHeight = sizeY / (2 * __DQUADTREE_COMPLEXITY__); for (unsigned int i = 0; i < w; i += quadWidth) { for (unsigned int j = 0; j < h; j += quadHeight) { list.push_back(_generateQuadTreePos(x + i, y + j)); } } return std::move(list); } public: explicit APhysics(unsigned int x, unsigned int y, bool destructibility, bool destructor, unsigned int type = 0) : _physicallyActive(true), _destructible(destructibility), _destructor(destructor), _type(type), _quadTree(sCore->getQuadTree()) { _generateQuadTreePos<1920, 1080, __DQUADTREE_COMPLEXITY__>(x, y); } virtual ~APhysics() { for (std::map*, std::list::iterator>::iterator it = _where.begin(); it != _where.end(); ++it) { it->first->erase(it->second); } } inline unsigned int getType() const { return _type; } inline void setType(unsigned int id) { _type = id; } inline bool isDestructible() { return _destructible; } inline bool isDestructor() { return _destructor; } protected: virtual void collisionHandler(APhysics*) = 0; bool preciseDetection(const sf::Sprite& s1, const sf::Sprite& s2) { if (s1.getGlobalBounds().intersects(s2.getGlobalBounds())) { return true; } return false; } void updateQuadTreePos(unsigned int x, unsigned int y, unsigned int width = 1, unsigned int height = 1) { const unsigned int quadWidth = 1920 / (2 * __DQUADTREE_COMPLEXITY__); const unsigned int quadHeight = 1080 / (2 * __DQUADTREE_COMPLEXITY__); std::list* potentialDangerList; std::list::iterator whereInList; if (!_physicallyActive) return; for (std::map*, std::list::iterator>::iterator it = _where.begin(); it != _where.end(); ++it) { it->first->erase(it->second); } _where.clear(); for (unsigned int i = 0; i <= (width + quadWidth); i += quadWidth) { for (unsigned int j = 0; j <= (height + quadHeight); j += quadHeight) { _generateQuadTreePos<1920, 1080, __DQUADTREE_COMPLEXITY__>(x + i, y + j); potentialDangerList = _quadTree->getDataTreeNode(_path); if (_destructible && potentialDangerList) { for (std::list::iterator potentialDanger = potentialDangerList->begin(); potentialDanger != potentialDangerList->end(); ++potentialDanger) { if ((*potentialDanger)->isDestructor()) { collisionHandler(*potentialDanger); } } } if (!potentialDangerList) { potentialDangerList = new std::list(); _quadTree->setTreeNode(potentialDangerList, _path); } potentialDangerList->push_front(this); whereInList = potentialDangerList->begin(); _where[potentialDangerList] = whereInList; } } } }; } #endif /* !APHISICS_H_ */