Magic_Game/core/Base/Game.cpp

312 lines
5.0 KiB
C++
Raw Normal View History

2018-04-21 21:24:46 +08:00
#include "..\e2dbase.h"
2018-08-15 23:30:23 +08:00
#include "..\e2dnode.h"
#include "..\e2dtransition.h"
2018-04-21 21:24:46 +08:00
#include "..\e2dmanager.h"
2018-04-24 09:02:06 +08:00
#include "..\e2dtool.h"
#include <thread>
2018-01-30 16:45:38 +08:00
2018-07-03 01:49:20 +08:00
e2d::Game::Game()
2018-07-24 12:49:32 +08:00
: _quit(true)
2018-07-03 01:49:20 +08:00
, _paused(false)
2018-07-24 12:49:32 +08:00
, _config()
2018-08-15 00:06:03 +08:00
, _window(nullptr)
, _input(nullptr)
, _renderer(nullptr)
2018-08-15 23:30:23 +08:00
, _currScene(nullptr)
, _nextScene(nullptr)
, _transition(nullptr)
, _scenes()
2018-07-03 01:49:20 +08:00
{
2018-07-04 15:33:09 +08:00
CoInitialize(nullptr);
2018-08-15 00:06:03 +08:00
_input = new (std::nothrow) Input;
_renderer = new (std::nothrow) Renderer;
2018-07-03 01:49:20 +08:00
}
e2d::Game::~Game()
{
2018-08-15 00:06:03 +08:00
if (_renderer)
delete _renderer;
if (_input)
delete _input;
if (_window)
delete _window;
2018-07-04 15:33:09 +08:00
CoUninitialize();
}
2018-07-03 01:49:20 +08:00
e2d::Game * e2d::Game::getInstance()
{
2018-08-15 00:06:03 +08:00
static Game instance;
return &instance;
}
void e2d::Game::start()
2018-01-30 16:45:38 +08:00
{
2018-08-02 00:27:45 +08:00
_quit = false;
2018-08-02 00:27:45 +08:00
const int minInterval = 5;
Time last = Time::now();
2018-08-15 00:06:03 +08:00
HWND hWnd = _window->getHWnd();
2018-08-02 00:27:45 +08:00
::ShowWindow(hWnd, SW_SHOWNORMAL);
::UpdateWindow(hWnd);
2018-08-15 00:06:03 +08:00
_window->poll();
2018-08-15 23:30:23 +08:00
updateScene();
2018-07-29 01:43:15 +08:00
2018-07-24 12:49:32 +08:00
while (!_quit)
2018-01-30 16:45:38 +08:00
{
2018-08-02 00:27:45 +08:00
auto now = Time::now();
auto dur = now - last;
2018-01-30 16:45:38 +08:00
2018-08-02 00:27:45 +08:00
if (dur.milliseconds() > minInterval)
2018-01-30 16:45:38 +08:00
{
2018-08-02 00:27:45 +08:00
last = now;
2018-08-15 00:06:03 +08:00
_input->update();
2018-07-29 01:43:15 +08:00
Timer::getInstance()->update();
ActionManager::getInstance()->update();
2018-08-15 23:30:23 +08:00
updateScene();
drawScene();
2018-08-15 00:06:03 +08:00
_window->poll();
2018-07-29 01:43:15 +08:00
GC::getInstance()->flush();
2018-01-30 16:45:38 +08:00
}
else
{
// ID2D1HwndRenderTarget <20><><EFBFBD><EFBFBD><EFBFBD>˴<EFBFBD>ֱͬ<D6B1><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦʱ<C8BE><CAB1><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>ʾ<EFBFBD><CABE>ˢ<EFBFBD>£<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˷dz<CBB7><C7B3>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>Դ󲿷<D4B4>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳̽<DFB3><CCBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
// <20><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<D2BB><D0A9><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><E7B4B0><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣߳<DFB3><CCA3><EFBFBD>ֹռ<D6B9>ù<EFBFBD><C3B9><EFBFBD> CPU <20><>
2018-08-02 00:27:45 +08:00
int wait = minInterval - dur.milliseconds();
if (wait > 1)
{
std::this_thread::sleep_for(std::chrono::milliseconds(wait));
}
2018-01-30 16:45:38 +08:00
}
}
}
void e2d::Game::pause()
2018-01-30 16:45:38 +08:00
{
2018-07-03 01:49:20 +08:00
_paused = true;
2018-01-30 16:45:38 +08:00
}
void e2d::Game::resume()
2018-01-30 16:45:38 +08:00
{
2018-07-24 12:49:32 +08:00
if (_paused && !_quit)
2018-05-24 00:58:16 +08:00
{
Timer::getInstance()->updateTime();
ActionManager::getInstance()->updateTime();
2018-05-24 00:58:16 +08:00
}
2018-07-05 16:44:47 +08:00
_paused = false;
}
bool e2d::Game::isPaused()
2018-01-30 16:45:38 +08:00
{
2018-07-03 01:49:20 +08:00
return _paused;
2018-01-30 16:45:38 +08:00
}
2018-07-24 12:49:32 +08:00
void e2d::Game::setConfig(const Config& config)
2018-07-04 17:00:21 +08:00
{
2018-07-24 20:21:25 +08:00
_config = config;
2018-07-04 17:00:21 +08:00
}
2018-08-15 00:06:03 +08:00
const e2d::Config& e2d::Game::getConfig() const
2018-07-04 17:00:21 +08:00
{
return _config;
}
2018-08-15 00:06:03 +08:00
void e2d::Game::setWindow(Window * window)
{
_window = window;
_renderer->init(_window);
_input->init(_window);
}
void e2d::Game::quit()
2018-01-30 16:45:38 +08:00
{
2018-07-24 12:49:32 +08:00
_quit = true;
2018-01-30 16:45:38 +08:00
}
2018-08-15 23:30:23 +08:00
void e2d::Game::pushScene(Scene * scene, bool saveCurrentScene)
2018-01-30 16:45:38 +08:00
{
2018-08-15 23:30:23 +08:00
if (!scene)
return;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
if (_nextScene) _nextScene->release();
_nextScene = scene;
_nextScene->retain();
if (saveCurrentScene && _currScene)
{
_scenes.push(_currScene);
}
}
void e2d::Game::pushScene(Transition * transition, bool saveCurrentScene)
{
if (!transition)
return;
pushScene(transition->_inScene, saveCurrentScene);
if (_transition)
{
_transition->_stop();
_transition->release();
}
_transition = transition;
_transition->retain();
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>
if (!_transition->_init(_currScene))
{
WARN("Transition initialize failed!");
_transition->release();
_transition = nullptr;
}
}
e2d::Scene* e2d::Game::popScene()
{
// ջΪ<D5BB><CEAA>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7>س<EFBFBD><D8B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
if (_scenes.size() == 0)
{
WARN("Scene stack is empty!");
return nullptr;
}
_nextScene = _scenes.top();
_nextScene->release();
_scenes.pop();
return _nextScene;
}
e2d::Scene * e2d::Game::popScene(Transition * transition)
{
if (!transition)
return nullptr;
auto scene = popScene();
if (scene)
{
if (_transition)
{
_transition->_stop();
_transition->release();
}
_transition = transition;
_transition->retain();
_transition->_inScene = scene;
_transition->_inScene->retain();
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>
if (!_transition->_init(_currScene))
{
WARN("Transition initialize failed!");
_transition->release();
_transition = nullptr;
}
}
return scene;
}
void e2d::Game::clearAllScenes()
{
while (!_scenes.empty())
{
_scenes.top()->release();
_scenes.pop();
}
}
e2d::Scene * e2d::Game::getCurrentScene()
{
return _currScene;
}
const std::stack<e2d::Scene*>& e2d::Game::getSceneStack()
{
return _scenes;
}
bool e2d::Game::isTransitioning() const
{
return _transition != nullptr;
}
void e2d::Game::updateScene()
{
if (_transition)
{
_transition->_update();
if (_transition->isDone())
{
_transition->release();
_transition = nullptr;
}
else
{
return;
}
}
if (_nextScene)
{
if (_currScene)
{
_currScene->onExit();
if (_scenes.empty() || _scenes.top() != _currScene)
{
_currScene->release();
}
}
_nextScene->onEnter();
_currScene = _nextScene;
_nextScene = nullptr;
}
}
void e2d::Game::drawScene()
{
// <20><>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD>
_renderer->beginDraw();
{
if (_transition)
{
_transition->_render();
}
else if (_currScene)
{
_currScene->visit(_renderer);
if (_config.isOutlineVisible())
{
auto brush = _renderer->getSolidColorBrush();
brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f));
brush->SetOpacity(1.f);
_currScene->drawOutline(_renderer);
}
if (_config.isColliderVisible())
{
_renderer->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
_currScene->drawCollider();
}
}
if (_config.isFpsShow())
{
_renderer->drawFps();
}
}
_renderer->endDraw();
2018-01-30 16:45:38 +08:00
}