From caf6297bf13167ca6cb3542609a9050bf0d324b6 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Thu, 5 Jul 2018 16:34:53 +0800 Subject: [PATCH] =?UTF-8?q?SceneManager=E5=92=8CColliderManager=E5=8D=95?= =?UTF-8?q?=E4=BE=8B=E6=A8=A1=E5=BC=8F=E9=87=8D=E5=81=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/GC.cpp | 2 + core/Base/Game.cpp | 17 ++-- core/Base/Input.cpp | 12 +-- core/Base/Renderer.cpp | 2 +- core/Base/Window.cpp | 2 +- core/Collider/Collision.cpp | 10 +- core/Common/Collider.cpp | 2 +- core/Manager/ActionManager.cpp | 24 +++-- core/Manager/ColliderManager.cpp | 40 ++++++-- core/Manager/SceneManager.cpp | 165 ++++++++++++++++--------------- core/Node/Button.cpp | 2 +- core/Node/Node.cpp | 6 +- core/Tool/Timer.cpp | 12 +-- core/e2dbase.h | 3 - core/e2dcollider.h | 7 +- core/e2dmanager.h | 63 +++++++++--- core/e2dtool.h | 3 - 17 files changed, 205 insertions(+), 167 deletions(-) diff --git a/core/Base/GC.cpp b/core/Base/GC.cpp index 2f8116e9..69f1881b 100644 --- a/core/Base/GC.cpp +++ b/core/Base/GC.cpp @@ -13,7 +13,9 @@ e2d::GC::~GC() Input::destroyInstance(); Window::destroyInstance(); Player::destroyInstance(); + SceneManager::destroyInstance(); ActionManager::destroyInstance(); + ColliderManager::destroyInstance(); } diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index b9b5e70d..ca3bccb6 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -44,9 +44,8 @@ void e2d::Game::start(bool cleanup) auto window = Window::getInstance(); auto renderer = Renderer::getInstance(); auto actionManager = ActionManager::getInstance(); + auto sceneManager = SceneManager::getInstance(); - // 初始化场景管理器 - SceneManager::__init(); // 显示窗口 ::ShowWindow(window->getHWnd(), SW_SHOWNORMAL); // 刷新窗口内容 @@ -77,7 +76,7 @@ void e2d::Game::start(bool cleanup) input->__update(); // 获取用户输入 Timer::__update(); // 更新定时器 actionManager->__update(); // 更新动作管理器 - SceneManager::__update(); // 更新场景内容 + sceneManager->__update(); // 更新场景内容 renderer->__render(); // 渲染游戏画面 Time::__updateLast(); // 刷新时间信息 @@ -116,8 +115,8 @@ void e2d::Game::reset() if (!_ended) { Time::__reset(); - ActionManager::getInstance()->__resetAll(); Timer::__resetAll(); + ActionManager::getInstance()->__resetAll(); } } @@ -155,15 +154,15 @@ void e2d::Game::quit() void e2d::Game::cleanup() { // 删除所有场景 - SceneManager::__uninit(); - // 删除输入监听器 - Input::__clearListeners(); + SceneManager::getInstance()->clear(); // 删除碰撞监听器 - Collision::__clearListeners(); + Collision::removeAllListeners(); + // 删除输入监听器 + Input::removeAllListeners(); // 清空图片缓存 Image::clearCache(); // 清空定时器 - Timer::__uninit(); + Timer::removeAll(); // 删除所有对象 GC::getInstance()->clear(); } diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index b101d6c2..f1c37839 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -330,8 +330,9 @@ void e2d::Input::removeAllListeners() { for (auto listener : s_vListeners) { - listener->_stopped = true; + GC::release(listener); } + s_vListeners.clear(); } void e2d::Input::__updateListeners() @@ -356,12 +357,3 @@ void e2d::Input::__updateListeners() } } } - -void e2d::Input::__clearListeners() -{ - for (auto listener : s_vListeners) - { - GC::release(listener); - } - s_vListeners.clear(); -} \ No newline at end of file diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index 1e6d5710..27c26789 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -131,7 +131,7 @@ void e2d::Renderer::__render() _renderTarget->Clear(_clearColor); // 渲染场景 - SceneManager::__render(); + SceneManager::getInstance()->__render(); // 渲染 FPS if (_showFps) diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index 08219612..c0d4afae 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -436,7 +436,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar // 窗口关闭消息 case WM_CLOSE: { - e2d::Scene * pCurrentScene = e2d::SceneManager::getCurrentScene(); + e2d::Scene * pCurrentScene = e2d::SceneManager::getInstance()->getCurrentScene(); if (!pCurrentScene || pCurrentScene->onCloseWindow()) { e2d::Game::getInstance()->quit(); diff --git a/core/Collider/Collision.cpp b/core/Collider/Collision.cpp index 0c3c62ea..a48bfd73 100644 --- a/core/Collider/Collision.cpp +++ b/core/Collider/Collision.cpp @@ -212,18 +212,10 @@ void e2d::Collision::startAllListeners() } void e2d::Collision::removeAllListeners() -{ - for (auto listener : s_vListeners) - { - listener->_stopped = true; - } -} - -void e2d::Collision::__clearListeners() { for (auto listener : s_vListeners) { GC::release(listener); } s_vListeners.clear(); -} \ No newline at end of file +} diff --git a/core/Common/Collider.cpp b/core/Common/Collider.cpp index ef989b7d..e1edc5c1 100644 --- a/core/Common/Collider.cpp +++ b/core/Common/Collider.cpp @@ -172,6 +172,6 @@ void e2d::Collider::_transform() &_transformed ); // 通知碰撞体管理器 - ColliderManager::__updateCollider(this); + ColliderManager::getInstance()->__updateCollider(this); } } diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index 50b6df53..3c46cb4f 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -215,25 +215,37 @@ void e2d::ActionManager::clearAllBindedWith(Node * target) void e2d::ActionManager::resumeAll() { - for (auto child : SceneManager::getCurrentScene()->getRoot()->getAllChildren()) + auto scene = SceneManager::getInstance()->getCurrentScene(); + if (scene) { - ActionManager::resumeAllBindedWith(child); + for (auto child : scene->getRoot()->getAllChildren()) + { + ActionManager::resumeAllBindedWith(child); + } } } void e2d::ActionManager::pauseAll() { - for (auto child : SceneManager::getCurrentScene()->getRoot()->getAllChildren()) + auto scene = SceneManager::getInstance()->getCurrentScene(); + if (scene) { - ActionManager::pauseAllBindedWith(child); + for (auto child : scene->getRoot()->getAllChildren()) + { + ActionManager::pauseAllBindedWith(child); + } } } void e2d::ActionManager::stopAll() { - for (auto child : SceneManager::getCurrentScene()->getRoot()->getAllChildren()) + auto scene = SceneManager::getInstance()->getCurrentScene(); + if (scene) { - ActionManager::stopAllBindedWith(child); + for (auto child : scene->getRoot()->getAllChildren()) + { + ActionManager::stopAllBindedWith(child); + } } } diff --git a/core/Manager/ColliderManager.cpp b/core/Manager/ColliderManager.cpp index d5306cf5..0e7f080b 100644 --- a/core/Manager/ColliderManager.cpp +++ b/core/Manager/ColliderManager.cpp @@ -4,8 +4,32 @@ #include "..\e2dtool.h" -// 碰撞体集合 -static std::vector s_vColliders; +e2d::ColliderManager * e2d::ColliderManager::_instance = nullptr; + +e2d::ColliderManager * e2d::ColliderManager::getInstance() +{ + if (!_instance) + _instance = new (std::nothrow) ColliderManager; + return _instance; +} + +void e2d::ColliderManager::destroyInstance() +{ + if (_instance) + { + delete _instance; + _instance = nullptr; + } +} + +e2d::ColliderManager::ColliderManager() + : _colliders() +{ +} + +e2d::ColliderManager::~ColliderManager() +{ +} void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider) { @@ -20,9 +44,9 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider) Scene* pCurrentScene = pActiveNode->getParentScene(); // 判断与其他碰撞体的交集情况 - for (size_t i = 0; i < s_vColliders.size(); ++i) + for (size_t i = 0; i < _colliders.size(); ++i) { - auto pPassiveCollider = s_vColliders[i]; + auto pPassiveCollider = _colliders[i]; // 判断两个碰撞体是否是同一个对象 if (pActiveCollider == pPassiveCollider) continue; @@ -55,7 +79,7 @@ void e2d::ColliderManager::__add(Collider * pCollider) if (pCollider) { pCollider->retain(); - s_vColliders.push_back(pCollider); + _colliders.push_back(pCollider); } } @@ -63,12 +87,12 @@ void e2d::ColliderManager::__remove(Collider * pCollider) { if (pCollider) { - for (size_t i = 0; i < s_vColliders.size(); ++i) + for (size_t i = 0; i < _colliders.size(); ++i) { - if (s_vColliders[i] == pCollider) + if (_colliders[i] == pCollider) { GC::release(pCollider); - s_vColliders.erase(s_vColliders.begin() + i); + _colliders.erase(_colliders.begin() + i); return; } } diff --git a/core/Manager/SceneManager.cpp b/core/Manager/SceneManager.cpp index 1eb6f2f8..b3141739 100644 --- a/core/Manager/SceneManager.cpp +++ b/core/Manager/SceneManager.cpp @@ -2,65 +2,89 @@ #include "..\e2dbase.h" #include "..\e2dtransition.h" -static bool s_bSaveCurrScene = true; -static e2d::Scene * s_pCurrScene = nullptr; -static e2d::Scene * s_pNextScene = nullptr; -static e2d::Transition * s_pTransition = nullptr; -static std::stack s_SceneStack; + +e2d::SceneManager * e2d::SceneManager::_instance = nullptr; + +e2d::SceneManager * e2d::SceneManager::getInstance() +{ + if (!_instance) + _instance = new (std::nothrow) SceneManager; + return _instance; +} + +void e2d::SceneManager::destroyInstance() +{ + if (_instance) + { + delete _instance; + _instance = nullptr; + } +} + +e2d::SceneManager::SceneManager() + : _saveCurrScene(true) + , _currScene(nullptr) + , _nextScene(nullptr) + , _transition(nullptr) + , _scenes() +{ +} + +e2d::SceneManager::~SceneManager() +{ +} void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */) { - if (scene == nullptr) - { - throw Exception(L"场景空指针异常"); - } + if (!scene) + return; // 保存下一场景的指针 - s_pNextScene = scene; - s_pNextScene->retain(); + _nextScene = scene; + _nextScene->retain(); // 设置切换场景动作 if (transition) { - if (s_pTransition) + if (_transition) { - s_pTransition->_stop(); - s_pTransition->release(); + _transition->_stop(); + _transition->release(); } - s_pTransition = transition; + _transition = transition; transition->retain(); - transition->_init(s_pCurrScene, s_pNextScene); + transition->_init(_currScene, _nextScene); transition->_update(); } - if (s_pCurrScene) + if (_currScene) { - s_bSaveCurrScene = saveCurrentScene; + _saveCurrScene = saveCurrentScene; } } void e2d::SceneManager::back(Transition * transition /* = nullptr */) { // 栈为空时,调用返回场景函数失败 - WARN_IF(s_SceneStack.size() == 0, "Scene stack is empty!"); - if (s_SceneStack.size() == 0) return; + WARN_IF(_scenes.size() == 0, "Scene stack is empty!"); + if (_scenes.size() == 0) return; // 从栈顶取出场景指针,作为下一场景 - s_pNextScene = s_SceneStack.top(); - s_SceneStack.pop(); + _nextScene = _scenes.top(); + _scenes.pop(); // 返回上一场景时,不保存当前场景 - if (s_pCurrScene) + if (_currScene) { - s_bSaveCurrScene = false; + _saveCurrScene = false; } // 设置切换场景动作 if (transition) { - s_pTransition = transition; + _transition = transition; transition->retain(); - transition->_init(s_pCurrScene, s_pNextScene); + transition->_init(_currScene, _nextScene); transition->_update(); } } @@ -68,48 +92,48 @@ void e2d::SceneManager::back(Transition * transition /* = nullptr */) void e2d::SceneManager::clear() { // 清空场景栈 - while (s_SceneStack.size()) + while (_scenes.size()) { - auto temp = s_SceneStack.top(); + auto temp = _scenes.top(); GC::release(temp); - s_SceneStack.pop(); + _scenes.pop(); } } e2d::Scene * e2d::SceneManager::getCurrentScene() { - return s_pCurrScene; + return _currScene; } std::stack e2d::SceneManager::getSceneStack() { - return s_SceneStack; + return _scenes; } bool e2d::SceneManager::isTransitioning() { - return s_pTransition != nullptr; + return _transition != nullptr; } void e2d::SceneManager::__update() { - if (s_pTransition == nullptr) + if (_transition == nullptr) { // 更新场景内容 - if (s_pCurrScene) + if (_currScene) { - s_pCurrScene->_update(); + _currScene->_update(); } } else { // 更新场景动作 - s_pTransition->_update(); + _transition->_update(); - if (s_pTransition->isDone()) + if (_transition->isDone()) { - s_pTransition->release(); - s_pTransition = nullptr; + _transition->release(); + _transition = nullptr; } else { @@ -118,65 +142,44 @@ void e2d::SceneManager::__update() } // 下一场景指针不为空时,切换场景 - if (s_pNextScene) + if (_nextScene) { - // 执行当前场景的 onExit 函数 - s_pCurrScene->onExit(); + if (_currScene) + { + // 执行当前场景的 onExit 函数 + _currScene->onExit(); - // 若要保存当前场景,把它放入栈中 - if (s_bSaveCurrScene) - { - s_SceneStack.push(s_pCurrScene); - } - else - { - GC::release(s_pCurrScene); + // 若要保存当前场景,把它放入栈中 + if (_saveCurrScene) + { + _scenes.push(_currScene); + } + else + { + _currScene->release(); + } } // 执行下一场景的 onEnter 函数 - s_pNextScene->onEnter(); + _nextScene->onEnter(); - s_pCurrScene = s_pNextScene; // 切换场景 - s_pNextScene = nullptr; // 下一场景置空 + _currScene = _nextScene; // 切换场景 + _nextScene = nullptr; // 下一场景置空 } } void e2d::SceneManager::__render() { - if (s_pTransition) + if (_transition) { - s_pTransition->_render(); + _transition->_render(); } else { // 绘制当前场景 - if (s_pCurrScene) + if (_currScene) { - s_pCurrScene->_render(); + _currScene->_render(); } } } - -bool e2d::SceneManager::__init() -{ - // 若游戏初始化时场景不为空,进入该场景 - if (s_pNextScene) - { - s_pCurrScene = s_pNextScene; - s_pCurrScene->onEnter(); - s_pNextScene = nullptr; - } - - // 更新场景内容 - SceneManager::__update(); - - return true; -} - -void e2d::SceneManager::__uninit() -{ - GC::release(s_pCurrScene); - GC::release(s_pNextScene); - GC::release(s_pTransition); - SceneManager::clear(); -} diff --git a/core/Node/Button.cpp b/core/Node/Button.cpp index 7c065b21..98120eba 100644 --- a/core/Node/Button.cpp +++ b/core/Node/Button.cpp @@ -177,7 +177,7 @@ void e2d::Button::setClickFunc(const Function& func) void e2d::Button::_fixedUpdate() { - if (SceneManager::isTransitioning()) + if (SceneManager::getInstance()->isTransitioning()) return; auto input = Input::getInstance(); diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 964489ce..c9b83463 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -559,7 +559,7 @@ void e2d::Node::setColliderType(Collider::Type type) default: { // 删除碰撞体 - ColliderManager::__remove(_collider); + ColliderManager::getInstance()->__remove(_collider); _collider = nullptr; } break; @@ -577,7 +577,7 @@ void e2d::Node::setColliderType(Collider::Type type) this->_collider->_parentNode = this; this->_collider->_recreate(type); // 添加新的碰撞体 - ColliderManager::__add(this->_collider); + ColliderManager::getInstance()->__add(this->_collider); } break; @@ -911,7 +911,7 @@ void e2d::Node::setAutoUpdate(bool bAutoUpdate) void e2d::Node::onDestroy() { ActionManager::getInstance()->clearAllBindedWith(this); - ColliderManager::__remove(_collider); + ColliderManager::getInstance()->__remove(_collider); for (auto child : _children) { GC::release(child); diff --git a/core/Tool/Timer.cpp b/core/Tool/Timer.cpp index c66976cf..9b3b5593 100644 --- a/core/Tool/Timer.cpp +++ b/core/Tool/Timer.cpp @@ -138,8 +138,9 @@ void e2d::Timer::removeAll() { for (auto timer : s_vTimers) { - timer->stopped = true; + delete timer; } + s_vTimers.clear(); } void e2d::Timer::__update() @@ -176,12 +177,3 @@ void e2d::Timer::__resetAll() timer->lastTime = Time::getTotalTime(); } } - -void e2d::Timer::__uninit() -{ - for (auto timer : s_vTimers) - { - delete timer; - } - s_vTimers.clear(); -} \ No newline at end of file diff --git a/core/e2dbase.h b/core/e2dbase.h index c3a4b7b7..00780a87 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -417,9 +417,6 @@ private: // 更新监听器 static void __updateListeners(); - // 清空监听器 - static void __clearListeners(); - private: IDirectInput8* _directInput; IDirectInputDevice8* _keyboardDevice; diff --git a/core/e2dcollider.h b/core/e2dcollider.h index 4a093db6..80cd0b66 100644 --- a/core/e2dcollider.h +++ b/core/e2dcollider.h @@ -5,15 +5,13 @@ namespace e2d { - - +class Node; class Listener; class ColliderManager; // 碰撞事件 class Collision { - friend class Game; friend class ColliderManager; public: @@ -117,9 +115,6 @@ private: Node * active, Node * passive ); - - // 清空监听器 - static void __clearListeners(); }; } \ No newline at end of file diff --git a/core/e2dmanager.h b/core/e2dmanager.h index d80ff1f7..2f41fd3a 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -23,42 +23,57 @@ class SceneManager friend class Renderer; public: + // 获取场景管理器实例 + static SceneManager * getInstance(); + + // 销毁实例 + static void destroyInstance(); + // 切换场景 - static void enter( + void enter( Scene * scene, /* 下一个场景的指针 */ Transition * transition = nullptr, /* 场景切换动作 */ bool saveCurrentScene = true /* 是否保存当前场景 */ ); // 返回上一场景 - static void back( + void back( Transition * transition = nullptr /* 场景切换动作 */ ); // 清空保存的所有场景 - static void clear(); + void clear(); // 获取当前场景 - static Scene * getCurrentScene(); + Scene * getCurrentScene(); // 获取场景栈 - static std::stack getSceneStack(); + std::stack getSceneStack(); // 是否正在进行转场动作 - static bool isTransitioning(); + bool isTransitioning(); private: + SceneManager(); + + ~SceneManager(); + + E2D_DISABLE_COPY(SceneManager); + // 更新场景内容 - static void __update(); + void __update(); // 渲染场景画面 - static void __render(); + void __render(); - // 初始化场景 - static bool __init(); +private: + bool _saveCurrScene; + Scene * _currScene; + Scene * _nextScene; + Transition * _transition; + std::stack _scenes; - // 回收场景资源 - static void __uninit(); + static SceneManager * _instance; }; @@ -171,21 +186,39 @@ class ColliderManager friend class Node; friend class Collider; +public: + // 获取碰撞体管理器实例 + static ColliderManager * getInstance(); + + // 销毁实例 + static void destroyInstance(); + private: + ColliderManager(); + + ~ColliderManager(); + + E2D_DISABLE_COPY(ColliderManager); + // 更新碰撞体 - static void __updateCollider( + void __updateCollider( Collider * pActiveCollider ); // 添加碰撞体 - static void __add( + void __add( Collider * pCollider ); // 删除已绑定的碰撞体 - static void __remove( + void __remove( Collider * pCollider ); + +private: + std::vector _colliders; + + static ColliderManager * _instance; }; } \ No newline at end of file diff --git a/core/e2dtool.h b/core/e2dtool.h index bc8fbbaa..7714f090 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -324,9 +324,6 @@ private: // 重置定时器状态 static void __resetAll(); - - // 清空定时器 - static void __uninit(); };