From 432a0150b95eecc843f2dc8008509c47dae8c13e Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Tue, 22 May 2018 00:11:57 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A2=B0=E6=92=9E=E7=9B=91=E5=90=AC=E5=99=A8?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=88=B0Collision=E7=B1=BB=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/Game.cpp | 6 +- core/Collider/Collision.cpp | 192 ++++++++++++++++++++++++++++--- core/Manager/ActionManager.cpp | 64 ++++++----- core/Manager/ColliderManager.cpp | 146 +---------------------- core/Manager/InputManager.cpp | 9 ++ core/Node/Node.cpp | 32 +++--- core/e2dcollider.h | 51 +++++++- core/e2dmanager.h | 52 +-------- core/e2dnode.h | 14 +-- 9 files changed, 309 insertions(+), 257 deletions(-) diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 1632cc33..f2ba83b8 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -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(); // 回收音乐播放器资源 diff --git a/core/Collider/Collision.cpp b/core/Collider/Collision.cpp index 54d5e90b..fe168410 100644 --- a/core/Collider/Collision.cpp +++ b/core/Collider/Collision.cpp @@ -3,16 +3,16 @@ typedef std::pair HashPair; -e2d::Node * e2d::Collision::__activeNode = nullptr; -e2d::Node * e2d::Collision::__passiveNode = nullptr; -static std::set __collisionList; +static e2d::Node * s_pActiveNode = nullptr; +static e2d::Node * s_pPassiveNode = nullptr; +static std::set 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 >& 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 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(); } \ No newline at end of file diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index 80d5eb65..be9dde77 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -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::ActionManager::get(const String& strActionName) +std::vector e2d::ActionManager::get(const String& name) { std::vector actions; for (auto action : s_vActions) { - if (action->getName() == strActionName) + if (action->getName() == name) { actions.push_back(action); } diff --git a/core/Manager/ColliderManager.cpp b/core/Manager/ColliderManager.cpp index 18e43ac7..9cda287d 100644 --- a/core/Manager/ColliderManager.cpp +++ b/core/Manager/ColliderManager.cpp @@ -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 s_vColliders; -// 监听器容器 -static std::vector 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(); -} diff --git a/core/Manager/InputManager.cpp b/core/Manager/InputManager.cpp index 9ef0f331..304453b2 100644 --- a/core/Manager/InputManager.cpp +++ b/core/Manager/InputManager.cpp @@ -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) diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 404c15db..36780c22 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -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(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() diff --git a/core/e2dcollider.h b/core/e2dcollider.h index 9889d0cb..22c2d50a 100644 --- a/core/e2dcollider.h +++ b/core/e2dcollider.h @@ -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 /* 椭圆形 */ diff --git a/core/e2dmanager.h b/core/e2dmanager.h index 53d2ba96..e92fe1b9 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -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 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(); }; } \ No newline at end of file diff --git a/core/e2dnode.h b/core/e2dnode.h index 415a506d..9ee825a8 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -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 ); // 销毁对象