| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | #include "..\e2dcollider.h"
 | 
					
						
							|  |  |  |  | #include "..\e2dnode.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | #include "..\e2dtool.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 23:04:58 +08:00
										 |  |  |  | typedef std::pair<UINT, UINT> HashPair; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 00:58:16 +08:00
										 |  |  |  | static std::vector<e2d::Listener*> s_vListeners;	// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | static e2d::Node * s_pActiveNode = nullptr;			// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD><D7B2>
 | 
					
						
							|  |  |  |  | static e2d::Node * s_pPassiveNode = nullptr;		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD><D7B2>
 | 
					
						
							|  |  |  |  | static std::set<HashPair> s_sCollisionList;			// <20><>ײӳ<D7B2><D3B3>
 | 
					
						
							| 
									
										
										
										
											2018-05-21 23:04:58 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 23:04:58 +08:00
										 |  |  |  | void e2d::Collision::addName(const String & name1, const String & name2) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	if (!name1.isEmpty() && !name2.isEmpty()) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		s_sCollisionList.insert(HashPair(name1.getHashCode(), name2.getHashCode())); | 
					
						
							| 
									
										
										
										
											2018-05-21 23:04:58 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::Collision::addName(const std::vector<std::pair<String, String> >& names) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	for (auto& name : names) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (!name.first.isEmpty() && !name.second.isEmpty()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 			s_sCollisionList.insert(HashPair(name.first.getHashCode(), name.second.getHashCode())); | 
					
						
							| 
									
										
										
										
											2018-05-21 23:04:58 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | bool e2d::Collision::isCollidable(Node * node1, Node * node2) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	return Collision::isCollidable(node1->getName(), node2->getName()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | bool e2d::Collision::isCollidable(const String & name1, const String & name2) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	UINT hashName1 = name1.getHashCode(), hashName2 = name2.getHashCode(); | 
					
						
							|  |  |  |  | 	HashPair pair1 = HashPair(hashName1, hashName2), pair2 = HashPair(hashName2, hashName1); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	for (auto& pair : s_sCollisionList) | 
					
						
							| 
									
										
										
										
											2018-05-21 23:04:58 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (pair == pair1 || pair == pair2) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			return true; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return false; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::Node * e2d::Collision::getActiveNode() | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	return s_pActiveNode; | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::Node * e2d::Collision::getPassiveNode() | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	return s_pPassiveNode; | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-26 14:06:07 +08:00
										 |  |  |  | bool e2d::Collision::isCausedBy(const String & name1, const String & name2) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	String activeName = s_pActiveNode->getName(); | 
					
						
							|  |  |  |  | 	String passiveName = s_pPassiveNode->getName(); | 
					
						
							|  |  |  |  | 	return (activeName == name1 && passiveName == name2) || | 
					
						
							|  |  |  |  | 		(activeName == name2 && passiveName == name1); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | bool e2d::Collision::isCausedBy(Node * node1, Node * node2) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	return (s_pActiveNode == node1 && s_pPassiveNode == node2) || | 
					
						
							|  |  |  |  | 		(s_pActiveNode == node2 && s_pPassiveNode == node1); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | e2d::Node* e2d::Collision::isCausedBy(Node * node) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	if (s_pActiveNode == node) | 
					
						
							|  |  |  |  | 		return s_pPassiveNode; | 
					
						
							|  |  |  |  | 	if (s_pPassiveNode == node) | 
					
						
							|  |  |  |  | 		return s_pActiveNode; | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | 	return nullptr; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::Node* e2d::Collision::isCausedBy(const String& name) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	if (s_pActiveNode->getName() == name) | 
					
						
							|  |  |  |  | 		return s_pActiveNode; | 
					
						
							|  |  |  |  | 	if (s_pPassiveNode->getName() == name) | 
					
						
							|  |  |  |  | 		return s_pPassiveNode; | 
					
						
							| 
									
										
										
										
											2018-05-19 00:36:32 +08:00
										 |  |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::Collision::__update(Node * active, Node * passive) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-03 01:49:20 +08:00
										 |  |  |  | 	if (s_vListeners.empty() || Game::getInstance()->isPaused()) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	s_pActiveNode = active; | 
					
						
							|  |  |  |  | 	s_pPassiveNode = passive; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for (size_t i = 0; i < s_vListeners.size(); ++i) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		auto listener = s_vListeners[i]; | 
					
						
							|  |  |  |  | 		// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ<CDA3>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-05-22 00:36:03 +08:00
										 |  |  |  | 		if (listener->_stopped) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-07-06 00:47:50 +08:00
										 |  |  |  | 			GC::safeRelease(listener); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 			s_vListeners.erase(s_vListeners.begin() + i); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		else | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | 			listener->_update(); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 			++i; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	s_pActiveNode = nullptr; | 
					
						
							|  |  |  |  | 	s_pPassiveNode = nullptr; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 21:21:04 +08:00
										 |  |  |  | e2d::Listener * e2d::Collision::addListener(const Function& func, const String& name, bool paused) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-06 12:59:32 +08:00
										 |  |  |  | 	auto listener = new (e2d::autorelease) Listener(func, name, paused); | 
					
						
							| 
									
										
										
										
											2018-07-06 00:47:50 +08:00
										 |  |  |  | 	listener->retain(); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	s_vListeners.push_back(listener); | 
					
						
							| 
									
										
										
										
											2018-05-22 21:21:04 +08:00
										 |  |  |  | 	return listener; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::Collision::addListener(Listener * listener) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	if (listener) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); | 
					
						
							|  |  |  |  | 		if (iter == s_vListeners.end()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-07-06 00:47:50 +08:00
										 |  |  |  | 			listener->retain(); | 
					
						
							| 
									
										
										
										
											2018-05-22 21:21:04 +08:00
										 |  |  |  | 			s_vListeners.push_back(listener); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::Collision::removeListener(Listener * listener) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	if (listener) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		auto iter = std::find(s_vListeners.begin(), s_vListeners.end(), listener); | 
					
						
							|  |  |  |  | 		if (iter != s_vListeners.end()) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-07-06 00:47:50 +08:00
										 |  |  |  | 			GC::safeRelease(listener); | 
					
						
							| 
									
										
										
										
											2018-05-22 21:21:04 +08:00
										 |  |  |  | 			s_vListeners.erase(iter); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | void e2d::Collision::stopListener(const String& name) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | 	if (s_vListeners.empty() || name.isEmpty()) | 
					
						
							|  |  |  |  | 		return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for (auto listener : s_vListeners) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-22 00:36:03 +08:00
										 |  |  |  | 		if (listener->_name == name) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | 			listener->stop(); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | void e2d::Collision::startListener(const String& name) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | 	if (s_vListeners.empty() || name.isEmpty()) | 
					
						
							|  |  |  |  | 		return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for (auto listener : s_vListeners) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-22 00:36:03 +08:00
										 |  |  |  | 		if (listener->_name == name) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | 			listener->start(); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 21:21:04 +08:00
										 |  |  |  | void e2d::Collision::removeListener(const String& name) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | 	if (s_vListeners.empty() || name.isEmpty()) | 
					
						
							|  |  |  |  | 		return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	for (auto listener : s_vListeners) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-22 00:36:03 +08:00
										 |  |  |  | 		if (listener->_name == name) | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-05-22 00:36:03 +08:00
										 |  |  |  | 			listener->_stopped = true; | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | void e2d::Collision::stopAllListeners() | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | 	for (auto listener : s_vListeners) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | 		listener->stop(); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | void e2d::Collision::startAllListeners() | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | 	for (auto listener : s_vListeners) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-22 15:54:01 +08:00
										 |  |  |  | 		listener->start(); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 21:21:04 +08:00
										 |  |  |  | void e2d::Collision::removeAllListeners() | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | 	for (auto listener : s_vListeners) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-07-05 22:05:23 +08:00
										 |  |  |  | 		listener->_stopped = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void e2d::Collision::clearAllListeners() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 	for (auto listener : s_vListeners) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		listener->release(); | 
					
						
							| 
									
										
										
										
											2018-05-22 00:11:57 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 	s_vListeners.clear(); | 
					
						
							| 
									
										
										
										
											2018-07-05 16:34:53 +08:00
										 |  |  |  | } |