SceneManager和ColliderManager单例模式重做

This commit is contained in:
Nomango 2018-07-05 16:34:53 +08:00
parent 4dc25a606d
commit caf6297bf1
17 changed files with 205 additions and 167 deletions

View File

@ -13,7 +13,9 @@ e2d::GC::~GC()
Input::destroyInstance(); Input::destroyInstance();
Window::destroyInstance(); Window::destroyInstance();
Player::destroyInstance(); Player::destroyInstance();
SceneManager::destroyInstance();
ActionManager::destroyInstance(); ActionManager::destroyInstance();
ColliderManager::destroyInstance();
} }

View File

@ -44,9 +44,8 @@ void e2d::Game::start(bool cleanup)
auto window = Window::getInstance(); auto window = Window::getInstance();
auto renderer = Renderer::getInstance(); auto renderer = Renderer::getInstance();
auto actionManager = ActionManager::getInstance(); auto actionManager = ActionManager::getInstance();
auto sceneManager = SceneManager::getInstance();
// 初始化场景管理器
SceneManager::__init();
// 显示窗口 // 显示窗口
::ShowWindow(window->getHWnd(), SW_SHOWNORMAL); ::ShowWindow(window->getHWnd(), SW_SHOWNORMAL);
// 刷新窗口内容 // 刷新窗口内容
@ -77,7 +76,7 @@ void e2d::Game::start(bool cleanup)
input->__update(); // 获取用户输入 input->__update(); // 获取用户输入
Timer::__update(); // 更新定时器 Timer::__update(); // 更新定时器
actionManager->__update(); // 更新动作管理器 actionManager->__update(); // 更新动作管理器
SceneManager::__update(); // 更新场景内容 sceneManager->__update(); // 更新场景内容
renderer->__render(); // 渲染游戏画面 renderer->__render(); // 渲染游戏画面
Time::__updateLast(); // 刷新时间信息 Time::__updateLast(); // 刷新时间信息
@ -116,8 +115,8 @@ void e2d::Game::reset()
if (!_ended) if (!_ended)
{ {
Time::__reset(); Time::__reset();
ActionManager::getInstance()->__resetAll();
Timer::__resetAll(); Timer::__resetAll();
ActionManager::getInstance()->__resetAll();
} }
} }
@ -155,15 +154,15 @@ void e2d::Game::quit()
void e2d::Game::cleanup() void e2d::Game::cleanup()
{ {
// 删除所有场景 // 删除所有场景
SceneManager::__uninit(); SceneManager::getInstance()->clear();
// 删除输入监听器
Input::__clearListeners();
// 删除碰撞监听器 // 删除碰撞监听器
Collision::__clearListeners(); Collision::removeAllListeners();
// 删除输入监听器
Input::removeAllListeners();
// 清空图片缓存 // 清空图片缓存
Image::clearCache(); Image::clearCache();
// 清空定时器 // 清空定时器
Timer::__uninit(); Timer::removeAll();
// 删除所有对象 // 删除所有对象
GC::getInstance()->clear(); GC::getInstance()->clear();
} }

View File

@ -330,8 +330,9 @@ void e2d::Input::removeAllListeners()
{ {
for (auto listener : s_vListeners) for (auto listener : s_vListeners)
{ {
listener->_stopped = true; GC::release(listener);
} }
s_vListeners.clear();
} }
void e2d::Input::__updateListeners() 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();
}

View File

@ -131,7 +131,7 @@ void e2d::Renderer::__render()
_renderTarget->Clear(_clearColor); _renderTarget->Clear(_clearColor);
// äÖȾ³¡¾° // äÖȾ³¡¾°
SceneManager::__render(); SceneManager::getInstance()->__render();
// äÖȾ FPS // äÖȾ FPS
if (_showFps) if (_showFps)

View File

