127 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| #include "..\e2dmanager.h"
 | |
| #include "..\e2dnode.h"
 | |
| #include "..\e2dtool.h"
 | |
| #include "..\e2dmodule.h"
 | |
| 
 | |
| 
 | |
| e2d::CollisionManager * e2d::CollisionManager::GetInstance()
 | |
| {
 | |
| 	static CollisionManager instance;
 | |
| 	return &instance;
 | |
| }
 | |
| 
 | |
| e2d::CollisionManager::CollisionManager()
 | |
| 	: collision_enabled_(false)
 | |
| {
 | |
| }
 | |
| 
 | |
| e2d::CollisionManager::~CollisionManager()
 | |
| {
 | |
| }
 | |
| 
 | |
| void e2d::CollisionManager::AddCollider(Collider * collider)
 | |
| {
 | |
| 	colliders_.push_back(collider);
 | |
| }
 | |
| 
 | |
| void e2d::CollisionManager::RemoveCollider(Collider * collider)
 | |
| {
 | |
| 	auto iter = std::find(colliders_.begin(), colliders_.end(), collider);
 | |
| 	if (iter != colliders_.end())
 | |
| 	{
 | |
| 		colliders_.erase(iter);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void e2d::CollisionManager::UpdateCollider(Collider* active)
 | |
| {
 | |
| 	if (!collision_enabled_ ||
 | |
| 		Game::GetInstance()->IsTransitioning())
 | |
| 		return;
 | |
| 
 | |
| 	auto currScene = Game::GetInstance()->GetCurrentScene();
 | |
| 	if (active->GetNode()->GetParentScene() != currScene)
 | |
| 		return;
 | |
| 
 | |
| 	std::vector<Collider*> currColliders;
 | |
| 	currColliders.reserve(colliders_.size());
 | |
| 	std::copy_if(
 | |
| 		colliders_.begin(),
 | |
| 		colliders_.end(),
 | |
| 		std::back_inserter(currColliders),
 | |
| 		[this, active, currScene](Collider* passive) -> bool
 | |
| 		{
 | |
| 			return active != passive &&
 | |
| 				passive->GetNode()->IsVisible() &&
 | |
| 				passive->GetNode()->GetParentScene() == currScene &&
 | |
| 				this->IsCollidable(active->GetNode(), passive->GetNode());
 | |
| 		}
 | |
| 	);
 | |
| 
 | |
| 	for (const auto& passive : currColliders)
 | |
| 	{
 | |
| 		// 判断两碰撞体交集情况
 | |
| 		Collider::Relation relation = active->GetRelationWith(passive);
 | |
| 		// 忽略 UNKNOWN 和 DISJOIN 情况
 | |
| 		if (relation != Collider::Relation::Unknown &&
 | |
| 			relation != Collider::Relation::Disjoin)
 | |
| 		{
 | |
| 			auto activeNode = active->GetNode();
 | |
| 			auto passiveNode = passive->GetNode();
 | |
| 			// 触发两次碰撞事件
 | |
| 			Collision activeCollision(passiveNode, relation);
 | |
| 			if (dynamic_cast<CollisionHandler*>(activeNode))
 | |
| 				dynamic_cast<CollisionHandler*>(activeNode)->Handle(activeCollision);
 | |
| 
 | |
| 			Collision passiveCollision(activeNode, passive->GetRelationWith(active));
 | |
| 			if (dynamic_cast<CollisionHandler*>(passiveNode))
 | |
| 				dynamic_cast<CollisionHandler*>(passiveNode)->Handle(passiveCollision);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void e2d::CollisionManager::SetCollisionEnabled(bool enabled)
 | |
| {
 | |
| 	collision_enabled_ = enabled;
 | |
| }
 | |
| 
 | |
| void e2d::CollisionManager::AddName(const String & name1, const String & name2)
 | |
| {
 | |
| 	if (!name1.IsEmpty() && !name2.IsEmpty())
 | |
| 	{
 | |
| 		collision_list_.insert(std::make_pair(name1.GetHash(), name2.GetHash()));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void e2d::CollisionManager::AddName(const std::vector<std::pair<String, String> >& names)
 | |
| {
 | |
| 	for (const auto& name : names)
 | |
| 	{
 | |
| 		if (!name.first.IsEmpty() && !name.second.IsEmpty())
 | |
| 		{
 | |
| 			collision_list_.insert(std::make_pair(name.first.GetHash(), name.second.GetHash()));
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| bool e2d::CollisionManager::IsCollidable(Node * node1, Node * node2)
 | |
| {
 | |
| 	return CollisionManager::IsCollidable(node1->GetName(), node2->GetName());
 | |
| }
 | |
| 
 | |
| bool e2d::CollisionManager::IsCollidable(const String & name1, const String & name2)
 | |
| {
 | |
| 	size_t hashName1 = name1.GetHash(), 
 | |
| 		hashName2 = name2.GetHash();
 | |
| 	auto pair1 = std::make_pair(hashName1, hashName2), 
 | |
| 		pair2 = std::make_pair(hashName2, hashName1);
 | |
| 	for (const auto& pair : collision_list_)
 | |
| 	{
 | |
| 		if (pair == pair1 || pair == pair2)
 | |
| 		{
 | |
| 			return true;
 | |
| 		}
 | |
| 	}
 | |
| 	return false;
 | |
| }
 |