碰撞监听器移动到Collision类中

This commit is contained in:
Nomango 2018-05-22 00:11:57 +08:00
parent 198ff09eaa
commit 432a0150b9
9 changed files with 309 additions and 257 deletions

View File

@ -1,6 +1,7 @@
#include "..\e2dbase.h"
#include "..\e2dmanager.h"
#include "..\e2dtool.h"
#include "..\e2dcollider.h"
// 控制游戏终止
@ -198,9 +199,10 @@ void e2d::Game::destroy()
{
// 删除所有场景
SceneManager::__uninit();
// 删除监听器
// 删除输入监听器
InputManager::__uninit();
ColliderManager::__uninit();
// 删除碰撞监听器
Collision::__uninit();
// 删除动作
ActionManager::__uninit();
// 回收音乐播放器资源

View File

@ -3,16 +3,16 @@
typedef std::pair<UINT, UINT> HashPair;
e2d::Node * e2d::Collision::__activeNode = nullptr;
e2d::Node * e2d::Collision::__passiveNode = nullptr;
static std::set<HashPair> __collisionList;
static e2d::Node * s_pActiveNode = nullptr;
static e2d::Node * s_pPassiveNode = nullptr;
static std::set<HashPair> s_sCollisionList;
void e2d::Collision::addName(const String & name1, const String & name2)
{
if (!name1.isEmpty() && !name2.isEmpty())
{
__collisionList.insert(HashPair(name1.getHashCode(), name2.getHashCode()));
s_sCollisionList.insert(HashPair(name1.getHashCode(), name2.getHashCode()));
}
}
@ -22,7 +22,7 @@ void e2d::Collision::addName(const std::vector<std::pair<String, String> >& name
{
if (!name.first.isEmpty() && !name.second.isEmpty())
{
__collisionList.insert(HashPair(name.first.getHashCode(), name.second.getHashCode()));
s_sCollisionList.insert(HashPair(name.first.getHashCode(), name.second.getHashCode()));
}
}
}
@ -36,7 +36,7 @@ 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);
for (auto& pair : __collisionList)
for (auto& pair : s_sCollisionList)
{
if (pair == pair1 || pair == pair2)
{
@ -48,28 +48,188 @@ bool e2d::Collision::isCollidable(const String & name1, const String & name2)
e2d::Node * e2d::Collision::getActiveNode()
{
return __activeNode;
return s_pActiveNode;
}
e2d::Node * e2d::Collision::getPassiveNode()
{
return __passiveNode;
return s_pPassiveNode;
}
e2d::Node* e2d::Collision::isCausedBy(Node * node)
{
if (__activeNode == node)
return __passiveNode;
if (__passiveNode == node)
return __activeNode;
if (s_pActiveNode == node)
return s_pPassiveNode;
if (s_pPassiveNode == node)
return s_pActiveNode;
return nullptr;
}
e2d::Node* e2d::Collision::isCausedBy(const String& name)
{
if (__activeNode->getName() == name)
return __activeNode;
if (__passiveNode->getName() == name)
return __passiveNode;
if (s_pActiveNode->getName() == name)
return s_pActiveNode;
if (s_pPassiveNode->getName() == name)
return s_pPassiveNode;
return nullptr;
}
// 监听器
class Listener
{
public:
Listener(
const e2d::Function& func,
const e2d::String& name,
bool paused
)
: name(name)
, callback(func)
, running(!paused)
, stopped(false)
{
}
// 更新监听器状态
virtual void update()
{
if (callback)
{
callback();
}
}
public:
bool running;
bool stopped;
e2d::String name;
e2d::Function callback;
};
// 监听器容器
static std::vector<Listener*> s_vListeners;
// 碰撞触发状态
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];
// 清除已停止的监听器
if (listener->stopped)
{
delete listener;
s_vListeners.erase(s_vListeners.begin() + i);
}
else
{
// 更新监听器
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();
}

View File

@ -43,6 +43,9 @@ void e2d::ActionManager::__add(Action * action)
void e2d::ActionManager::__remove(Action * action)
{
if (s_vActions.empty() || action == nullptr)
return;
auto iter = std::find(s_vActions.begin(), s_vActions.end(), action);
if (iter != s_vActions.end())
{
@ -52,42 +55,42 @@ void e2d::ActionManager::__remove(Action * action)
void e2d::ActionManager::__resumeAllBindedWith(Node * target)
{
if (target)
if (s_vRunningActions.empty() || target == nullptr)
return;
for (auto action : s_vRunningActions)
{
for (auto action : s_vRunningActions)
if (action->getTarget() == target)
{
if (action->getTarget() == target)
{
action->resume();
}
action->resume();
}
}
}
void e2d::ActionManager::__pauseAllBindedWith(Node * target)
{
if (target)
if (s_vRunningActions.empty() || target == nullptr)
return;
for (auto action : s_vRunningActions)
{
for (auto action : s_vRunningActions)
if (action->getTarget() == target)
{
if (action->getTarget() == target)
{
action->pause();
}
action->pause();
}
}
}
void e2d::ActionManager::__stopAllBindedWith(Node * target)
{
if (target)
if (s_vRunningActions.empty() || target == nullptr)
return;
for (auto action : s_vRunningActions)
{
for (auto action : s_vRunningActions)
if (action->getTarget() == target)
{
if (action->getTarget() == target)
{
action->stop();
}
action->stop();
}
}
}
@ -109,33 +112,42 @@ void e2d::ActionManager::start(Action * action, Node * target, bool paused)
}
}
void e2d::ActionManager::resume(const String& strActionName)
void e2d::ActionManager::resume(const String& name)
{
if (s_vRunningActions.empty() || name.isEmpty())
return;
for (auto action : s_vRunningActions)
{
if (action->getName() == strActionName)
if (action->getName() == name)
{
action->resume();
}
}
}
void e2d::ActionManager::pause(const String& strActionName)
void e2d::ActionManager::pause(const String& name)
{
if (s_vRunningActions.empty() || name.isEmpty())
return;
for (auto action : s_vRunningActions)
{
if (action->getName() == strActionName)
if (action->getName() == name)
{
action->pause();
}
}
}
void e2d::ActionManager::stop(const String& strActionName)
void e2d::ActionManager::stop(const String& name)
{
if (s_vRunningActions.empty() || name.isEmpty())
return;
for (auto action : s_vRunningActions)
{
if (action->getName() == strActionName)
if (action->getName() == name)
{
action->stop();
}
@ -196,12 +208,12 @@ void e2d::ActionManager::stopAll()
}
}
std::vector<e2d::Action*> e2d::ActionManager::get(const String& strActionName)
std::vector<e2d::Action*> e2d::ActionManager::get(const String& name)
{
std::vector<Action*> actions;
for (auto action : s_vActions)
{
if (action->getName() == strActionName)
if (action->getName() == name)
{
actions.push_back(action);
}

View File

@ -3,79 +3,14 @@
#include "..\e2dcollider.h"
#include "..\e2dtool.h"
// 监听器
class Listener
{
public:
Listener(
const e2d::Function& func,
const e2d::String& name,
bool paused
)
: name(name)
, callback(func)
, running(!paused)
, stopped(false)
{
}
// 更新监听器状态
virtual void update()
{
if (callback)
{
callback();
}
}
public:
bool running;
bool stopped;
e2d::String name;
e2d::Function callback;
};
// 碰撞体集合
static std::vector<e2d::Collider*> s_vColliders;
// 监听器容器
static std::vector<Listener*> s_vListeners;
// 碰撞触发状态
static bool s_bCollisionEnable = false;
void e2d::ColliderManager::setEnable(bool enable)
{
s_bCollisionEnable = enable;
}
void e2d::ColliderManager::__update()
{
if (s_vListeners.empty() || Game::isPaused())
return;
for (size_t i = 0; i < s_vListeners.size(); ++i)
{
auto listener = s_vListeners[i];
// 清除已停止的监听器
if (listener->stopped)
{
delete listener;
s_vListeners.erase(s_vListeners.begin() + i);
}
else
{
// 更新监听器
listener->update();
++i;
}
}
}
void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
{
// 判断碰撞触发是否打开
if (!s_bCollisionEnable)
if (!Collision::isEnable())
return;
Node* pActiveNode = pActiveCollider->_parentNode;
@ -106,81 +41,15 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
// 忽略 UNKNOWN 和 DISJOIN 情况
if (relation != Collider::Relation::UNKNOWN && relation != Collider::Relation::DISJOIN)
{
Collision::__activeNode = pActiveNode;
Collision::__passiveNode = pPassiveNode;
ColliderManager::__update();
// 更新碰撞监听器
Collision::__update(pActiveNode, pPassiveNode);
}
Collision::__activeNode = nullptr;
Collision::__passiveNode = nullptr;
}
}
}
}
}
void e2d::ColliderManager::add(const Function& func, const String& name, bool paused)
{
auto listener = new (std::nothrow) Listener(func, name, paused);
s_vListeners.push_back(listener);
}
void e2d::ColliderManager::pause(const String& name)
{
for (auto listener : s_vListeners)
{
if (listener->name == name)
{
listener->running = false;
}
}
}
void e2d::ColliderManager::resume(const String& name)
{
for (auto listener : s_vListeners)
{
if (listener->name == name)
{
listener->running = true;
}
}
}
void e2d::ColliderManager::stop(const String& name)
{
for (auto listener : s_vListeners)
{
if (listener->name == name)
{
listener->stopped = true;
}
}
}
void e2d::ColliderManager::pauseAll()
{
for (auto listener : s_vListeners)
{
listener->running = false;
}
}
void e2d::ColliderManager::resumeAll()
{
for (auto listener : s_vListeners)
{
listener->running = true;
}
}
void e2d::ColliderManager::stopAll()
{
for (auto listener : s_vListeners)
{
listener->stopped = true;
}
}
void e2d::ColliderManager::__addCollider(Collider * pCollider)
{
if (pCollider)
@ -210,12 +79,3 @@ void e2d::ColliderManager::__removeCollider(Collider * pCollider)
}
}
}
void e2d::ColliderManager::__uninit()
{
for (auto listener : s_vListeners)
{
delete listener;
}
s_vListeners.clear();
}