@ -436,7 +436,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
// 窗口关闭消息 // 窗口关闭消息
case WM_CLOSE: case WM_CLOSE:
{ {
e2d::Scene * pCurrentScene = e2d::SceneManager::getCurrentScene(); e2d::Scene * pCurrentScene = e2d::SceneManager::getInstance()->getCurrentScene();
if (!pCurrentScene || pCurrentScene->onCloseWindow()) if (!pCurrentScene || pCurrentScene->onCloseWindow())
{ {
e2d::Game::getInstance()->quit(); e2d::Game::getInstance()->quit();

View File

@ -212,14 +212,6 @@ void e2d::Collision::startAllListeners()
} }
void e2d::Collision::removeAllListeners() void e2d::Collision::removeAllListeners()
{
for (auto listener : s_vListeners)
{
listener->_stopped = true;
}
}
void e2d::Collision::__clearListeners()
{ {
for (auto listener : s_vListeners) for (auto listener : s_vListeners)
{ {

View File

@ -172,6 +172,6 @@ void e2d::Collider::_transform()
&_transformed &_transformed
); );
// 通知碰撞体管理器 // 通知碰撞体管理器
ColliderManager::__updateCollider(this); ColliderManager::getInstance()->__updateCollider(this);
} }
} }

View File

@ -215,26 +215,38 @@ void e2d::ActionManager::clearAllBindedWith(Node * target)
void e2d::ActionManager::resumeAll() void e2d::ActionManager::resumeAll()
{ {
for (auto child : SceneManager::getCurrentScene()->getRoot()->getAllChildren()) auto scene = SceneManager::getInstance()->getCurrentScene();
if (scene)
{
for (auto child : scene->getRoot()->getAllChildren())
{ {
ActionManager::resumeAllBindedWith(child); ActionManager::resumeAllBindedWith(child);
} }
}
} }
void e2d::ActionManager::pauseAll() void e2d::ActionManager::pauseAll()
{ {
for (auto child : SceneManager::getCurrentScene()->getRoot()->getAllChildren()) auto scene = SceneManager::getInstance()->getCurrentScene();
if (scene)
{
for (auto child : scene->getRoot()->getAllChildren())
{ {
ActionManager::pauseAllBindedWith(child); ActionManager::pauseAllBindedWith(child);
} }
}
} }
void e2d::ActionManager::stopAll() void e2d::ActionManager::stopAll()
{ {
for (auto child : SceneManager::getCurrentScene()->getRoot()->getAllChildren()) auto scene = SceneManager::getInstance()->getCurrentScene();
if (scene)
{
for (auto child : scene->getRoot()->getAllChildren())
{ {
ActionManager::stopAllBindedWith(child); ActionManager::stopAllBindedWith(child);
} }
}
} }
std::vector<e2d::Action*> e2d::ActionManager::get(const String& name) std::vector<e2d::Action*> e2d::ActionManager::get(const String& name)

View File

@ -4,8 +4,32 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
// ÅöײÌ弯ºÏ e2d::ColliderManager * e2d::ColliderManager::_instance = nullptr;
static std::vector<e2d::Collider*> s_vColliders;
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) void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
{ {
@ -20,9 +44,9 @@ void e2d::ColliderManager::__updateCollider(e2d::Collider * pActiveCollider)
Scene* pCurrentScene = pActiveNode->getParentScene(); 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) if (pActiveCollider == pPassiveCollider)
continue; continue;
@ -55,7 +79,7 @@ void e2d::ColliderManager::__add(Collider * pCollider)
if (pCollider) if (pCollider)
{ {
pCollider->retain(); pCollider->retain();
s_vColliders.push_back(pCollider); _colliders.push_back(pCollider);
} }
} }
@ -63,12 +87,12 @@ void e2d::ColliderManager::__remove(Collider * pCollider)
{ {
if (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); GC::release(pCollider);
s_vColliders.erase(s_vColliders.begin() + i); _colliders.erase(_colliders.begin() + i);
return; return;
} }
} }

View File

