From 198ff09eaa562ecc0893208678f037cb8eb440cb Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Mon, 21 May 2018 23:04:58 +0800 Subject: [PATCH] =?UTF-8?q?Collision=E5=88=A4=E6=96=AD=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E9=87=8D=E5=81=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Collider/Collision.cpp | 41 ++++++++++++++++++ core/Manager/ActionManager.cpp | 25 +++-------- core/Manager/ColliderManager.cpp | 13 +----- core/Node/Node.cpp | 73 ++++++++------------------------ core/e2dbase.h | 2 +- core/e2dcollider.h | 23 ++++++++++ core/e2dnode.h | 31 +++----------- 7 files changed, 94 insertions(+), 114 deletions(-) diff --git a/core/Collider/Collision.cpp b/core/Collider/Collision.cpp index 17633103..54d5e90b 100644 --- a/core/Collider/Collision.cpp +++ b/core/Collider/Collision.cpp @@ -1,10 +1,51 @@ #include "..\e2dcollider.h" #include "..\e2dnode.h" +typedef std::pair HashPair; + e2d::Node * e2d::Collision::__activeNode = nullptr; e2d::Node * e2d::Collision::__passiveNode = nullptr; +static std::set __collisionList; +void e2d::Collision::addName(const String & name1, const String & name2) +{ + if (!name1.isEmpty() && !name2.isEmpty()) + { + __collisionList.insert(HashPair(name1.getHashCode(), name2.getHashCode())); + } +} + +void e2d::Collision::addName(const std::vector >& names) +{ + for (auto& name : names) + { + if (!name.first.isEmpty() && !name.second.isEmpty()) + { + __collisionList.insert(HashPair(name.first.getHashCode(), name.second.getHashCode())); + } + } +} + +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); + for (auto& pair : __collisionList) + { + if (pair == pair1 || pair == pair2) + { + return true; + } + } + return false; +} + e2d::Node * e2d::Collision::getActiveNode() { return __activeNode; diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index 677470ea..80d5eb65 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -43,16 +43,10 @@ void e2d::ActionManager::__add(Action * action) void e2d::ActionManager::__remove(Action * action) { - for (size_t i = 0; i < s_vActions.size();) + auto iter = std::find(s_vActions.begin(), s_vActions.end(), action); + if (iter != s_vActions.end()) { - if (s_vActions[i] == action) - { - s_vActions.erase(s_vActions.begin() + i); - } - else - { - ++i; - } + s_vActions.erase(iter); } } @@ -105,17 +99,8 @@ void e2d::ActionManager::start(Action * action, Node * target, bool paused) if (action && target) { - ASSERT([](Action * newAction) - { - for (const auto& action : s_vRunningActions) - { - if (newAction == action) - { - return false; - } - } - return true; - }(action), "action already be added!"); + auto iter = std::find(s_vRunningActions.begin(), s_vRunningActions.end(), action); + ASSERT(iter == s_vRunningActions.end(), "Action has begun!"); action->_startWithTarget(target); action->retain(); diff --git a/core/Manager/ColliderManager.cpp b/core/Manager/ColliderManager.cpp index 547bc8e6..18e43ac7 100644 --- a/core/Manager/ColliderManager.cpp +++ b/core/Manager/ColliderManager.cpp @@ -81,16 +81,6 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider) Node* pActiveNode = pActiveCollider->_parentNode; if (pActiveNode) { - // 判断两物体是否是相互冲突的物体 - auto IsCollideWith = [](Node * active, Node * passive) -> bool - { - unsigned int hash = passive->getHashName(); - for (auto collider : active->_colliders) - if (collider == hash) - return true; - return false; - }; - // 获取节点所在场景 Scene* pCurrentScene = pActiveNode->getParentScene(); @@ -108,7 +98,8 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider) if (pPassiveNode && pPassiveNode->getParentScene() == pCurrentScene) { - if (IsCollideWith(pActiveNode, pPassiveNode)) + // 判断两物体是否是相互冲突的物体 + if (Collision::isCollidable(pActiveNode, pPassiveNode)) { // 判断两碰撞体交集情况 Collider::Relation relation = pActiveCollider->getRelationWith(pPassiveCollider); diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 6b28de29..404c15db 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 = true; +static bool s_fDefaultColliderEnabled = false; e2d::Node::Node() : _nOrder(0) @@ -584,36 +584,18 @@ void e2d::Node::setCollider(Collider * pCollider) } } -void e2d::Node::addColliableName(const String& collliderName) -{ - unsigned int hash = collliderName.getHashCode(); - _colliders.insert(hash); -} - -void e2d::Node::addColliableName(const std::vector& colliderNames) -{ - for (const auto &name : colliderNames) - { - this->addColliableName(name); - } -} - -void e2d::Node::removeColliableName(const String& collliderName) -{ - unsigned int hash = collliderName.getHashCode(); - _colliders.erase(hash); -} - void e2d::Node::addChild(Node * child, int order /* = 0 */) { WARN_IF(child == nullptr, "Node::addChild NULL pointer exception."); if (child) { + // TODO: 抛出一个异常 ASSERT(child->_parent == nullptr, "Node already added. It can't be added again!"); for (Node * parent = this; parent != nullptr; parent = parent->getParent()) { + // TODO: 抛出一个异常 ASSERT(child != parent, "A Node cannot be the child of his own children!"); } @@ -717,22 +699,19 @@ bool e2d::Node::removeChild(Node * child) if (child) { - size_t size = _children.size(); - for (size_t i = 0; i < size; ++i) + auto iter = std::find(_children.begin(), _children.end(), child); + if (iter != _children.end()) { - if (_children[i] == child) + _children.erase(iter); + child->_parent = nullptr; + + if (child->_parentScene) { - _children.erase(_children.begin() + i); - child->_parent = nullptr; - - if (child->_parentScene) - { - child->_setParentScene(nullptr); - } - - child->release(); - return true; + child->_setParentScene(nullptr); } + + child->release(); + return true; } } return false; @@ -793,7 +772,7 @@ void e2d::Node::runAction(Action * action) void e2d::Node::resumeAction(const String& strActionName) { - auto actions = ActionManager::get(strActionName); + auto& actions = ActionManager::get(strActionName); for (auto action : actions) { if (action->getTarget() == this) @@ -805,7 +784,7 @@ void e2d::Node::resumeAction(const String& strActionName) void e2d::Node::pauseAction(const String& strActionName) { - auto actions = ActionManager::get(strActionName); + auto& actions = ActionManager::get(strActionName); for (auto action : actions) { if (action->getTarget() == this) @@ -817,7 +796,7 @@ void e2d::Node::pauseAction(const String& strActionName) void e2d::Node::stopAction(const String& strActionName) { - auto actions = ActionManager::get(strActionName); + auto& actions = ActionManager::get(strActionName); for (auto action : actions) { if (action->getTarget() == this) @@ -829,7 +808,7 @@ void e2d::Node::stopAction(const String& strActionName) e2d::Action * e2d::Node::getAction(const String& strActionName) { - auto actions = ActionManager::get(strActionName); + auto& actions = ActionManager::get(strActionName); for (auto action : actions) { if (action->getTarget() == this) @@ -840,24 +819,6 @@ e2d::Action * e2d::Node::getAction(const String& strActionName) return nullptr; } -std::vector e2d::Node::getActions(const String& strActionName) -{ - std::vector::iterator iter; - auto actions = ActionManager::get(strActionName); - for (iter = actions.begin(); iter != actions.end();) - { - if ((*iter)->getTarget() != this) - { - iter = actions.erase(iter); - } - else - { - ++iter; - } - } - return std::move(actions); -} - bool e2d::Node::isPointIn(Point point) const { BOOL ret = 0; diff --git a/core/e2dbase.h b/core/e2dbase.h index e5528184..b0be3d05 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -113,7 +113,7 @@ public: // 弹出提示窗口 static void info( const String& text, /* 内容 */ - const String& title = L"Prompt" /* 窗口标题 */ + const String& title = L"Infomation" /* 窗口标题 */ ); // 弹出警告窗口 diff --git a/core/e2dcollider.h b/core/e2dcollider.h index b68e64a5..9889d0cb 100644 --- a/core/e2dcollider.h +++ b/core/e2dcollider.h @@ -15,6 +15,29 @@ class Collision friend ColliderManager; public: + // 添加可互相碰撞物体的名称 + static void addName( + const String& name1, + const String& name2 + ); + + // 添加可互相碰撞物体的名称 + static void addName( + const std::vector >& names + ); + + // 判断两个物体是否是可碰撞的 + static bool isCollidable( + Node * node1, + Node * node2 + ); + + // 判断两个物体是否是可碰撞的 + static bool isCollidable( + const String& name1, + const String& name2 + ); + // 获取碰撞发生时的主动体 static Node * getActiveNode(); diff --git a/core/e2dnode.h b/core/e2dnode.h index 6e4270a4..415a506d 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -344,21 +344,6 @@ public: Collider * pCollider ); - // 添加可碰撞节点的名称 - virtual void addColliableName( - const String& collliderName - ); - - // 添加多个可碰撞节点的名称 - virtual void addColliableName( - const std::vector& colliderNames /* 名称数组 */ - ); - - // 移除可碰撞节点的名称 - virtual void removeColliableName( - const String& collliderName - ); - // 添加子节点 virtual void addChild( Node * child, @@ -391,16 +376,11 @@ public: const String& strActionName ); - // 获取名称相同的动作 + // 获取动作 virtual Action * getAction( const String& strActionName ); - // 获取所有名称相同的动作 - virtual std::vector getActions( - const String& strActionName - ); - // 继续所有暂停动作 virtual void resumeAllActions(); @@ -416,7 +396,7 @@ public: double defaultPiovtY ); - // 设置节点是否包含默认碰撞体(默认打开) + // 设置节点是否包含默认碰撞体(默认关闭) static void setDefaultColliderEnable( bool enable ); @@ -476,10 +456,9 @@ protected: Collider * _collider; Scene * _parentScene; Node * _parent; - D2D1::Matrix3x2F _initialMatri; - D2D1::Matrix3x2F _finalMatri; - std::set _colliders; - std::vector _children; + D2D1::Matrix3x2F _initialMatri; + D2D1::Matrix3x2F _finalMatri; + std::vector _children; };