View File

@ -45,6 +45,9 @@ void e2d::InputManager::add(const Function& func, const String& name, bool pause
void e2d::InputManager::pause(const String& name)
{
if (s_vListeners.empty() || name.isEmpty())
return;
for (auto listener : s_vListeners)
{
if (listener->name == name)
@ -56,6 +59,9 @@ void e2d::InputManager::pause(const String& name)
void e2d::InputManager::resume(const String& name)
{
if (s_vListeners.empty() || name.isEmpty())
return;
for (auto listener : s_vListeners)
{
if (listener->name == name)
@ -67,6 +73,9 @@ void e2d::InputManager::resume(const String& name)
void e2d::InputManager::stop(const String& name)
{
if (s_vListeners.empty() || name.isEmpty())
return;
for (auto listener : s_vListeners)
{
if (listener->name == name)

View File

@ -6,7 +6,7 @@
// ĬÈÏÖÐÐĵãλÖÃ
static float s_fDefaultPiovtX = 0;
static float s_fDefaultPiovtY = 0;
static bool s_fDefaultColliderEnabled = false;
static e2d::Collider::Type s_fDefaultColliderType = e2d::Collider::Type::NONE;
e2d::Node::Node()
: _nOrder(0)
@ -35,9 +35,9 @@ e2d::Node::Node()
, _autoUpdate(true)
, _positionFixed(false)
{
if (s_fDefaultColliderEnabled)
if (s_fDefaultColliderType != Collider::Type::NONE)
{
this->setCollider(GC::create<ColliderRect>(this));
this->setCollider(s_fDefaultColliderType);
}
}
@ -560,6 +560,12 @@ void e2d::Node::setCollider(Collider::Type type)
break;
}
case Collider::Type::NONE:
{
this->setCollider(nullptr);
break;
}
default:
break;
}
@ -770,9 +776,9 @@ void e2d::Node::runAction(Action * action)
}
}
void e2d::Node::resumeAction(const String& strActionName)
void e2d::Node::resumeAction(const String& name)
{
auto& actions = ActionManager::get(strActionName);
auto& actions = ActionManager::get(name);
for (auto action : actions)
{
if (action->getTarget() == this)
@ -782,9 +788,9 @@ void e2d::Node::resumeAction(const String& strActionName)
}
}
void e2d::Node::pauseAction(const String& strActionName)
void e2d::Node::pauseAction(const String& name)
{
auto& actions = ActionManager::get(strActionName);
auto& actions = ActionManager::get(name);
for (auto action : actions)
{
if (action->getTarget() == this)
@ -794,9 +800,9 @@ void e2d::Node::pauseAction(const String& strActionName)
}
}
void e2d::Node::stopAction(const String& strActionName)
void e2d::Node::stopAction(const String& name)
{
auto& actions = ActionManager::get(strActionName);
auto& actions = ActionManager::get(name);
for (auto action : actions)
{
if (action->getTarget() == this)
@ -806,9 +812,9 @@ void e2d::Node::stopAction(const String& strActionName)
}
}
e2d::Action * e2d::Node::getAction(const String& strActionName)
e2d::Action * e2d::Node::getAction(const String& name)
{
auto& actions = ActionManager::get(strActionName);
auto& actions = ActionManager::get(name);
for (auto action : actions)
{
if (action->getTarget() == this)
@ -928,9 +934,9 @@ void e2d::Node::setDefaultPiovt(double defaultPiovtX, double defaultPiovtY)
s_fDefaultPiovtY = min(max(float(defaultPiovtY), 0), 1);
}
void e2d::Node::setDefaultColliderEnable(bool enable)
void e2d::Node::setDefaultCollider(Collider::Type type)
{
s_fDefaultColliderEnabled = enable;
s_fDefaultColliderType = type;
}
void e2d::Node::onDestroy()

View File

@ -12,6 +12,7 @@ class ColliderManager;
// 碰撞事件
class Collision
{
friend Game;
friend ColliderManager;
public:
@ -56,9 +57,54 @@ public:
const String& name
);
// 开启或关闭物体碰撞监听功能(默认关闭)
static void setEnable(
bool enable
);
// 是否打开了物体碰撞监听
static bool isEnable();
// 添加碰撞监听
static void addListener(
const Function& func, /* 监听到碰撞时的执行函数 */
const String& name = L"", /* 监听器名称 */
bool paused = false /* 是否暂停 */
);
// 暂停碰撞监听
static void pause(
const String& name
);
// 暂停碰撞监听
static void resume(
const String& name
);
// 停止碰撞监听
static void stop(
const String& name
);
// 暂停所有监听器
static void pauseAll();
// 继续所有监听器
static void resumeAll();
// 停止所有监听器
static void stopAll();
private:
static Node * __activeNode;
static Node * __passiveNode;
// 更新监听器
static void __update(
Node * active,
Node * passive
);
// 回收资源
static void __uninit();
};
@ -73,6 +119,7 @@ public:
// 碰撞体类别
enum class Type : int
{
NONE, /* 无 */
RECT, /* 矩形 */
CIRCLE, /* 圆形 */
ELLIPSE /* 椭圆形 */

View File

@ -79,17 +79,17 @@ public:
// 继续名称相同的所有动作
static void resume(
const String& strActionName
const String& name
);
// 暂停名称相同的所有动作
static void pause(
const String& strActionName
const String& name
);
// 停止名称相同的所有动作
static void stop(
const String& strActionName
const String& name
);
// 继续所有动作
@ -103,7 +103,7 @@ public:
// 获取所有名称相同的动作
static std::vector<Action *> get(
const String& strActionName
const String& name
);
// 获取所有动作
@ -201,51 +201,10 @@ private:
// 碰撞管理器
class ColliderManager
{
friend Game;
friend Node;
friend Collider;
public:
// 开启或关闭碰撞监听功能(默认关闭)
static void setEnable(
bool enable
);
// 添加碰撞监听
static void add(
const Function& func, /* 监听到碰撞时的执行函数 */
const String& name = L"", /* 监听器名称 */
bool paused = false /* 是否暂停 */
);
// 暂停碰撞监听
static void pause(
const String& name
);
// 暂停碰撞监听
static void resume(
const String& name
);
// 停止碰撞监听
static void stop(
const String& name
);
// 暂停所有监听器
static void pauseAll();
// 继续所有监听器
static void resumeAll();
// 停止所有监听器
static void stopAll();
private:
// 更新监听器
static void __update();
// 更新碰撞体
static void __updateCollider(
Collider * pActiveCollider
@ -260,9 +219,6 @@ private:
static void __removeCollider(
Collider * pCollider
);
// 回收资源
static void __uninit();
};
}

View File

@ -363,22 +363,22 @@ public:
// 继续动作
virtual void resumeAction(
const String& strActionName
const String& name
);
// 暂停动作
virtual void pauseAction(
const String& strActionName
const String& name
);
// 停止动作
virtual void stopAction(
const String& strActionName
const String& name
);
// 获取动作
virtual Action * getAction(
const String& strActionName
const String& name
);
// 继续所有暂停动作
@ -396,9 +396,9 @@ public:
double defaultPiovtY
);
// 设置节点是否包含默认碰撞体(默认关闭
static void setDefaultColliderEnable(
bool enable
// 设置节点的默认碰撞体类型(默认无
static void setDefaultCollider(
Collider::Type type
);
// 销毁对象