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

View File

@ -3,16 +3,16 @@
typedef std::pair<UINT, UINT> HashPair; typedef std::pair<UINT, UINT> HashPair;
e2d::Node * e2d::Collision::__activeNode = nullptr; static e2d::Node * s_pActiveNode = nullptr;
e2d::Node * e2d::Collision::__passiveNode = nullptr; static e2d::Node * s_pPassiveNode = nullptr;
static std::set<HashPair> __collisionList; static std::set<HashPair> s_sCollisionList;
void e2d::Collision::addName(const String & name1, const String & name2) void e2d::Collision::addName(const String & name1, const String & name2)
{ {
if (!name1.isEmpty() && !name2.isEmpty()) 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()) 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(); UINT hashName1 = name1.getHashCode(), hashName2 = name2.getHashCode();
HashPair pair1 = HashPair(hashName1, hashName2), pair2 = HashPair(hashName2, hashName1); HashPair pair1 = HashPair(hashName1, hashName2), pair2 = HashPair(hashName2, hashName1);
for (auto& pair : __collisionList) for (auto& pair : s_sCollisionList)
{ {
if (pair == pair1 || pair == pair2) if (pair == pair1 || pair == pair2)
{ {
@ -48,28 +48,188 @@ bool e2d::Collision::isCollidable(const String & name1, const String & name2)
e2d::Node * e2d::Collision::getActiveNode() e2d::Node * e2d::Collision::getActiveNode()
{ {
return __activeNode; return s_pActiveNode;
} }
e2d::Node * e2d::Collision::getPassiveNode() e2d::Node * e2d::Collision::getPassiveNode()
{ {
return __passiveNode; return s_pPassiveNode;
} }
e2d::Node* e2d::Collision::isCausedBy(Node * node) e2d::Node* e2d::Collision::isCausedBy(Node * node)
{ {
if (__activeNode == node) if (s_pActiveNode == node)
return __passiveNode; return s_pPassiveNode;
if (__passiveNode == node) if (s_pPassiveNode == node)
return __activeNode; return s_pActiveNode;
return nullptr; return nullptr;
} }
e2d::Node* e2d::Collision::isCausedBy(const String& name) e2d::Node* e2d::Collision::isCausedBy(const String& name)
{ {
if (__activeNode->getName() == name) if (s_pActiveNode->getName() == name)
return __activeNode; return s_pActiveNode;
if (__passiveNode->getName() == name) if (s_pPassiveNode->getName() == name)
return __passiveNode; return s_pPassiveNode;
return nullptr; 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) void e2d::ActionManager::__remove(Action * action)
{ {
if (s_vActions.empty() || action == nullptr)
return;
auto iter = std::find(s_vActions.begin(), s_vActions.end(), action); auto iter = std::find(s_vActions.begin(), s_vActions.end(), action);
if (iter != s_vActions.end()) if (iter != s_vActions.end())
{ {
@ -52,42 +55,42 @@ void e2d::ActionManager::__remove(Action * action)
void e2d::ActionManager::__resumeAllBindedWith(Node * target) 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) 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) 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) for (auto action : s_vRunningActions)
{ {
if (action->getName() == strActionName) if (action->getName() == name)
{ {
action->resume(); 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) for (auto action : s_vRunningActions)
{ {
if (action->getName() == strActionName) if (action->getName() == name)
{ {
action->pause(); 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) for (auto action : s_vRunningActions)
{ {
if (action->getName() == strActionName) if (action->getName() == name)
{ {
action->stop(); 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; std::vector<Action*> actions;
for (auto action : s_vActions) for (auto action : s_vActions)
{ {
if (action->getName() == strActionName) if (action->getName() == name)
{ {
actions.push_back(action); actions.push_back(action);
} }

View File

@ -3,79 +3,14 @@
#include "..\e2dcollider.h" #include "..\e2dcollider.h"
#include "..\e2dtool.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<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) void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
{ {
// 判断碰撞触发是否打开 // 判断碰撞触发是否打开
if (!s_bCollisionEnable) if (!Collision::isEnable())
return; return;
Node* pActiveNode = pActiveCollider->_parentNode; Node* pActiveNode = pActiveCollider->_parentNode;
@ -106,81 +41,15 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
// 忽略 UNKNOWN 和 DISJOIN 情况 // 忽略 UNKNOWN 和 DISJOIN 情况
if (relation != Collider::Relation::UNKNOWN && relation != Collider::Relation::DISJOIN) if (relation != Collider::Relation::UNKNOWN && relation != Collider::Relation::DISJOIN)
{ {
Collision::__activeNode = pActiveNode; // 更新碰撞监听器
Collision::__passiveNode = pPassiveNode; Collision::__update(pActiveNode, pPassiveNode);
ColliderManager::__update();
} }
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) void e2d::ColliderManager::__addCollider(Collider * pCollider)
{ {
if (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) void e2d::InputManager::pause(const String& name)
{ {
if (s_vListeners.empty() || name.isEmpty())
return;
for (auto listener : s_vListeners) for (auto listener : s_vListeners)
{ {
if (listener->name == name) if (listener->name == name)
@ -56,6 +59,9 @@ void e2d::InputManager::pause(const String& name)
void e2d::InputManager::resume(const String& name) void e2d::InputManager::resume(const String& name)
{ {
if (s_vListeners.empty() || name.isEmpty())
return;
for (auto listener : s_vListeners) for (auto listener : s_vListeners)
{ {
if (listener->name == name) if (listener->name == name)
@ -67,6 +73,9 @@ void e2d::InputManager::resume(const String& name)
void e2d::InputManager::stop(const String& name) void e2d::InputManager::stop(const String& name)
{ {
if (s_vListeners.empty() || name.isEmpty())
return;
for (auto listener : s_vListeners) for (auto listener : s_vListeners)
{ {
if (listener->name == name) if (listener->name == name)

View File

@ -6,7 +6,7 @@
// ĬÈÏÖÐÐĵãλÖà // ĬÈÏÖÐÐĵãλÖÃ
static float s_fDefaultPiovtX = 0; static float s_fDefaultPiovtX = 0;
static float s_fDefaultPiovtY = 0; static float s_fDefaultPiovtY = 0;
static bool s_fDefaultColliderEnabled = false; static e2d::Collider::Type s_fDefaultColliderType = e2d::Collider::Type::NONE;
e2d::Node::Node() e2d::Node::Node()
: _nOrder(0) : _nOrder(0)
@ -35,9 +35,9 @@ e2d::Node::Node()
, _autoUpdate(true) , _autoUpdate(true)
, _positionFixed(false) , _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; break;
} }
case Collider::Type::NONE:
{
this->setCollider(nullptr);
break;
}
default: default:
break; 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) for (auto action : actions)
{ {
if (action->getTarget() == this) 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) for (auto action : actions)
{ {
if (action->getTarget() == this) 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) for (auto action : actions)
{ {
if (action->getTarget() == this) 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) for (auto action : actions)
{ {
if (action->getTarget() == this) if (action->getTarget() == this)
@ -928,9 +934,9 @@ void e2d::Node::setDefaultPiovt(double defaultPiovtX, double defaultPiovtY)
s_fDefaultPiovtY = min(max(float(defaultPiovtY), 0), 1); 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() void e2d::Node::onDestroy()

View File

@ -12,6 +12,7 @@ class ColliderManager;
// 碰撞事件 // 碰撞事件
class Collision class Collision
{ {
friend Game;
friend ColliderManager; friend ColliderManager;
public: public:
@ -56,9 +57,54 @@ public:
const String& name 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: 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 enum class Type : int
{ {
NONE, /* 无 */
RECT, /* 矩形 */ RECT, /* 矩形 */
CIRCLE, /* 圆形 */ CIRCLE, /* 圆形 */
ELLIPSE /* 椭圆形 */ ELLIPSE /* 椭圆形 */

View File

@ -79,17 +79,17 @@ public:
// 继续名称相同的所有动作 // 继续名称相同的所有动作
static void resume( static void resume(
const String& strActionName const String& name
); );
// 暂停名称相同的所有动作 // 暂停名称相同的所有动作
static void pause( static void pause(
const String& strActionName const String& name
); );
// 停止名称相同的所有动作 // 停止名称相同的所有动作
static void stop( static void stop(
const String& strActionName const String& name
); );
// 继续所有动作 // 继续所有动作
@ -103,7 +103,7 @@ public:
// 获取所有名称相同的动作 // 获取所有名称相同的动作
static std::vector<Action *> get( static std::vector<Action *> get(
const String& strActionName const String& name
); );
// 获取所有动作 // 获取所有动作
@ -201,51 +201,10 @@ private:
// 碰撞管理器 // 碰撞管理器
class ColliderManager class ColliderManager
{ {
friend Game;
friend Node; friend Node;
friend Collider; 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: private:
// 更新监听器
static void __update();
// 更新碰撞体 // 更新碰撞体
static void __updateCollider( static void __updateCollider(
Collider * pActiveCollider Collider * pActiveCollider
@ -260,9 +219,6 @@ private:
static void __removeCollider( static void __removeCollider(
Collider * pCollider Collider * pCollider
); );
// 回收资源
static void __uninit();
}; };
} }

View File

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