@ -2,65 +2,89 @@
#include "..\e2dbase.h" #include "..\e2dbase.h"
#include "..\e2dtransition.h" #include "..\e2dtransition.h"
static bool s_bSaveCurrScene = true;
static e2d::Scene * s_pCurrScene = nullptr; e2d::SceneManager * e2d::SceneManager::_instance = nullptr;
static e2d::Scene * s_pNextScene = nullptr;
static e2d::Transition * s_pTransition = nullptr; e2d::SceneManager * e2d::SceneManager::getInstance()
static std::stack<e2d::Scene*> s_SceneStack; {
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 */) void e2d::SceneManager::enter(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */)
{ {
if (scene == nullptr) if (!scene)
{ return;
throw Exception(L"场景空指针异常");
}
// 保存下一场景的指针 // 保存下一场景的指针
s_pNextScene = scene; _nextScene = scene;
s_pNextScene->retain(); _nextScene->retain();
// 设置切换场景动作 // 设置切换场景动作
if (transition) if (transition)
{ {
if (s_pTransition) if (_transition)
{ {
s_pTransition->_stop(); _transition->_stop();
s_pTransition->release(); _transition->release();
} }
s_pTransition = transition; _transition = transition;
transition->retain(); transition->retain();
transition->_init(s_pCurrScene, s_pNextScene); transition->_init(_currScene, _nextScene);
transition->_update(); transition->_update();
} }
if (s_pCurrScene) if (_currScene)
{ {
s_bSaveCurrScene = saveCurrentScene; _saveCurrScene = saveCurrentScene;
} }
} }
void e2d::SceneManager::back(Transition * transition /* = nullptr */) void e2d::SceneManager::back(Transition * transition /* = nullptr */)
{ {
// 栈为空时,调用返回场景函数失败 // 栈为空时,调用返回场景函数失败
WARN_IF(s_SceneStack.size() == 0, "Scene stack is empty!"); WARN_IF(_scenes.size() == 0, "Scene stack is empty!");
if (s_SceneStack.size() == 0) return; if (_scenes.size() == 0) return;
// 从栈顶取出场景指针,作为下一场景 // 从栈顶取出场景指针,作为下一场景
s_pNextScene = s_SceneStack.top(); _nextScene = _scenes.top();
s_SceneStack.pop(); _scenes.pop();
// 返回上一场景时,不保存当前场景 // 返回上一场景时,不保存当前场景
if (s_pCurrScene) if (_currScene)
{ {
s_bSaveCurrScene = false; _saveCurrScene = false;
} }
// 设置切换场景动作 // 设置切换场景动作
if (transition) if (transition)
{ {
s_pTransition = transition; _transition = transition;
transition->retain(); transition->retain();
transition->_init(s_pCurrScene, s_pNextScene); transition->_init(_currScene, _nextScene);
transition->_update(); transition->_update();
} }
} }
@ -68,48 +92,48 @@ void e2d::SceneManager::back(Transition * transition /* = nullptr */)
void e2d::SceneManager::clear() void e2d::SceneManager::clear()
{ {
// 清空场景栈 // 清空场景栈
while (s_SceneStack.size()) while (_scenes.size())
{ {
auto temp = s_SceneStack.top(); auto temp = _scenes.top();
GC::release(temp); GC::release(temp);
s_SceneStack.pop(); _scenes.pop();
} }
} }
e2d::Scene * e2d::SceneManager::getCurrentScene() e2d::Scene * e2d::SceneManager::getCurrentScene()
{ {
return s_pCurrScene; return _currScene;
} }
std::stack<e2d::Scene*> e2d::SceneManager::getSceneStack() std::stack<e2d::Scene*> e2d::SceneManager::getSceneStack()
{ {
return s_SceneStack; return _scenes;
} }
bool e2d::SceneManager::isTransitioning() bool e2d::SceneManager::isTransitioning()
{ {
return s_pTransition != nullptr; return _transition != nullptr;
} }
void e2d::SceneManager::__update() void e2d::SceneManager::__update()
{ {
if (s_pTransition == nullptr) if (_transition == nullptr)
{ {
// 更新场景内容 // 更新场景内容
if (s_pCurrScene) if (_currScene)
{ {
s_pCurrScene->_update(); _currScene->_update();
} }
} }
else else
{ {
// 更新场景动作 // 更新场景动作
s_pTransition->_update(); _transition->_update();
if (s_pTransition->isDone()) if (_transition->isDone())
{ {
s_pTransition->release(); _transition->release();
s_pTransition = nullptr; _transition = nullptr;
} }
else else
{ {
@ -118,65 +142,44 @@ void e2d::SceneManager::__update()
} }
// 下一场景指针不为空时,切换场景 // 下一场景指针不为空时,切换场景
if (s_pNextScene) if (_nextScene)
{
if (_currScene)
{ {
// 执行当前场景的 onExit 函数 // 执行当前场景的 onExit 函数
s_pCurrScene->onExit(); _currScene->onExit();
// 若要保存当前场景,把它放入栈中 // 若要保存当前场景,把它放入栈中
if (s_bSaveCurrScene) if (_saveCurrScene)
{ {
s_SceneStack.push(s_pCurrScene); _scenes.push(_currScene);
} }
else else
{ {
GC::release(s_pCurrScene); _currScene->release();
}
} }
// 执行下一场景的 onEnter 函数 // 执行下一场景的 onEnter 函数
s_pNextScene->onEnter(); _nextScene->onEnter();
s_pCurrScene = s_pNextScene; // 切换场景 _currScene = _nextScene; // Çл»³¡¾°
s_pNextScene = nullptr; // 下一场景置空 _nextScene = nullptr; // ÏÂÒ»³¡¾°ÖÿÕ
} }
} }
void e2d::SceneManager::__render() void e2d::SceneManager::__render()
{ {
if (s_pTransition) if (_transition)
{ {
s_pTransition->_render(); _transition->_render();
} }
else 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();
}

View File

@ -177,7 +177,7 @@ void e2d::Button::setClickFunc(const Function& func)
void e2d::Button::_fixedUpdate() void e2d::Button::_fixedUpdate()
{ {
if (SceneManager::isTransitioning()) if (SceneManager::getInstance()->isTransitioning())
return; return;
auto input = Input::getInstance(); auto input = Input::getInstance();

View File

@ -559,7 +559,7 @@ void e2d::Node::setColliderType(Collider::Type type)
default: default:
{ {
// 删除碰撞体 // 删除碰撞体
ColliderManager::__remove(_collider); ColliderManager::getInstance()->__remove(_collider);
_collider = nullptr; _collider = nullptr;
} }
break; break;
@ -577,7 +577,7 @@ void e2d::Node::setColliderType(Collider::Type type)
this->_collider->_parentNode = this; this->_collider->_parentNode = this;
this->_collider->_recreate(type); this->_collider->_recreate(type);
// 添加新的碰撞体 // 添加新的碰撞体
ColliderManager::__add(this->_collider); ColliderManager::getInstance()->__add(this->_collider);
} }
break; break;
@ -911,7 +911,7 @@ void e2d::Node::setAutoUpdate(bool bAutoUpdate)
void e2d::Node::onDestroy() void e2d::Node::onDestroy()
{ {
ActionManager::getInstance()->clearAllBindedWith(this); ActionManager::getInstance()->clearAllBindedWith(this);
ColliderManager::__remove(_collider); ColliderManager::getInstance()->__remove(_collider);
for (auto child : _children) for (auto child : _children)
{ {
GC::release(child); GC::release(child);

View File

@ -138,8 +138,9 @@ void e2d::Timer::removeAll()
{ {
for (auto timer : s_vTimers) for (auto timer : s_vTimers)
{ {
timer->stopped = true; delete timer;
} }
s_vTimers.clear();
} }
void e2d::Timer::__update() void e2d::Timer::__update()
@ -176,12 +177,3 @@ void e2d::Timer::__resetAll()
timer->lastTime = Time::getTotalTime(); timer->lastTime = Time::getTotalTime();
} }
} }
void e2d::Timer::__uninit()
{
for (auto timer : s_vTimers)
{
delete timer;
}
s_vTimers.clear();
}

View File

@ -417,9 +417,6 @@ private:
// 更新监听器 // 更新监听器
static void __updateListeners(); static void __updateListeners();
// 清空监听器
static void __clearListeners();
private: private:
IDirectInput8* _directInput; IDirectInput8* _directInput;
IDirectInputDevice8* _keyboardDevice; IDirectInputDevice8* _keyboardDevice;

View File

@ -5,15 +5,13 @@
namespace e2d namespace e2d
{ {
class Node;
class Listener; class Listener;
class ColliderManager; class ColliderManager;
// 碰撞事件 // 碰撞事件
class Collision class Collision
{ {
friend class Game;
friend class ColliderManager; friend class ColliderManager;
public: public:
@ -117,9 +115,6 @@ private:
Node * active, Node * active,
Node * passive Node * passive
); );
// 清空监听器
static void __clearListeners();
}; };
} }

View File

@ -23,42 +23,57 @@ class SceneManager
friend class Renderer; friend class Renderer;
public: public:
// 获取场景管理器实例
static SceneManager * getInstance();
// 销毁实例
static void destroyInstance();
// 切换场景 // 切换场景
static void enter( void enter(
Scene * scene, /* 下一个场景的指针 */ Scene * scene, /* 下一个场景的指针 */
Transition * transition = nullptr, /* 场景切换动作 */ Transition * transition = nullptr, /* 场景切换动作 */
bool saveCurrentScene = true /* 是否保存当前场景 */ bool saveCurrentScene = true /* 是否保存当前场景 */
); );
// 返回上一场景 // 返回上一场景
static void back( void back(
Transition * transition = nullptr /* 场景切换动作 */ Transition * transition = nullptr /* 场景切换动作 */
); );
// 清空保存的所有场景 // 清空保存的所有场景
static void clear(); void clear();
// 获取当前场景 // 获取当前场景
static Scene * getCurrentScene(); Scene * getCurrentScene();
// 获取场景栈 // 获取场景栈
static std::stack<Scene*> getSceneStack(); std::stack<Scene*> getSceneStack();
// 是否正在进行转场动作 // 是否正在进行转场动作
static bool isTransitioning(); bool isTransitioning();
private: private:
SceneManager();
~SceneManager();
E2D_DISABLE_COPY(SceneManager);
// 更新场景内容 // 更新场景内容
static void __update(); void __update();
// 渲染场景画面 // 渲染场景画面
static void __render(); void __render();
// ³õʼ»¯³¡¾° private:
static bool __init(); bool _saveCurrScene;
Scene * _currScene;
Scene * _nextScene;
Transition * _transition;
std::stack<Scene*> _scenes;
// »ØÊÕ³¡¾°×ÊÔ´ static SceneManager * _instance;
static void __uninit();
}; };
@ -171,21 +186,39 @@ class ColliderManager
friend class Node; friend class Node;
friend class Collider; friend class Collider;
public:
// 获取碰撞体管理器实例
static ColliderManager * getInstance();
// 销毁实例
static void destroyInstance();
private: private:
ColliderManager();
~ColliderManager();
E2D_DISABLE_COPY(ColliderManager);
// 更新碰撞体 // 更新碰撞体
static void __updateCollider( void __updateCollider(
Collider * pActiveCollider Collider * pActiveCollider
); );
// 添加碰撞体 // 添加碰撞体
static void __add( void __add(
Collider * pCollider Collider * pCollider
); );
// 删除已绑定的碰撞体 // 删除已绑定的碰撞体
static void __remove( void __remove(
Collider * pCollider Collider * pCollider
); );
private:
std::vector<Collider*> _colliders;
static ColliderManager * _instance;
}; };
} }

View File

@ -324,9 +324,6 @@ private:
// 重置定时器状态 // 重置定时器状态
static void __resetAll(); static void __resetAll();
// 清空定时器
static void __uninit();
}; };