Magic_Game/core/Manager/CollisionManager.cpp

126 lines
3.1 KiB
C++
Raw Normal View History

#include "..\e2dmanager.h"
#include "..\e2dnode.h"
#include "..\e2dtool.h"
2018-09-04 22:42:34 +08:00
e2d::CollisionManager * e2d::CollisionManager::GetInstance()
{
2018-08-19 15:11:20 +08:00
static CollisionManager instance;
return &instance;
}
e2d::CollisionManager::CollisionManager()
2018-09-04 22:42:34 +08:00
: collision_enabled_(false)
{
}
e2d::CollisionManager::~CollisionManager()
{
}
2018-09-04 22:42:34 +08:00
void e2d::CollisionManager::AddCollider(Collider * collider)
{
2018-09-04 22:42:34 +08:00
colliders_.push_back(collider);
}
2018-09-04 22:42:34 +08:00
void e2d::CollisionManager::RemoveCollider(Collider * collider)
{
2018-09-04 22:42:34 +08:00
auto iter = std::find(colliders_.begin(), colliders_.end(), collider);
if (iter != colliders_.end())
{
2018-09-04 22:42:34 +08:00
colliders_.erase(iter);
}
}
2018-09-04 22:42:34 +08:00
void e2d::CollisionManager::UpdateCollider(Collider* active)
{
2018-09-04 22:42:34 +08:00
if (!collision_enabled_ ||
Game::GetInstance()->IsTransitioning())
return;
2018-09-04 22:42:34 +08:00
auto currScene = Game::GetInstance()->GetCurrentScene();
if (active->GetNode()->GetParentScene() != currScene)
2018-08-28 00:06:10 +08:00
return;
2018-08-12 15:38:02 +08:00
std::vector<Collider*> currColliders;
2018-09-04 22:42:34 +08:00
currColliders.reserve(colliders_.size());
2018-08-12 15:38:02 +08:00
std::copy_if(
2018-09-04 22:42:34 +08:00
colliders_.begin(),
colliders_.end(),
2018-08-12 15:38:02 +08:00
std::back_inserter(currColliders),
2018-08-28 00:06:10 +08:00
[this, active, currScene](Collider* passive) -> bool
2018-07-13 00:45:39 +08:00
{
2018-08-28 00:06:10 +08:00
return active != passive &&
2018-09-04 22:42:34 +08:00
passive->GetNode()->IsVisible() &&
passive->GetNode()->GetParentScene() == currScene &&
this->IsCollidable(active->GetNode(), passive->GetNode());
2018-07-13 00:45:39 +08:00
}
2018-08-12 15:38:02 +08:00
);
2018-07-13 00:45:39 +08:00
2018-08-12 15:38:02 +08:00
for (const auto& passive : currColliders)
{
2018-07-13 00:45:39 +08:00
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD><EFBFBD><E5BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2018-09-04 22:42:34 +08:00
Collider::Relation relation = active->GetRelationWith(passive);
2018-07-13 00:45:39 +08:00
// <20><><EFBFBD><EFBFBD> UNKNOWN <20><> DISJOIN <20><><EFBFBD><EFBFBD>
if (relation != Collider::Relation::Unknown &&
relation != Collider::Relation::Disjoin)
{
2018-09-04 22:42:34 +08:00
auto activeNode = active->GetNode();
auto passiveNode = passive->GetNode();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD>¼<EFBFBD>
2018-08-12 15:38:02 +08:00
Collision activeCollision(passiveNode, relation);
2018-08-19 17:46:37 +08:00
if (dynamic_cast<CollisionHandler*>(activeNode))
2018-09-04 22:42:34 +08:00
dynamic_cast<CollisionHandler*>(activeNode)->Handle(activeCollision);
2018-09-04 22:42:34 +08:00
Collision passiveCollision(activeNode, passive->GetRelationWith(active));
2018-08-19 17:46:37 +08:00
if (dynamic_cast<CollisionHandler*>(passiveNode))
2018-09-04 22:42:34 +08:00
dynamic_cast<CollisionHandler*>(passiveNode)->Handle(passiveCollision);
}
}
}
2018-09-04 22:42:34 +08:00
void e2d::CollisionManager::SetCollisionEnabled(bool enabled)
2018-08-19 15:11:20 +08:00
{
2018-09-04 22:42:34 +08:00
collision_enabled_ = enabled;
2018-08-19 15:11:20 +08:00
}
2018-09-04 22:42:34 +08:00
void e2d::CollisionManager::AddName(const String & name1, const String & name2)
{
2018-09-04 22:42:34 +08:00
if (!name1.IsEmpty() && !name2.IsEmpty())
{
2018-09-04 22:42:34 +08:00
collision_list_.insert(std::make_pair(name1.GetHash(), name2.GetHash()));
}
}
2018-09-04 22:42:34 +08:00
void e2d::CollisionManager::AddName(const std::vector<std::pair<String, String> >& names)
{
2018-08-12 14:30:28 +08:00
for (const auto& name : names)
{
2018-09-04 22:42:34 +08:00
if (!name.first.IsEmpty() && !name.second.IsEmpty())
{
2018-09-04 22:42:34 +08:00
collision_list_.insert(std::make_pair(name.first.GetHash(), name.second.GetHash()));
}
}
}
2018-09-04 22:42:34 +08:00
bool e2d::CollisionManager::IsCollidable(Node * node1, Node * node2)
{
2018-09-04 22:42:34 +08:00
return CollisionManager::IsCollidable(node1->GetName(), node2->GetName());
}
2018-09-04 22:42:34 +08:00
bool e2d::CollisionManager::IsCollidable(const String & name1, const String & name2)
{
2018-09-04 22:42:34 +08:00
size_t hashName1 = name1.GetHash(),
hashName2 = name2.GetHash();
2018-07-13 00:45:39 +08:00
auto pair1 = std::make_pair(hashName1, hashName2),
pair2 = std::make_pair(hashName2, hashName1);
2018-09-04 22:42:34 +08:00
for (const auto& pair : collision_list_)
{
if (pair == pair1 || pair == pair2)
{
return true;
}
}
return false;
}