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();
Window::destroyInstance();
Player::destroyInstance();
SceneManager::destroyInstance();
ActionManager::destroyInstance();
ColliderManager::destroyInstance();
}

View File

@ -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();
}

View File

@ -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();
}

View File

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

View File

@ -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();

View File

@ -212,14 +212,6 @@ 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)
{

View File

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

View File

@ -215,27 +215,39 @@ void e2d::ActionManager::clearAllBindedWith(Node * target)
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);
}
}
}
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);
}
}
}
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);
}
}
}
std::vector<e2d::Action*> e2d::ActionManager::get(const String& name)
{

View File

@ -4,8 +4,32 @@
#include "..\e2dtool.h"
// ÅöײÌ弯ºÏ
static std::vector<e2d::Collider*> 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;
}
}

View File

@ -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<e2d::Scene*> 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::Scene*> 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)
{
if (_currScene)
{
// 执行当前场景的 onExit 函数
s_pCurrScene->onExit();
_currScene->onExit();
// 若要保存当前场景,把它放入栈中
if (s_bSaveCurrScene)
if (_saveCurrScene)
{
s_SceneStack.push(s_pCurrScene);
_scenes.push(_currScene);
}
else
{
GC::release(s_pCurrScene);
_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();
}

View File

@ -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();

View File

@ -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);

View File

@ -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();
}

View File

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

View File

@ -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();
};
}

View File

@ -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<Scene*> getSceneStack();
std::stack<Scene*> 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<Scene*> _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<Collider*> _colliders;
static ColliderManager * _instance;
};
}

View File

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