| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | #include "..\e2dmanager.h"
 | 
					
						
							|  |  |  |  | #include "..\e2dnode.h"
 | 
					
						
							|  |  |  |  | #include "..\e2dtool.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::CollisionManager * e2d::CollisionManager::_instance = nullptr; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::CollisionManager * e2d::CollisionManager::getInstance() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	if (!_instance) | 
					
						
							|  |  |  |  | 		_instance = new (std::nothrow) CollisionManager; | 
					
						
							|  |  |  |  | 	return _instance; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::CollisionManager::destroyInstance() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	if (_instance) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		delete _instance; | 
					
						
							|  |  |  |  | 		_instance = nullptr; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::CollisionManager::CollisionManager() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::CollisionManager::~CollisionManager() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | void e2d::CollisionManager::__addCollider(Collider * collider) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	_colliders.push_back(collider); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | void e2d::CollisionManager::__removeCollider(Collider * collider) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	auto iter = std::find(_colliders.begin(), _colliders.end(), collider); | 
					
						
							|  |  |  |  | 	if (iter != _colliders.end()) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		_colliders.erase(iter); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | void e2d::CollisionManager::__updateCollider(Collider* collider) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | 	if (Game::getInstance()->isPaused() || | 
					
						
							| 
									
										
										
										
											2018-07-24 12:49:32 +08:00
										 |  |  |  | 		!Game::getInstance()->getConfig().isCollisionEnabled() || | 
					
						
							| 
									
										
										
										
											2018-07-26 21:43:47 +08:00
										 |  |  |  | 		SceneManager::getInstance()->isTransitioning()) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	for (size_t i = 0; i < _colliders.size(); i++) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD><D7B2><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		auto active = collider->getNode(); | 
					
						
							|  |  |  |  | 		auto passive = _colliders[i]->getNode(); | 
					
						
							|  |  |  |  | 		// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><E0BBA5>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		if (active == passive || | 
					
						
							|  |  |  |  | 			active->getParentScene() != passive->getParentScene() || | 
					
						
							|  |  |  |  | 			!CollisionManager::isCollidable(active, passive)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			continue; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD>彻<EFBFBD><E5BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		Collider::Relation relation = active->getCollider()->getRelationWith(passive->getCollider()); | 
					
						
							|  |  |  |  | 		// <20><><EFBFBD><EFBFBD> UNKNOWN <20><> DISJOIN <20><><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		if (relation != Collider::Relation::Unknown && | 
					
						
							|  |  |  |  | 			relation != Collider::Relation::Disjoin) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-07-17 14:08:03 +08:00
										 |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD>¼<EFBFBD>
 | 
					
						
							|  |  |  |  | 			Collision activeCollision(passive, relation); | 
					
						
							|  |  |  |  | 			active->getParentScene()->onCollision(activeCollision); | 
					
						
							|  |  |  |  | 			active->onCollision(activeCollision); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			Collision passiveCollision(active, passive->getCollider()->getRelationWith(active->getCollider())); | 
					
						
							|  |  |  |  | 			passive->getParentScene()->onCollision(passiveCollision); | 
					
						
							|  |  |  |  | 			passive->onCollision(passiveCollision); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::CollisionManager::addName(const String & name1, const String & name2) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	if (!name1.isEmpty() && !name2.isEmpty()) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		_collisionList.insert(std::make_pair(name1.getHashCode(), name2.getHashCode())); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::CollisionManager::addName(const std::vector<std::pair<String, String> >& names) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	for (auto& name : names) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (!name.first.isEmpty() && !name.second.isEmpty()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 			_collisionList.insert(std::make_pair(name.first.getHashCode(), name.second.getHashCode())); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 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) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-16 22:11:27 +08:00
										 |  |  |  | 	size_t hashName1 = name1.getHashCode(),  | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		hashName2 = name2.getHashCode(); | 
					
						
							|  |  |  |  | 	auto pair1 = std::make_pair(hashName1, hashName2),  | 
					
						
							|  |  |  |  | 		pair2 = std::make_pair(hashName2, hashName1); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	for (auto& pair : _collisionList) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (pair == pair1 || pair == pair2) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			return true; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return false; | 
					
						
							|  |  |  |  | } |