2018-05-19 00:36:32 +08:00
|
|
|
|
#include "..\e2dcollider.h"
|
|
|
|
|
|
#include "..\e2dnode.h"
|
|
|
|
|
|
|
2018-05-21 23:04:58 +08:00
|
|
|
|
typedef std::pair<UINT, UINT> HashPair;
|
|
|
|
|
|
|
2018-05-22 00:11:57 +08:00
|
|
|
|
static e2d::Node * s_pActiveNode = nullptr;
|
|
|
|
|
|
static e2d::Node * s_pPassiveNode = nullptr;
|
|
|
|
|
|
static std::set<HashPair> s_sCollisionList;
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
class Listener
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
Listener(
|
|
|
|
|
|
const e2d::Function& func,
|
|
|
|
|
|
const e2d::String& name,
|
|
|
|
|
|
bool paused
|
|
|
|
|
|
)
|
|
|
|
|
|
: name(name)
|
|
|
|
|
|
, callback(func)
|
|
|
|
|
|
, running(!paused)
|
|
|
|
|
|
, stopped(false)
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>״̬
|
|
|
|
|
|
virtual void update()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (callback)
|
|
|
|
|
|
{
|
|
|
|
|
|
callback();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
bool running;
|
|
|
|
|
|
bool stopped;
|
|
|
|
|
|
e2d::String name;
|
|
|
|
|
|
e2d::Function callback;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
static std::vector<Listener*> s_vListeners;
|
|
|
|
|
|
// <20><>ײ<EFBFBD><D7B2><EFBFBD><EFBFBD>״̬
|
|
|
|
|
|
static bool s_bCollisionEnable = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::setEnable(bool enable)
|
|
|
|
|
|
{
|
|
|
|
|
|
s_bCollisionEnable = enable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool e2d::Collision::isEnable()
|
|
|
|
|
|
{
|
|
|
|
|
|
return s_bCollisionEnable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::__update(Node * active, Node * passive)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || Game::isPaused())
|
|
|
|
|
|
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>
|
|
|
|
|
|
if (listener->stopped)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete listener;
|
|
|
|
|
|
s_vListeners.erase(s_vListeners.begin() + i);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
listener->update();
|
|
|
|
|
|
++i;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s_pActiveNode = nullptr;
|
|
|
|
|
|
s_pPassiveNode = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::addListener(const Function& func, const String& name, bool paused)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto listener = new (std::nothrow) Listener(func, name, paused);
|
|
|
|
|
|
s_vListeners.push_back(listener);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::pause(const String& name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || name.isEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (listener->name == name)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->running = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::resume(const String& name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || name.isEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (listener->name == name)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->running = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::stop(const String& name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_vListeners.empty() || name.isEmpty())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (listener->name == name)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->stopped = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::pauseAll()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->running = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::resumeAll()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->running = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::stopAll()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
listener->stopped = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void e2d::Collision::__uninit()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto listener : s_vListeners)
|
|
|
|
|
|
{
|
|
|
|
|
|
delete listener;
|
|
|
|
|
|
}
|
|
|
|
|
|
s_vListeners.clear();
|
2018-05-19 00:36:32 +08:00
|
|
|
|
}
|