diff --git a/core/Action/Action.cpp b/core/Action/Action.cpp index 8ddd2cdb..24238d82 100644 --- a/core/Action/Action.cpp +++ b/core/Action/Action.cpp @@ -6,7 +6,6 @@ e2d::Action::Action() , _done(false) , _initialized(false) , _target(nullptr) - , _last(0) { ActionManager::getInstance()->__add(this); } @@ -24,7 +23,6 @@ bool e2d::Action::isRunning() void e2d::Action::resume() { _running = true; - _last = Game::getInstance()->getTotalDuration().seconds(); } void e2d::Action::pause() @@ -56,7 +54,7 @@ void e2d::Action::reset() { _initialized = false; _done = false; - _last = Game::getInstance()->getTotalDuration().seconds(); + _started = Time::now(); } bool e2d::Action::_isDone() @@ -74,7 +72,7 @@ void e2d::Action::_startWithTarget(Node* target) void e2d::Action::_init() { _initialized = true; - _last = Game::getInstance()->getTotalDuration().seconds(); + _started = Time::now(); } void e2d::Action::_update() diff --git a/core/Action/Animate.cpp b/core/Action/Animate.cpp index 61075af6..385b9b46 100644 --- a/core/Action/Animate.cpp +++ b/core/Action/Animate.cpp @@ -56,8 +56,7 @@ void e2d::Animate::_update() return; } - auto game = Game::getInstance(); - while ((game->getTotalDuration().seconds() - _last) >= _animation->getInterval()) + while ((Time::now() - _started).seconds() >= _animation->getInterval()) { auto& frames = _animation->getFrames(); auto target = dynamic_cast(_target); @@ -67,7 +66,7 @@ void e2d::Animate::_update() target->open(frames[_frameIndex]); } - _last += _animation->getInterval(); + _started += Duration(_animation->getInterval()); ++_frameIndex; if (_frameIndex == frames.size()) @@ -81,7 +80,6 @@ void e2d::Animate::_update() void e2d::Animate::_resetTime() { Action::_resetTime(); - _last = Game::getInstance()->getTotalDuration().seconds(); } void e2d::Animate::reset() diff --git a/core/Action/Delay.cpp b/core/Action/Delay.cpp index 0198b65b..1f29436b 100644 --- a/core/Action/Delay.cpp +++ b/core/Action/Delay.cpp @@ -31,7 +31,7 @@ void e2d::Delay::_update() { Action::_update(); - _delta = Game::getInstance()->getTotalDuration().seconds() - _last; + _delta = (Time::now() - _started).seconds(); if (_delta >= _delay) { @@ -42,5 +42,5 @@ void e2d::Delay::_update() void e2d::Delay::_resetTime() { Action::_resetTime(); - _last = Game::getInstance()->getTotalDuration().seconds() - _delta; + _started = Time::now() - Duration(_delta); } diff --git a/core/Action/FiniteTimeAction.cpp b/core/Action/FiniteTimeAction.cpp index dd1fb98a..becd7b7c 100644 --- a/core/Action/FiniteTimeAction.cpp +++ b/core/Action/FiniteTimeAction.cpp @@ -28,7 +28,7 @@ void e2d::FiniteTimeAction::_update() } else { - _delta = std::min((Game::getInstance()->getTotalDuration().seconds() - _last) / _duration, 1.f); + _delta = std::min((Time::now() - _started).seconds() / _duration, 1.f); if (_delta >= 1) { @@ -40,5 +40,5 @@ void e2d::FiniteTimeAction::_update() void e2d::FiniteTimeAction::_resetTime() { Action::_resetTime(); - _last = Game::getInstance()->getTotalDuration().seconds() - _delta * _duration; + _started = Time::now() - Duration(_delta * _duration); } diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 352129ec..4c7d80ca 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -12,8 +12,6 @@ e2d::Game::Game() , _config() { CoInitialize(nullptr); - - _start = _last = _now = Time::now(); } e2d::Game::~Game() @@ -39,26 +37,25 @@ void e2d::Game::destroyInstance() void e2d::Game::start() { - SceneManager::getInstance()->update(); + _quit = false; + const int minInterval = 5; + Time last = Time::now(); HWND hWnd = Window::getInstance()->getHWnd(); + ::ShowWindow(hWnd, SW_SHOWNORMAL); ::UpdateWindow(hWnd); Window::getInstance()->poll(); - - _quit = false; - _last = _now = Time::now(); - - const Duration minInterval(15); + SceneManager::getInstance()->update(); while (!_quit) { - _now = Time::now(); - Duration interval = _now - _last; + auto now = Time::now(); + auto dur = now - last; - if (minInterval < interval) + if (dur.milliseconds() > minInterval) { - _last = _now; + last = now; Input::getInstance()->update(); Timer::getInstance()->update(); ActionManager::getInstance()->update(); @@ -72,7 +69,7 @@ void e2d::Game::start() // ID2D1HwndRenderTarget 在渲染时会等待显示器刷新,即开启了垂直同步, // 它起到了非常稳定的延时作用,所以大部分时候不需要手动挂起线程进行延时。 // 下面的代码仅在一些情况下(例如窗口最小化时)挂起线程,防止占用过高 CPU 。 - int wait = (minInterval - interval).milliseconds(); + int wait = minInterval - dur.milliseconds(); if (wait > 1) { std::this_thread::sleep_for(std::chrono::milliseconds(wait)); @@ -90,7 +87,6 @@ void e2d::Game::resume() { if (_paused && !_quit) { - _last = _now = Time::now(); Timer::getInstance()->updateTime(); ActionManager::getInstance()->updateTime(); } @@ -120,11 +116,6 @@ const e2d::Config& e2d::Game::getConfig() return _config; } -e2d::Duration e2d::Game::getTotalDuration() const -{ - return std::move(_now - _start); -} - void e2d::Game::quit() { _quit = true; diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index 87b9f6cc..6d7e7369 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -107,15 +107,14 @@ void e2d::Renderer::render() void e2d::Renderer::_renderFps() { - ++_renderTimes; + int duration = (Time::now() - _lastRenderTime).milliseconds(); - auto& now = Time::now(); - int duration = (now - _lastRenderTime).milliseconds(); + ++_renderTimes; if (duration >= 100) { - String fpsText = String::format(L"FPS: %.1f", (1000.f / duration * _renderTimes)); - _renderTimes = 0; - _lastRenderTime = now; + String fpsText = String::format(L"FPS: %.1f", (1000.f / duration * _renderTimes)); + _lastRenderTime = Time::now(); + _renderTimes = 0; auto writeFactory = Renderer::getWriteFactory(); if (!_fpsFormat) diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index 43585eff..dd525cab 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -3,6 +3,9 @@ #include #pragma comment (lib ,"imm32.lib") +#define WINDOW_STYLE WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME +#define REGISTER_CLASS L"Easy2DApp" + e2d::Window * e2d::Window::_instance = nullptr; @@ -51,9 +54,7 @@ bool e2d::Window::createMutex(const String & mutex) if (mutex.isEmpty()) return false; - // 创建进程互斥体 - String fullMutexName = L"Easy2DApp-" + mutex; - HANDLE hMutex = ::CreateMutex(nullptr, TRUE, (LPCWSTR)fullMutexName); + HANDLE hMutex = ::CreateMutex(nullptr, TRUE, LPCWSTR(L"Easy2DApp-" + mutex)); if (hMutex == nullptr) { @@ -68,7 +69,7 @@ bool e2d::Window::createMutex(const String & mutex) if (!this->_title.isEmpty()) { // 获取窗口句柄 - HWND hProgramWnd = ::FindWindow(L"Easy2DApp", (LPCTSTR)this->_title); + HWND hProgramWnd = ::FindWindow(REGISTER_CLASS, (LPCTSTR)_title); if (hProgramWnd) { // 获取窗口显示状态 @@ -85,79 +86,59 @@ bool e2d::Window::createMutex(const String & mutex) return true; } -HWND e2d::Window::__create() +HWND e2d::Window::__registerWindow() { - // 注册窗口类 WNDCLASSEX wcex = { 0 }; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.lpszClassName = L"Easy2DApp"; - wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - wcex.lpfnWndProc = Window::WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = sizeof(LONG_PTR); - wcex.hInstance = HINST_THISCOMPONENT; - wcex.hbrBackground = nullptr; - wcex.lpszMenuName = nullptr; - wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW); + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.lpszClassName = REGISTER_CLASS; + wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wcex.lpfnWndProc = Window::WndProc; + wcex.hIcon = nullptr; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = sizeof(LONG_PTR); + wcex.hInstance = HINST_THISCOMPONENT; + wcex.hbrBackground = nullptr; + wcex.lpszMenuName = nullptr; + wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW); - if (this->_iconID != 0) + if (_iconID != 0) { wcex.hIcon = (HICON)::LoadImage( HINST_THISCOMPONENT, - MAKEINTRESOURCE(this->_iconID), + MAKEINTRESOURCE(_iconID), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE ); } - else - { - wcex.hIcon = nullptr; - } + // 注册窗口类 RegisterClassEx(&wcex); - // 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它 - // 适应窗口缩放 - float dpiScaleX = 0.f, dpiScaleY = 0.f; - Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); - - int nWidth = static_cast(ceil(_size.width * dpiScaleX / 96.f)); - int nHeight = static_cast(ceil(_size.height * dpiScaleY / 96.f)); - // 计算窗口大小 - DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME; - RECT wr = { 0, 0, static_cast(nWidth), static_cast(nHeight) }; - ::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL); - // 获取新的宽高 - nWidth = static_cast(wr.right - wr.left); - nHeight = static_cast(wr.bottom - wr.top); - - // 获取屏幕分辨率 - int screenWidth = ::GetSystemMetrics(SM_CXSCREEN); - int screenHeight = ::GetSystemMetrics(SM_CYSCREEN); + Rect wRect = __adjustWindow(int(_size.width), int(_size.height)); // 创建窗口 HWND hWnd = ::CreateWindowEx( NULL, - L"Easy2DApp", + REGISTER_CLASS, (LPCTSTR)_title, - dwStyle, - (screenWidth - nWidth) / 2, (screenHeight - nHeight) / 2, - nWidth, nHeight, + WINDOW_STYLE, + int(wRect.origin.x), + int(wRect.origin.y), + int(wRect.size.width), + int(wRect.size.height), nullptr, nullptr, HINST_THISCOMPONENT, nullptr ); - HRESULT hr = hWnd ? S_OK : E_FAIL; - - if (SUCCEEDED(hr)) + if (hWnd) { // 禁用输入法 - this->setTypewritingEnabled(false); + setTypewritingEnabled(false); // 禁用控制台关闭按钮 HWND consoleHWnd = ::GetConsoleWindow(); if (consoleHWnd) @@ -170,11 +151,35 @@ HWND e2d::Window::__create() } else { - ::UnregisterClass(L"Easy2DApp", HINST_THISCOMPONENT); + ::UnregisterClass(REGISTER_CLASS, HINST_THISCOMPONENT); } return hWnd; } +e2d::Rect e2d::Window::__adjustWindow(int width, int height) +{ + float dpiScaleX = 0.f, dpiScaleY = 0.f; + Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); + + Rect result; + RECT wRECT = { 0, 0, LONG(ceil(width * dpiScaleX / 96.f)), LONG(ceil(height * dpiScaleY / 96.f)) }; + int maxWidth = ::GetSystemMetrics(SM_CXSCREEN); + int maxHeight = ::GetSystemMetrics(SM_CYSCREEN); + + // 计算合适的窗口大小 + ::AdjustWindowRectEx(&wRECT, WINDOW_STYLE, FALSE, NULL); + width = static_cast(wRECT.right - wRECT.left); + height = static_cast(wRECT.bottom - wRECT.top); + + // 当输入的窗口大小比分辨率大时,给出警告 + WARN_IF(maxWidth < width || maxHeight < height, "The window is larger than screen!"); + width = std::min(width, maxWidth); + height = std::min(height, maxHeight); + + float x = float((maxWidth - width) / 2), y = float((maxHeight - height) / 2); + return std::move(Rect(x, y, float(width), float(height))); +} + void e2d::Window::poll() { while (::PeekMessage(&_msg, nullptr, 0, 0, PM_REMOVE)) @@ -213,7 +218,7 @@ HWND e2d::Window::getHWnd() { if (!_hWnd) { - _hWnd = this->__create(); + _hWnd = __registerWindow(); if (_hWnd == nullptr) { throw SystemException(L"注册窗口失败"); @@ -224,37 +229,24 @@ HWND e2d::Window::getHWnd() void e2d::Window::setSize(int width, int height) { - this->_size = Size(static_cast(width), static_cast(height)); + _size = Size(static_cast(width), static_cast(height)); if (_hWnd) { - float dpiScaleX = 0.f, dpiScaleY = 0.f; - Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); - - width = static_cast(ceil(width * dpiScaleX / 96.f)); - height = static_cast(ceil(height * dpiScaleY / 96.f)); - // 计算窗口大小 - DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME; - RECT wr = { 0, 0, static_cast(width), static_cast(height) }; - ::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL); - // 获取新的宽高 - width = static_cast(wr.right - wr.left); - height = static_cast(wr.bottom - wr.top); - // 获取屏幕分辨率 - int screenWidth = ::GetSystemMetrics(SM_CXSCREEN); - int screenHeight = ::GetSystemMetrics(SM_CYSCREEN); - // 当输入的窗口大小比分辨率大时,给出警告 - WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!"); - // 取最小值 - width = std::min(width, screenWidth); - height = std::min(height, screenHeight); - // 修改窗口大小,并设置窗口在屏幕居中 - ::MoveWindow(_hWnd, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, TRUE); + Rect wRect = __adjustWindow(width, height); + ::MoveWindow( + _hWnd, + int(wRect.origin.x), + int(wRect.origin.y), + int(wRect.size.width), + int(wRect.size.height), + TRUE + ); } } void e2d::Window::setTitle(const String& title) { - this->_title = title; + _title = title; if (_hWnd) { ::SetWindowText(_hWnd, (LPCWSTR)title); diff --git a/core/Common/Duration.cpp b/core/Common/Duration.cpp index 0e672f65..94a27ac5 100644 --- a/core/Common/Duration.cpp +++ b/core/Common/Duration.cpp @@ -7,13 +7,8 @@ e2d::Duration::Duration() { } -e2d::Duration::Duration(int ms) - : _ms(ms) -{ -} - -e2d::Duration::Duration(const std::chrono::milliseconds& ms) - : _ms(ms) +e2d::Duration::Duration(float seconds) + : _ms(static_cast(seconds * 1000.f)) { } @@ -59,12 +54,16 @@ bool e2d::Duration::operator<=(const Duration & other) const e2d::Duration e2d::Duration::operator+(Duration const & other) const { - return std::move(Duration(_ms + other._ms)); + Duration d; + d._ms = _ms + other._ms; + return std::move(d); } e2d::Duration e2d::Duration::operator-(Duration const & other) const { - return std::move(Duration(_ms - other._ms)); + Duration d; + d._ms = _ms - other._ms; + return std::move(d); } e2d::Duration & e2d::Duration::operator+=(Duration const &other) diff --git a/core/Common/Time.cpp b/core/Common/Time.cpp index 6a2bfc4d..a709e5ad 100644 --- a/core/Common/Time.cpp +++ b/core/Common/Time.cpp @@ -7,11 +7,6 @@ e2d::Time::Time() { } -e2d::Time::Time(const steady_clock::time_point& time) - : _timePoint(time) -{ -} - time_t e2d::Time::getTimeStamp() const { auto& duration = time_point_cast(_timePoint).time_since_epoch(); @@ -25,7 +20,16 @@ bool e2d::Time::isZero() const e2d::Time e2d::Time::operator+(Duration const & other) const { - return std::move(Time(_timePoint + milliseconds(other.milliseconds()))); + Time t; + t._timePoint = _timePoint + milliseconds(other.milliseconds()); + return std::move(t); +} + +e2d::Time e2d::Time::operator-(Duration const & other) const +{ + Time t; + t._timePoint = _timePoint - milliseconds(other.milliseconds()); + return std::move(t); } e2d::Time & e2d::Time::operator+=(Duration const & other) @@ -34,11 +38,6 @@ e2d::Time & e2d::Time::operator+=(Duration const & other) return (*this); } -e2d::Time e2d::Time::operator-(Duration const & other) const -{ - return std::move(Time(_timePoint - milliseconds(other.milliseconds()))); -} - e2d::Time & e2d::Time::operator-=(Duration const &other) { _timePoint -= milliseconds(other.milliseconds()); @@ -47,11 +46,13 @@ e2d::Time & e2d::Time::operator-=(Duration const &other) e2d::Duration e2d::Time::operator-(Time const & other) const { - auto& ms = duration_cast(_timePoint - other._timePoint); - return std::move(Duration(ms)); + auto ms = duration_cast(_timePoint - other._timePoint).count(); + return std::move(Duration(static_cast(ms) / 1000.f)); } e2d::Time e2d::Time::now() { - return std::move(Time(steady_clock::now())); + Time t; + t._timePoint = steady_clock::now(); + return std::move(t); } diff --git a/core/Manager/SceneManager.cpp b/core/Manager/SceneManager.cpp index 7363e499..d4a5f005 100644 --- a/core/Manager/SceneManager.cpp +++ b/core/Manager/SceneManager.cpp @@ -22,8 +22,7 @@ void e2d::SceneManager::destroyInstance() } e2d::SceneManager::SceneManager() - : _saveCurrScene(true) - , _currScene(nullptr) + : _currScene(nullptr) , _nextScene(nullptr) , _transition(nullptr) , _scenes() @@ -34,7 +33,7 @@ e2d::SceneManager::~SceneManager() { } -void e2d::SceneManager::push(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */) +void e2d::SceneManager::push(Scene * scene, bool saveCurrentScene) { if (!scene) return; @@ -44,58 +43,59 @@ void e2d::SceneManager::push(Scene * scene, Transition * transition /* = nullptr _nextScene = scene; _nextScene->retain(); - // 设置切换场景动作 - if (transition) + // 初始化场景切换动画 + if (_transition && !_transition->init(_currScene, _nextScene)) { - if (_transition) - { - _transition->_stop(); - _transition->release(); - } - _transition = transition; - transition->retain(); - transition->_init(_currScene, _nextScene); - transition->_update(); + WARN("Transition initialize failed!"); + _transition->release(); + _transition = nullptr; } - if (_currScene) + if (saveCurrentScene && _currScene) { - _saveCurrScene = saveCurrentScene; + _scenes.push(_currScene); } } -void e2d::SceneManager::pop(Transition * transition /* = nullptr */) +e2d::Scene* e2d::SceneManager::pop() { // 栈为空时,调用返回场景函数失败 if (_scenes.size() == 0) { WARN("Scene stack is empty!"); - return; + return nullptr; } - // 从栈顶取出场景指针,作为下一场景 _nextScene = _scenes.top(); _scenes.pop(); - // 返回上一场景时,不保存当前场景 - if (_currScene) + // 初始化场景切换动画 + if (_transition && !_transition->init(_currScene, _nextScene)) { - _saveCurrScene = false; + WARN("Transition initialize failed!"); + _transition->release(); + _transition = nullptr; } - // 设置切换场景动作 + return _nextScene; +} + +void e2d::SceneManager::setTransition(Transition * transition) +{ if (transition) { - transition->retain(); - transition->_init(_currScene, _nextScene); - transition->_update(); + if (_transition) + { + _transition->stop(); + _transition->release(); + } _transition = transition; + _transition->retain(); } } void e2d::SceneManager::clear() { - // 清空场景栈 while (!_scenes.empty()) { _scenes.top()->release(); @@ -108,7 +108,7 @@ e2d::Scene * e2d::SceneManager::getCurrentScene() return _currScene; } -std::stack e2d::SceneManager::getSceneStack() +const std::stack& e2d::SceneManager::getSceneStack() { return _scenes; } @@ -120,19 +120,13 @@ bool e2d::SceneManager::isTransitioning() void e2d::SceneManager::update() { - if (_transition == nullptr) - { - // 更新场景内容 - if (_currScene) - { - _currScene->update(); - } - } - else - { - // 更新场景动作 - _transition->_update(); + if (_currScene) _currScene->update(); + if (_nextScene) _nextScene->update(); + if (_transition) + { + _transition->update(); + if (_transition->isDone()) { _transition->release(); @@ -144,26 +138,17 @@ void e2d::SceneManager::update() } } - // 下一场景指针不为空时,切换场景 if (_nextScene) { if (_currScene) { - // 执行当前场景的 onExit 函数 _currScene->onExit(); - - // 若要保存当前场景,把它放入栈中 - if (_saveCurrScene) - { - _scenes.push(_currScene); - } - else + if (_scenes.empty() || _scenes.top() != _currScene) { _currScene->release(); } } - // 执行下一场景的 onEnter 函数 _nextScene->onEnter(); _currScene = _nextScene; @@ -175,15 +160,11 @@ void e2d::SceneManager::render() { if (_transition) { - _transition->_render(); + _transition->render(); } - else + else if (_currScene) { - // 绘制当前场景 - if (_currScene) - { - _currScene->render(); - } + _currScene->render(); } } diff --git a/core/Tool/Task.cpp b/core/Tool/Task.cpp index 206bf5f5..1d1984e4 100644 --- a/core/Tool/Task.cpp +++ b/core/Tool/Task.cpp @@ -6,8 +6,7 @@ e2d::Task::Task(const Function & func, const String & name) , _stopped(false) , _runTimes(0) , _totalTimes(-1) - , _delay(0.f) - , _lastTime(0.f) + , _delay() , _callback(func) , _name(name) { @@ -17,9 +16,8 @@ e2d::Task::Task(const Function & func, float delay, int times, const String & na : _running(true) , _stopped(false) , _runTimes(0) - , _totalTimes(times) , _delay(std::max(delay, 0.f)) - , _lastTime(0.f) + , _totalTimes(times) , _callback(func) , _name(name) { @@ -38,17 +36,24 @@ void e2d::Task::resume() void e2d::Task::update() { - if (_callback) + if (_totalTimes == 0) { - _callback(); + _stopped = true; + return; } ++_runTimes; _lastTime += _delay; + if (_callback) + { + _callback(); + } + if (_runTimes == _totalTimes) { _stopped = true; + return; } } @@ -56,11 +61,11 @@ bool e2d::Task::isReady() const { if (_running) { - if (_delay == 0) + if (_delay.milliseconds() == 0) { return true; } - if ((Game::getInstance()->getTotalDuration().seconds() - _lastTime) >= _delay) + if (Time::now() - _lastTime >= _delay) { return true; } @@ -80,5 +85,5 @@ e2d::String e2d::Task::getName() const void e2d::Task::updateTime() { - _lastTime = Game::getInstance()->getTotalDuration().seconds(); -} \ No newline at end of file + _lastTime = Time::now(); +} diff --git a/core/Transition/BoxTransition.cpp b/core/Transition/BoxTransition.cpp index 885093e6..641e6a1d 100644 --- a/core/Transition/BoxTransition.cpp +++ b/core/Transition/BoxTransition.cpp @@ -6,14 +6,20 @@ e2d::BoxTransition::BoxTransition(float duration) { } -void e2d::BoxTransition::_init(Scene * prev, Scene * next) +bool e2d::BoxTransition::init(Scene * prev, Scene * next) { - Transition::_init(prev, next); - _inLayerParam.opacity = 0; + if (Transition::init(prev, next)) + { + _inLayerParam.opacity = 0; + return true; + } + return false; } -void e2d::BoxTransition::_updateCustom() +void e2d::BoxTransition::update() { + Transition::update(); + if (_delta <= 0.5) { _outLayerParam.contentBounds = D2D1::RectF( @@ -35,11 +41,11 @@ void e2d::BoxTransition::_updateCustom() ); if (_delta >= 1) { - this->_stop(); + this->stop(); } } } -void e2d::BoxTransition::_reset() +void e2d::BoxTransition::reset() { } diff --git a/core/Transition/EmergeTransition.cpp b/core/Transition/EmergeTransition.cpp index 6bd7c819..c79d8f5a 100644 --- a/core/Transition/EmergeTransition.cpp +++ b/core/Transition/EmergeTransition.cpp @@ -6,24 +6,30 @@ e2d::EmergeTransition::EmergeTransition(float duration) { } -void e2d::EmergeTransition::_init(Scene * prev, Scene * next) +bool e2d::EmergeTransition::init(Scene * prev, Scene * next) { - Transition::_init(prev, next); - _outLayerParam.opacity = 1; - _inLayerParam.opacity = 0; + if (Transition::init(prev, next)) + { + _outLayerParam.opacity = 1; + _inLayerParam.opacity = 0; + return true; + } + return false; } -void e2d::EmergeTransition::_updateCustom() +void e2d::EmergeTransition::update() { + Transition::update(); + _outLayerParam.opacity = 1 - _delta; _inLayerParam.opacity = _delta; if (_delta >= 1) { - this->_stop(); + this->stop(); } } -void e2d::EmergeTransition::_reset() +void e2d::EmergeTransition::reset() { } diff --git a/core/Transition/FadeTransition.cpp b/core/Transition/FadeTransition.cpp index 4a49ed2f..459e0b9f 100644 --- a/core/Transition/FadeTransition.cpp +++ b/core/Transition/FadeTransition.cpp @@ -6,15 +6,21 @@ e2d::FadeTransition::FadeTransition(float duration) { } -void e2d::FadeTransition::_init(Scene * prev, Scene * next) +bool e2d::FadeTransition::init(Scene * prev, Scene * next) { - Transition::_init(prev, next); - _outLayerParam.opacity = 1; - _inLayerParam.opacity = 0; + if (Transition::init(prev, next)) + { + _outLayerParam.opacity = 1; + _inLayerParam.opacity = 0; + return true; + } + return false; } -void e2d::FadeTransition::_updateCustom() +void e2d::FadeTransition::update() { + Transition::update(); + if (_delta < 0.5) { _outLayerParam.opacity = 1 - _delta * 2; @@ -26,11 +32,11 @@ void e2d::FadeTransition::_updateCustom() _inLayerParam.opacity = (_delta - 0.5f) * 2; if (_delta >= 1) { - this->_stop(); + this->stop(); } } } -void e2d::FadeTransition::_reset() +void e2d::FadeTransition::reset() { } diff --git a/core/Transition/MoveTransition.cpp b/core/Transition/MoveTransition.cpp index 168b6356..76e07495 100644 --- a/core/Transition/MoveTransition.cpp +++ b/core/Transition/MoveTransition.cpp @@ -7,39 +7,44 @@ e2d::MoveTransition::MoveTransition(float duration, Direction direction) { } -void e2d::MoveTransition::_init(Scene * prev, Scene * next) +bool e2d::MoveTransition::init(Scene * prev, Scene * next) { - Transition::_init(prev, next); + if (Transition::init(prev, next)) + { + float width = _windowSize.width; + float height = _windowSize.height; + if (_direction == Direction::Up) + { + _posDelta = Vector2(0, -height); + _startPos = Point(0, height); + } + else if (_direction == Direction::Down) + { + _posDelta = Vector2(0, height); + _startPos = Point(0, -height); + } + else if (_direction == Direction::Left) + { + _posDelta = Vector2(-width, 0); + _startPos = Point(width, 0); + } + else if (_direction == Direction::Right) + { + _posDelta = Vector2(width, 0); + _startPos = Point(-width, 0); + } - float width = _windowSize.width; - float height = _windowSize.height; - if (_direction == Direction::Up) - { - _posDelta = Vector2(0, -height); - _startPos = Point(0, height); + if (_outScene) _outScene->getRoot()->setPos(0, 0); + _inScene->getRoot()->setPos(_startPos); + return true; } - else if (_direction == Direction::Down) - { - _posDelta = Vector2(0, height); - _startPos = Point(0, -height); - } - else if (_direction == Direction::Left) - { - _posDelta = Vector2(-width, 0); - _startPos = Point(width, 0); - } - else if (_direction == Direction::Right) - { - _posDelta = Vector2(width, 0); - _startPos = Point(-width, 0); - } - - if (_outScene) _outScene->getRoot()->setPos(0, 0); - _inScene->getRoot()->setPos(_startPos); + return false; } -void e2d::MoveTransition::_updateCustom() +void e2d::MoveTransition::update() { + Transition::update(); + if (_outScene) { _outScene->getRoot()->setPos(_posDelta * _delta); @@ -51,11 +56,11 @@ void e2d::MoveTransition::_updateCustom() if (_delta >= 1) { - this->_stop(); + this->stop(); } } -void e2d::MoveTransition::_reset() +void e2d::MoveTransition::reset() { if (_outScene) _outScene->getRoot()->setPos(0, 0); _inScene->getRoot()->setPos(0, 0); diff --git a/core/Transition/Transition.cpp b/core/Transition/Transition.cpp index 04e0c810..b487f316 100644 --- a/core/Transition/Transition.cpp +++ b/core/Transition/Transition.cpp @@ -4,7 +4,7 @@ e2d::Transition::Transition(float duration) : _end(false) - , _last() + , _started() , _delta(0) , _outScene(nullptr) , _inScene(nullptr) @@ -29,7 +29,7 @@ bool e2d::Transition::isDone() return _end; } -void e2d::Transition::_init(Scene * prev, Scene * next) +bool e2d::Transition::init(Scene * prev, Scene * next) { auto renderer = Renderer::getInstance(); // 创建图层 @@ -42,10 +42,10 @@ void e2d::Transition::_init(Scene * prev, Scene * next) if (FAILED(hr)) { - throw SystemException(L"场景过渡动画图层创建失败"); + return false; } - _last = Game::getInstance()->getTotalDuration(); + _started = Time::now(); _outScene = prev; _inScene = next; if (_outScene) _outScene->retain(); @@ -61,35 +61,24 @@ void e2d::Transition::_init(Scene * prev, Scene * next) renderer->getSolidColorBrush(), D2D1_LAYER_OPTIONS_NONE ); + + return true; } -void e2d::Transition::_update() +void e2d::Transition::update() { - // 计算动作进度 if (_duration == 0) { _delta = 1; } else { - _delta = (Game::getInstance()->getTotalDuration() - _last).seconds() / _duration; + _delta = (Time::now() - _started).seconds() / _duration; _delta = std::min(_delta, 1.f); } - - this->_updateCustom(); - - // 更新场景内容 - if (_outScene) - { - _outScene->update(); - } - if (_inScene) - { - _inScene->update(); - } } -void e2d::Transition::_render() +void e2d::Transition::render() { auto pRT = Renderer::getInstance()->getRenderTarget(); @@ -132,8 +121,8 @@ void e2d::Transition::_render() } } -void e2d::Transition::_stop() +void e2d::Transition::stop() { _end = true; - _reset(); + reset(); } diff --git a/core/e2daction.h b/core/e2daction.h index fbc99898..fa6352db 100644 --- a/core/e2daction.h +++ b/core/e2daction.h @@ -85,7 +85,7 @@ protected: bool _done; bool _initialized; Node * _target; - float _last; + Time _started; }; diff --git a/core/e2dbase.h b/core/e2dbase.h index eae663a2..2764b0b6 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -118,9 +118,6 @@ public: // 获取游戏配置 const Config& getConfig(); - // 获取游戏总时长 - Duration getTotalDuration() const; - private: Game(); @@ -132,9 +129,6 @@ private: bool _quit; bool _paused; Config _config; - Time _start; - Time _now; - Time _last; static Game * _instance; }; @@ -243,7 +237,13 @@ private: E2D_DISABLE_COPY(Window); // 注册窗口 - HWND __create(); + HWND __registerWindow(); + + // 根据客户区大小计算合适的窗口区域 + Rect __adjustWindow( + int width, + int height + ); // Win32 窗口消息回调程序 static LRESULT CALLBACK WndProc( @@ -342,12 +342,6 @@ public: Color color ); - // 渲染游戏画面 - void render(); - - // 删除设备相关资源 - void discardDeviceResources(); - // 获取文字渲染器 TextRenderer * getTextRenderer(); @@ -357,6 +351,12 @@ public: // 获取 ID2D1SolidColorBrush 对象 ID2D1SolidColorBrush * getSolidColorBrush(); + // 渲染游戏画面 + void render(); + + // 删除设备相关资源 + void discardDeviceResources(); + // 获取 ID2D1Factory 对象 static ID2D1Factory * getFactory(); diff --git a/core/e2dcommon.h b/core/e2dcommon.h index 7aeda3bd..9ebe3c44 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -414,11 +414,7 @@ public: Duration(); explicit Duration( - int ms - ); - - explicit Duration( - const std::chrono::milliseconds& ms + float seconds ); // 获取毫秒数 @@ -451,10 +447,6 @@ class Time public: Time(); - explicit Time( - const std::chrono::steady_clock::time_point& time - ); - // 获取时间戳 time_t getTimeStamp() const; diff --git a/core/e2dmanager.h b/core/e2dmanager.h index 0ca20a4b..1fe957ee 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -25,13 +25,15 @@ public: // 场景入栈 void push( Scene * scene, /* 下一个场景的指针 */ - Transition * transition = nullptr, /* 场景切换动作 */ bool saveCurrentScene = true /* 是否保存当前场景 */ ); // 场景出栈 - void pop( - Transition * transition = nullptr /* 场景切换动作 */ + Scene* pop(); + + // 设置场景切换动作 + void setTransition( + Transition * transition /* 场景切换动作 */ ); // 清空保存的所有场景 @@ -41,7 +43,7 @@ public: Scene * getCurrentScene(); // 获取场景栈 - std::stack getSceneStack(); + const std::stack& getSceneStack(); // 是否正在进行转场动作 bool isTransitioning(); @@ -70,7 +72,6 @@ private: E2D_DISABLE_COPY(SceneManager); private: - bool _saveCurrScene; Scene * _currScene; Scene * _nextScene; Transition * _transition; diff --git a/core/e2dtool.h b/core/e2dtool.h index 1b3f3ad8..9c8b52be 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -308,8 +308,8 @@ private: bool _stopped; int _runTimes; int _totalTimes; - float _delay; - float _lastTime; + Duration _delay; + Time _lastTime; String _name; Function _callback; }; diff --git a/core/e2dtransition.h b/core/e2dtransition.h index bbf8fb88..0d94a451 100644 --- a/core/e2dtransition.h +++ b/core/e2dtransition.h @@ -5,15 +5,10 @@ namespace e2d { -class SceneManager; - - // 场景过渡 class Transition : public Ref { - friend class SceneManager; - public: explicit Transition(float duration); @@ -22,36 +17,32 @@ public: // 场景过渡动画是否结束 bool isDone(); -protected: // 初始化场景过渡动画 - virtual void _init( + virtual bool init( Scene * prev, Scene * next ); // 更新场景过渡动画 - virtual void _update(); - - // 更新场景过渡动画 - virtual void _updateCustom() = 0; + virtual void update(); // 渲染场景过渡动画 - virtual void _render(); - - // 重置场景过渡动画 - virtual void _reset() = 0; + virtual void render(); // 停止场景过渡动画 - virtual void _stop(); + virtual void stop(); + + // 重置场景过渡动画 + virtual void reset() = 0; protected: - bool _end; - float _duration; - float _delta; - Duration _last; - Size _windowSize; - Scene * _outScene; - Scene * _inScene; + bool _end; + float _duration; + float _delta; + Time _started; + Size _windowSize; + Scene* _outScene; + Scene* _inScene; ID2D1Layer * _outLayer; ID2D1Layer * _inLayer; D2D1_LAYER_PARAMETERS _outLayerParam; @@ -68,16 +59,15 @@ public: float duration /* 动画持续时长 */ ); -protected: // 更新动画 - virtual void _updateCustom() override; + virtual void update() override; - virtual void _init( + virtual bool init( Scene * prev, Scene * next ) override; - virtual void _reset() override; + virtual void reset() override; }; @@ -90,16 +80,15 @@ public: float duration /* 浮现动画持续时长 */ ); -protected: // 更新动画 - virtual void _updateCustom() override; + virtual void update() override; - virtual void _init( + virtual bool init( Scene * prev, Scene * next ) override; - virtual void _reset() override; + virtual void reset() override; }; @@ -112,16 +101,15 @@ public: float duration /* 动画持续时长 */ ); -protected: // 更新动画 - virtual void _updateCustom() override; + virtual void update() override; - virtual void _init( + virtual bool init( Scene * prev, Scene * next ) override; - virtual void _reset() override; + virtual void reset() override; }; @@ -135,16 +123,15 @@ public: Direction direction = Direction::Left /* 场景移动方向 */ ); -protected: // 更新动画 - virtual void _updateCustom() override; + virtual void update() override; - virtual void _init( + virtual bool init( Scene * prev, Scene * next ) override; - virtual void _reset() override; + virtual void reset() override; protected: Direction _direction;