From 3a8428d54eb14245b82b67fc1062fc724df24840 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Tue, 28 Aug 2018 00:06:10 +0800 Subject: [PATCH] Refactoring... --- core/Base/GC.cpp | 9 ++ core/Base/Game.cpp | 49 ++++----- core/Base/Input.cpp | 70 +++++++----- core/Base/Renderer.cpp | 158 +++++++++++++++++---------- core/Base/Window.cpp | 169 ++++++++++++++++------------- core/Common/Collider.cpp | 4 +- core/Common/Image.cpp | 10 +- core/Common/String.cpp | 22 ++-- core/Custom/TextRenderer.cpp | 8 +- core/Manager/CollisionManager.cpp | 24 ++-- core/Node/Button.cpp | 10 +- core/Node/Canvas.cpp | 12 +- core/Node/Node.cpp | 23 ++-- core/Node/Scene.cpp | 12 +- core/Node/Sprite.cpp | 4 +- core/Node/Text.cpp | 158 ++++++++++++++------------- core/Tool/File.cpp | 7 +- core/Tool/Path.cpp | 4 +- core/Transition/BoxTransition.cpp | 17 +-- core/Transition/MoveTransition.cpp | 19 ++-- core/Transition/Transition.cpp | 22 ++-- core/e2dbase.h | 122 +++++++++++---------- core/e2dcommon.h | 8 +- core/e2dnode.h | 27 ++--- core/e2dtransition.h | 5 +- 25 files changed, 520 insertions(+), 453 deletions(-) diff --git a/core/Base/GC.cpp b/core/Base/GC.cpp index e3721700..0d47648c 100644 --- a/core/Base/GC.cpp +++ b/core/Base/GC.cpp @@ -73,6 +73,15 @@ void e2d::GC::clear() } _pool.clear(); _cleanup = false; + + // 清除缓存 + Image::clearCache(); + + // 清除单例 + Game::destroyInstance(); + Renderer::destroyInstance(); + Input::destroyInstance(); + Window::destroyInstance(); } e2d::GC * e2d::GC::getInstance() diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index b26df78e..79d26431 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -6,12 +6,27 @@ #include +e2d::Game * e2d::Game::_instance = nullptr; + +e2d::Game * e2d::Game::getInstance() +{ + if (!_instance) + _instance = new (std::nothrow) Game; + return _instance; +} + +void e2d::Game::destroyInstance() +{ + if (_instance) + { + delete _instance; + _instance = nullptr; + } +} + e2d::Game::Game() : _quit(true) , _paused(false) - , _window(nullptr) - , _input(nullptr) - , _renderer(nullptr) , _currScene(nullptr) , _nextScene(nullptr) , _transition(nullptr) @@ -19,36 +34,18 @@ e2d::Game::Game() { CoInitialize(nullptr); - _input = new (std::nothrow) Input; - _renderer = new (std::nothrow) Renderer; + _window = Window::getInstance(); + _input = Input::getInstance(); + _renderer = Renderer::getInstance(); _timer = Timer::getInstance(); _actionManager = ActionManager::getInstance(); } e2d::Game::~Game() { - if (_renderer) - delete _renderer; - - if (_input) - delete _input; - CoUninitialize(); } -e2d::Game * e2d::Game::getInstance() -{ - static Game instance; - return &instance; -} - -void e2d::Game::initWithWindow(Window * window) -{ - _window = window; - _renderer->initWithWindow(_window); - _input->initWithWindow(_window); -} - void e2d::Game::start() { _quit = false; @@ -274,11 +271,11 @@ void e2d::Game::drawScene() { if (_transition) { - _transition->_render(this); + _transition->_render(); } else if (_currScene) { - _currScene->visit(this); + _currScene->visit(); } } _renderer->endDraw(); diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index f02ab4b0..4e544935 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -4,6 +4,24 @@ #pragma comment(lib, "dinput8.lib") +e2d::Input * e2d::Input::_instance = nullptr; + +e2d::Input * e2d::Input::getInstance() +{ + if (!_instance) + _instance = new (std::nothrow) Input; + return _instance; +} + +void e2d::Input::destroyInstance() +{ + if (_instance) + { + delete _instance; + _instance = nullptr; + } +} + e2d::Input::Input() : _directInput(false) , _keyboardDevice(false) @@ -15,32 +33,17 @@ e2d::Input::Input() ZeroMemory(&_mouseState, sizeof(_mouseState)); // 初始化接口对象 - HRESULT hr = DirectInput8Create( - HINST_THISCOMPONENT, - DIRECTINPUT_VERSION, - IID_IDirectInput8, - (void**)&_directInput, - nullptr + ThrowIfFailed( + DirectInput8Create( + HINST_THISCOMPONENT, + DIRECTINPUT_VERSION, + IID_IDirectInput8, + (void**)&_directInput, + nullptr + ) ); -} -e2d::Input::~Input() -{ - if (_keyboardDevice) - _keyboardDevice->Unacquire(); - if (_mouseDevice) - _mouseDevice->Unacquire(); - - SafeRelease(_mouseDevice); - SafeRelease(_keyboardDevice); - SafeRelease(_directInput); - - CoUninitialize(); -} - -void e2d::Input::initWithWindow(Window * window) -{ - HWND hwnd = window->getHWnd(); + HWND hwnd = Window::getInstance()->getHWnd(); // 初始化键盘设备 ThrowIfFailed( @@ -71,6 +74,20 @@ void e2d::Input::initWithWindow(Window * window) _mouseDevice->Poll(); } +e2d::Input::~Input() +{ + if (_keyboardDevice) + _keyboardDevice->Unacquire(); + if (_mouseDevice) + _mouseDevice->Unacquire(); + + SafeRelease(_mouseDevice); + SafeRelease(_keyboardDevice); + SafeRelease(_directInput); + + CoUninitialize(); +} + void e2d::Input::update() { if (_keyboardDevice) @@ -130,13 +147,12 @@ float e2d::Input::getMouseY() e2d::Point e2d::Input::getMousePos() { - auto window = Game::getInstance()->getWindow(); + auto window = Window::getInstance(); + float dpi = window->getDpi(); POINT mousePos; ::GetCursorPos(&mousePos); ::ScreenToClient(window->getHWnd(), &mousePos); - - float dpi = window->getDpi(); return Point(mousePos.x * 96.f / dpi, mousePos.y * 96.f / dpi); } diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index 0d8f2463..cd0c2559 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -3,6 +3,39 @@ #include "..\e2dnode.h" +e2d::Renderer* e2d::Renderer::_instance = nullptr; +ID2D1Factory* e2d::Renderer::_factory = nullptr; +IWICImagingFactory* e2d::Renderer::_imagingFactory = nullptr; +IDWriteFactory* e2d::Renderer::_writeFactory = nullptr; +ID2D1StrokeStyle* e2d::Renderer::_miterStrokeStyle = nullptr; +ID2D1StrokeStyle* e2d::Renderer::_bevelStrokeStyle = nullptr; +ID2D1StrokeStyle* e2d::Renderer::_roundStrokeStyle = nullptr; + +e2d::Renderer * e2d::Renderer::getInstance() +{ + if (!_instance) + { + _instance = new (std::nothrow) Renderer; + } + return _instance; +} + +void e2d::Renderer::destroyInstance() +{ + if (_instance) + { + delete _instance; + _instance = nullptr; + + SafeRelease(_miterStrokeStyle); + SafeRelease(_bevelStrokeStyle); + SafeRelease(_roundStrokeStyle); + SafeRelease(_factory); + SafeRelease(_imagingFactory); + SafeRelease(_writeFactory); + } +} + e2d::Renderer::Renderer() : _showFps(false) , _lastRenderTime(Time::now()) @@ -12,63 +45,11 @@ e2d::Renderer::Renderer() , _renderTarget(nullptr) , _solidBrush(nullptr) , _textRenderer(nullptr) - , _factory(nullptr) - , _imagingFactory(nullptr) - , _writeFactory(nullptr) - , _miterStrokeStyle(nullptr) - , _bevelStrokeStyle(nullptr) - , _roundStrokeStyle(nullptr) , _clearColor(D2D1::ColorF(D2D1::ColorF::Black)) { CoInitialize(nullptr); - ThrowIfFailed( - D2D1CreateFactory( - D2D1_FACTORY_TYPE_SINGLE_THREADED, - &_factory - ) - ); - - ThrowIfFailed( - CoCreateInstance( - CLSID_WICImagingFactory, - nullptr, - CLSCTX_INPROC_SERVER, - IID_IWICImagingFactory, - reinterpret_cast(&_imagingFactory) - ) - ); - - ThrowIfFailed( - DWriteCreateFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast(&_writeFactory) - ) - ); -} - -e2d::Renderer::~Renderer() -{ - SafeRelease(_fpsFormat); - SafeRelease(_fpsLayout); - SafeRelease(_textRenderer); - SafeRelease(_solidBrush); - SafeRelease(_renderTarget); - - SafeRelease(_miterStrokeStyle); - SafeRelease(_bevelStrokeStyle); - SafeRelease(_roundStrokeStyle); - SafeRelease(_factory); - SafeRelease(_imagingFactory); - SafeRelease(_writeFactory); - - CoUninitialize(); -} - -void e2d::Renderer::initWithWindow(Window * window) -{ - HWND hWnd = window->getHWnd(); + HWND hWnd = Window::getInstance()->getHWnd(); RECT rc; GetClientRect(hWnd, &rc); @@ -81,7 +62,7 @@ void e2d::Renderer::initWithWindow(Window * window) // 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建 // 创建一个 Direct2D 渲染目标 ThrowIfFailed( - _factory->CreateHwndRenderTarget( + getFactory()->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hWnd, @@ -103,13 +84,24 @@ void e2d::Renderer::initWithWindow(Window * window) ThrowIfFailed( TextRenderer::Create( &_textRenderer, - _factory, + getFactory(), _renderTarget, _solidBrush ) ); } +e2d::Renderer::~Renderer() +{ + SafeRelease(_fpsFormat); + SafeRelease(_fpsLayout); + SafeRelease(_textRenderer); + SafeRelease(_solidBrush); + SafeRelease(_renderTarget); + + CoUninitialize(); +} + void e2d::Renderer::beginDraw() { // 开始渲染 @@ -134,7 +126,7 @@ void e2d::Renderer::endDraw() if (!_fpsFormat) { ThrowIfFailed( - _writeFactory->CreateTextFormat( + getWriteFactory()->CreateTextFormat( L"", nullptr, DWRITE_FONT_WEIGHT_NORMAL, @@ -154,7 +146,7 @@ void e2d::Renderer::endDraw() SafeRelease(_fpsLayout); ThrowIfFailed( - _writeFactory->CreateTextLayout( + getWriteFactory()->CreateTextLayout( (const WCHAR *)fpsText, (UINT32)fpsText.length(), _fpsFormat, @@ -220,12 +212,58 @@ void e2d::Renderer::showFps(bool show) _showFps = show; } +ID2D1Factory * e2d::Renderer::getFactory() +{ + if (!_factory) + { + ThrowIfFailed( + D2D1CreateFactory( + D2D1_FACTORY_TYPE_SINGLE_THREADED, + &_factory + ) + ); + } + return _factory; +} + +IWICImagingFactory * e2d::Renderer::getImagingFactory() +{ + if (!_imagingFactory) + { + ThrowIfFailed( + CoCreateInstance( + CLSID_WICImagingFactory, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IWICImagingFactory, + reinterpret_cast(&_imagingFactory) + ) + ); + } + return _imagingFactory; +} + +IDWriteFactory * e2d::Renderer::getWriteFactory() +{ + if (!_writeFactory) + { + ThrowIfFailed( + DWriteCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&_writeFactory) + ) + ); + } + return _writeFactory; +} + ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle() { if (!_miterStrokeStyle) { ThrowIfFailed( - _factory->CreateStrokeStyle( + getFactory()->CreateStrokeStyle( D2D1::StrokeStyleProperties( D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_FLAT, @@ -248,7 +286,7 @@ ID2D1StrokeStyle * e2d::Renderer::getBevelStrokeStyle() if (!_bevelStrokeStyle) { ThrowIfFailed( - _factory->CreateStrokeStyle( + getFactory()->CreateStrokeStyle( D2D1::StrokeStyleProperties( D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_FLAT, @@ -271,7 +309,7 @@ ID2D1StrokeStyle * e2d::Renderer::getRoundStrokeStyle() if (!_roundStrokeStyle) { ThrowIfFailed( - _factory->CreateStrokeStyle( + getFactory()->CreateStrokeStyle( D2D1::StrokeStyleProperties( D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_FLAT, diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index 25a37e87..6e9c74f3 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -8,83 +8,36 @@ #define REGISTER_CLASS L"Easy2DApp" -e2d::Window::Window(const String & title, int width, int height, int iconID) +e2d::Window * e2d::Window::_instance = nullptr; + +e2d::Window * e2d::Window::getInstance() +{ + if (!_instance) + _instance = new (std::nothrow) Window; + return _instance; +} + +void e2d::Window::destroyInstance() +{ + if (_instance) + { + delete _instance; + _instance = nullptr; + } +} + +e2d::Window::Window() : _hWnd(nullptr) - , _width(width) - , _height(height) - , _title(title) - , _iconID(iconID) + , _width(640) + , _height(480) + , _title(L"Easy2D Game") + , _iconID(0) , _dpi(0.f) { CoInitialize(nullptr); // 获取系统 DPI _dpi = static_cast(::GetDpiForSystem()); - - WNDCLASSEX wcex = { 0 }; - 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 (_iconID != 0) - { - wcex.hIcon = (HICON)::LoadImage( - HINST_THISCOMPONENT, - MAKEINTRESOURCE(_iconID), - IMAGE_ICON, - 0, - 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE - ); - } - - // 注册窗口类 - RegisterClassEx(&wcex); - - // 计算窗口大小 - Rect clientRect = _locate(_width, _height); - - // 创建窗口 - _hWnd = ::CreateWindowEx( - NULL, - REGISTER_CLASS, - (LPCTSTR)_title, - WINDOW_STYLE, - int(clientRect.origin.x), - int(clientRect.origin.y), - int(clientRect.size.width), - int(clientRect.size.height), - nullptr, - nullptr, - HINST_THISCOMPONENT, - this - ); - - if (_hWnd) - { - // 禁用输入法 - setTypewritingEnabled(false); - // 禁用控制台关闭按钮 - HWND consoleHWnd = ::GetConsoleWindow(); - if (consoleHWnd) - { - HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE); - ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); - } - } - else - { - ::UnregisterClass(REGISTER_CLASS, HINST_THISCOMPONENT); - throw SystemException("Create window failed"); - } } e2d::Window::~Window() @@ -192,8 +145,75 @@ e2d::String e2d::Window::getTitle() const return _title; } -HWND e2d::Window::getHWnd() const +HWND e2d::Window::getHWnd() { + if (!_hWnd) + { + WNDCLASSEX wcex = { 0 }; + 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 (_iconID != 0) + { + wcex.hIcon = (HICON)::LoadImage( + HINST_THISCOMPONENT, + MAKEINTRESOURCE(_iconID), + IMAGE_ICON, + 0, + 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE + ); + } + + // 注册窗口类 + RegisterClassEx(&wcex); + + // 计算窗口大小 + Rect clientRect = _locate(_width, _height); + + // 创建窗口 + _hWnd = ::CreateWindowEx( + NULL, + REGISTER_CLASS, + (LPCTSTR)_title, + WINDOW_STYLE, + int(clientRect.origin.x), + int(clientRect.origin.y), + int(clientRect.size.width), + int(clientRect.size.height), + nullptr, + nullptr, + HINST_THISCOMPONENT, + this + ); + + if (_hWnd) + { + // 禁用输入法 + setTypewritingEnabled(false); + // 禁用控制台关闭按钮 + HWND consoleHWnd = ::GetConsoleWindow(); + if (consoleHWnd) + { + HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE); + ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); + } + } + else + { + ::UnregisterClass(REGISTER_CLASS, HINST_THISCOMPONENT); + throw SystemException("Create window failed"); + } + } return _hWnd; } @@ -318,7 +338,7 @@ void e2d::Window::setTypewritingEnabled(bool enabled) { if (hImc != nullptr) { - ::ImmAssociateContext(_hWnd, hImc); + ::ImmAssociateContext(getHWnd(), hImc); hImc = nullptr; } } @@ -326,7 +346,7 @@ void e2d::Window::setTypewritingEnabled(bool enabled) { if (hImc == nullptr) { - hImc = ::ImmAssociateContext(_hWnd, nullptr); + hImc = ::ImmAssociateContext(getHWnd(), nullptr); } } } @@ -448,8 +468,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染 // 目标适当。它可能会调用失败,但是这里可以忽略有可能的 // 错误,因为这个错误将在下一次调用 EndDraw 时产生 - auto renderer = Game::getInstance()->getRenderer(); - auto pRT = renderer->getRenderTarget(); + auto pRT = Renderer::getInstance()->getRenderTarget(); if (pRT) { pRT->Resize(D2D1::SizeU(width, height)); diff --git a/core/Common/Collider.cpp b/core/Common/Collider.cpp index f9253b52..e05b8e1d 100644 --- a/core/Common/Collider.cpp +++ b/core/Common/Collider.cpp @@ -80,7 +80,7 @@ void e2d::Collider::render() { if (_geometry && _enabled && _visible) { - auto renderer = Game::getInstance()->getRenderer(); + auto renderer = Renderer::getInstance(); // 获取纯色画刷 ID2D1SolidColorBrush * brush = renderer->getSolidColorBrush(); // 设置画刷颜色和透明度 @@ -131,7 +131,7 @@ void e2d::Collider::recreate() return; SafeRelease(_geometry); - auto factory = Game::getInstance()->getRenderer()->getFactory(); + auto factory = Renderer::getFactory(); switch (_shape) { diff --git a/core/Common/Image.cpp b/core/Common/Image.cpp index f954fbe3..e9efae81 100644 --- a/core/Common/Image.cpp +++ b/core/Common/Image.cpp @@ -157,9 +157,8 @@ bool e2d::Image::preload(const Resource& res) return true; } - Renderer* renderer = Game::getInstance()->getRenderer(); - ID2D1HwndRenderTarget* pRenderTarget = renderer->getRenderTarget(); - IWICImagingFactory *pImagingFactory = renderer->getImagingFactory(); + IWICImagingFactory *pImagingFactory = Renderer::getImagingFactory(); + ID2D1HwndRenderTarget* pRenderTarget = Renderer::getInstance()->getRenderTarget(); IWICBitmapDecoder *pDecoder = nullptr; IWICBitmapFrameDecode *pSource = nullptr; IWICStream *pStream = nullptr; @@ -287,9 +286,8 @@ bool e2d::Image::preload(const String & fileName) if (_bitmapCache.find(hash) != _bitmapCache.end()) return true; - Renderer* renderer = Game::getInstance()->getRenderer(); - ID2D1HwndRenderTarget* pRenderTarget = renderer->getRenderTarget(); - IWICImagingFactory *pImagingFactory = renderer->getImagingFactory(); + IWICImagingFactory *pImagingFactory = Renderer::getImagingFactory(); + ID2D1HwndRenderTarget* pRenderTarget = Renderer::getInstance()->getRenderTarget(); IWICBitmapDecoder *pDecoder = nullptr; IWICBitmapFrameDecode *pSource = nullptr; IWICStream *pStream = nullptr; diff --git a/core/Common/String.cpp b/core/Common/String.cpp index a85c0b58..2d04cea4 100644 --- a/core/Common/String.cpp +++ b/core/Common/String.cpp @@ -332,6 +332,17 @@ e2d::String::operator wchar_t*() const return const_cast(_str.c_str()); } +e2d::String::operator std::wstring() const +{ + return _str; +} + +e2d::String::operator std::string() const +{ + std::string str = static_cast(_bstr_t(_str.c_str())); + return std::move(str); +} + bool e2d::String::isEmpty() const { return _str.empty(); @@ -348,17 +359,6 @@ size_t e2d::String::hash() const return hash(_str); } -std::wstring e2d::String::getWString() const -{ - return _str; -} - -std::string e2d::String::getCString() const -{ - std::string str = static_cast(_bstr_t(_str.c_str())); - return std::move(str); -} - wchar_t e2d::String::at(int index) const { return _str[size_t(index)]; diff --git a/core/Custom/TextRenderer.cpp b/core/Custom/TextRenderer.cpp index 4a1c9ed0..73ca61ad 100644 --- a/core/Custom/TextRenderer.cpp +++ b/core/Custom/TextRenderer.cpp @@ -59,18 +59,16 @@ STDMETHODIMP_(void) TextRenderer::SetTextStyle( sOutlineColor_ = outlineColor; fOutlineWidth = 2 * outlineWidth; - auto pRenderer = Game::getInstance()->getRenderer(); - switch (outlineJoin) { case D2D1_LINE_JOIN_MITER: - pCurrStrokeStyle_ = pRenderer->getMiterStrokeStyle(); + pCurrStrokeStyle_ = Renderer::getMiterStrokeStyle(); break; case D2D1_LINE_JOIN_BEVEL: - pCurrStrokeStyle_ = pRenderer->getBevelStrokeStyle(); + pCurrStrokeStyle_ = Renderer::getBevelStrokeStyle(); break; case D2D1_LINE_JOIN_ROUND: - pCurrStrokeStyle_ = pRenderer->getRoundStrokeStyle(); + pCurrStrokeStyle_ = Renderer::getRoundStrokeStyle(); break; default: pCurrStrokeStyle_ = nullptr; diff --git a/core/Manager/CollisionManager.cpp b/core/Manager/CollisionManager.cpp index d1f56555..73a4c999 100644 --- a/core/Manager/CollisionManager.cpp +++ b/core/Manager/CollisionManager.cpp @@ -32,47 +32,47 @@ void e2d::CollisionManager::__removeCollider(Collider * collider) } } -void e2d::CollisionManager::__updateCollider(Collider* collider) +void e2d::CollisionManager::__updateCollider(Collider* active) { if (!_collisionEnabled || Game::getInstance()->isTransitioning()) return; + auto currScene = Game::getInstance()->getCurrentScene(); + if (active->getNode()->getParentScene() != currScene) + return; + std::vector currColliders; currColliders.reserve(_colliders.size()); std::copy_if( _colliders.begin(), _colliders.end(), std::back_inserter(currColliders), - [this, collider](Collider* passive) -> bool + [this, active, currScene](Collider* passive) -> bool { - return collider != passive && + return active != passive && passive->getNode()->isVisible() && - collider->getNode()->getParentScene() == passive->getNode()->getParentScene() && - this->isCollidable(collider->getNode(), passive->getNode()); + passive->getNode()->getParentScene() == currScene && + this->isCollidable(active->getNode(), passive->getNode()); } ); for (const auto& passive : currColliders) { // 判断两碰撞体交集情况 - Collider::Relation relation = collider->getRelationWith(passive); + Collider::Relation relation = active->getRelationWith(passive); // 忽略 UNKNOWN 和 DISJOIN 情况 if (relation != Collider::Relation::Unknown && relation != Collider::Relation::Disjoin) { - auto activeNode = collider->getNode(); + auto activeNode = active->getNode(); auto passiveNode = passive->getNode(); // 触发两次碰撞事件 Collision activeCollision(passiveNode, relation); - if (dynamic_cast(activeNode->getParentScene())) - dynamic_cast(activeNode->getParentScene())->handle(activeCollision); if (dynamic_cast(activeNode)) dynamic_cast(activeNode)->handle(activeCollision); - Collision passiveCollision(activeNode, passive->getRelationWith(collider)); - if (dynamic_cast(passiveNode->getParentScene())) - dynamic_cast(passiveNode->getParentScene())->handle(passiveCollision); + Collision passiveCollision(activeNode, passive->getRelationWith(active)); if (dynamic_cast(passiveNode)) dynamic_cast(passiveNode)->handle(passiveCollision); } diff --git a/core/Node/Button.cpp b/core/Node/Button.cpp index 30856906..1b086075 100644 --- a/core/Node/Button.cpp +++ b/core/Node/Button.cpp @@ -189,20 +189,20 @@ bool e2d::Button::dispatch(const MouseEvent & e, bool handled) return Node::dispatch(e, handled); } -void e2d::Button::visit(Game * game) +void e2d::Button::visit() { - Node::visit(game); + Node::visit(); if (_visible && !_enabled && _normal && - _normal->containsPoint(game->getInput()->getMousePos())) + _normal->containsPoint(Input::getInstance()->getMousePos())) { - game->getWindow()->setCursor(Window::Cursor::No); + Window::getInstance()->setCursor(Window::Cursor::No); } else if (_status == Status::Mouseover || _status == Status::Selected) { - game->getWindow()->setCursor(Window::Cursor::Hand); + Window::getInstance()->setCursor(Window::Cursor::Hand); } } diff --git a/core/Node/Canvas.cpp b/core/Node/Canvas.cpp index a60714df..3cb5a679 100644 --- a/core/Node/Canvas.cpp +++ b/core/Node/Canvas.cpp @@ -1,16 +1,14 @@ #include "..\e2dnode.h" e2d::Canvas::Canvas(float width, float height) - : _renderer(nullptr) - , _renderTarget(nullptr) + : _renderTarget(nullptr) , _fillBrush(nullptr) , _lineBrush(nullptr) , _strokeStyle(nullptr) , _strokeWidth(1.0f) , _stroke(Stroke::Miter) { - _renderer = Game::getInstance()->getRenderer(); - _renderTarget = _renderer->getRenderTarget(); + _renderTarget = Renderer::getInstance()->getRenderTarget(); _renderTarget->AddRef(); ThrowIfFailed( @@ -60,13 +58,13 @@ void e2d::Canvas::setStrokeStyle(Stroke strokeStyle) switch (strokeStyle) { case e2d::Stroke::Miter: - _strokeStyle = _renderer->getMiterStrokeStyle(); + _strokeStyle = Renderer::getMiterStrokeStyle(); break; case e2d::Stroke::Bevel: - _strokeStyle = _renderer->getBevelStrokeStyle(); + _strokeStyle = Renderer::getBevelStrokeStyle(); break; case e2d::Stroke::Round: - _strokeStyle = _renderer->getRoundStrokeStyle(); + _strokeStyle = Renderer::getRoundStrokeStyle(); break; } } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index aee05668..21cc3974 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -79,11 +79,12 @@ e2d::Node::~Node() } } -void e2d::Node::visit(Game * game) +void e2d::Node::visit() { if (!_visible) return; + auto game = Game::getInstance(); if (!game->isPaused()) { auto updatableNode = dynamic_cast(this); @@ -99,8 +100,7 @@ void e2d::Node::visit(Game * game) _extrapolate = this->getProperty(); } - auto renderer = game->getRenderer(); - auto renderTarget = renderer->getRenderTarget(); + auto renderTarget = Renderer::getInstance()->getRenderTarget(); if (_clipEnabled) { renderTarget->SetTransform(_finalMatri); @@ -116,7 +116,7 @@ void e2d::Node::visit(Game * game) if (drawableNode) { renderTarget->SetTransform(_finalMatri); - drawableNode->draw(renderer); + drawableNode->draw(); } } else @@ -131,7 +131,7 @@ void e2d::Node::visit(Game * game) // 访问 Order 小于零的节点 if (child->getOrder() < 0) { - child->visit(game); + child->visit(); } else { @@ -143,12 +143,12 @@ void e2d::Node::visit(Game * game) if (drawableNode) { renderTarget->SetTransform(_finalMatri); - drawableNode->draw(renderer); + drawableNode->draw(); } // 访问剩余节点 for (; i < _children.size(); ++i) - _children[i]->visit(game); + _children[i]->visit(); } if (_clipEnabled) @@ -157,10 +157,11 @@ void e2d::Node::visit(Game * game) } } -void e2d::Node::drawOutline(Renderer * renderer) +void e2d::Node::drawOutline() { if (_visible) { + auto renderer = Renderer::getInstance(); renderer->getRenderTarget()->SetTransform(_finalMatri); renderer->getRenderTarget()->DrawRectangle( D2D1::RectF(0, 0, _width, _height), @@ -171,7 +172,7 @@ void e2d::Node::drawOutline(Renderer * renderer) // 渲染所有子节点的轮廓 for (const auto& child : _children) { - child->drawOutline(renderer); + child->drawOutline(); } } } @@ -842,7 +843,7 @@ bool e2d::Node::containsPoint(const Point& point) // 为节点创建一个轮廓 BOOL ret = 0; ID2D1RectangleGeometry * rectGeo = nullptr; - auto factory = Game::getInstance()->getRenderer()->getFactory(); + auto factory = Renderer::getFactory(); ThrowIfFailed( factory->CreateRectangleGeometry( @@ -874,7 +875,7 @@ bool e2d::Node::intersects(Node * node) D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN; ID2D1RectangleGeometry *rectGeo = nullptr, *rectGeo2 = nullptr; ID2D1TransformedGeometry *transGeo = nullptr, *transGeo2 = nullptr; - auto factory = Game::getInstance()->getRenderer()->getFactory(); + auto factory = Renderer::getFactory(); ThrowIfFailed( factory->CreateRectangleGeometry( diff --git a/core/Node/Scene.cpp b/core/Node/Scene.cpp index 31110ad5..4850ec3e 100644 --- a/core/Node/Scene.cpp +++ b/core/Node/Scene.cpp @@ -6,6 +6,7 @@ e2d::Scene::Scene() : _outlineVisible(false) , _colliderVisible(false) { + _parentScene = this; } e2d::Scene::~Scene() @@ -22,20 +23,21 @@ void e2d::Scene::setColliderVisible(bool visible) _colliderVisible = visible; } -void e2d::Scene::visit(Game * game) +void e2d::Scene::visit() { - Node::visit(game); + Node::visit(); if (_outlineVisible) { - auto brush = game->getRenderer()->getSolidColorBrush(); + auto brush = Renderer::getInstance()->getSolidColorBrush(); brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f)); brush->SetOpacity(1.f); - this->drawOutline(game->getRenderer()); + this->drawOutline(); } + if (_colliderVisible) { - game->getRenderer()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + Renderer::getInstance()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); this->drawCollider(); } } diff --git a/core/Node/Sprite.cpp b/core/Node/Sprite.cpp index f4c2cc09..dfd7dca8 100644 --- a/core/Node/Sprite.cpp +++ b/core/Node/Sprite.cpp @@ -103,7 +103,7 @@ e2d::Image * e2d::Sprite::getImage() const return _image; } -void e2d::Sprite::draw(Renderer * renderer) const +void e2d::Sprite::draw() const { if (_image && _image->getBitmap()) { @@ -111,7 +111,7 @@ void e2d::Sprite::draw(Renderer * renderer) const float fCropX = _image->getCropX(); float fCropY = _image->getCropY(); // 渲染图片 - renderer->getRenderTarget()->DrawBitmap( + Renderer::getInstance()->getRenderTarget()->DrawBitmap( _image->getBitmap(), D2D1::RectF(0, 0, _width, _height), _displayOpacity, diff --git a/core/Node/Text.cpp b/core/Node/Text.cpp index dbd8e3c7..98f6fae0 100644 --- a/core/Node/Text.cpp +++ b/core/Node/Text.cpp @@ -287,24 +287,25 @@ void e2d::Text::setOutlineStroke(Stroke outlineStroke) _style.outlineStroke = outlineStroke; } -void e2d::Text::draw(Renderer * renderer) const +void e2d::Text::draw() const { if (_textLayout) { + auto renderer = Renderer::getInstance(); // 创建文本区域 D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, _width, _height); // 设置画刷颜色和透明度 renderer->getSolidColorBrush()->SetOpacity(_displayOpacity); // 获取文本渲染器 - auto pTextRenderer = renderer->getTextRenderer(); - pTextRenderer->SetTextStyle( + auto textRenderer = renderer->getTextRenderer(); + textRenderer->SetTextStyle( (D2D1_COLOR_F)_style.color, _style.hasOutline, (D2D1_COLOR_F)_style.outlineColor, _style.outlineWidth, D2D1_LINE_JOIN(_style.outlineStroke) ); - _textLayout->Draw(nullptr, pTextRenderer, 0, 0); + _textLayout->Draw(nullptr, textRenderer, 0, 0); } } @@ -320,49 +321,44 @@ void e2d::Text::_createFormat() { SafeRelease(_textFormat); - HRESULT hr = Game::getInstance()->getRenderer()->getWriteFactory()->CreateTextFormat( - (const WCHAR *)_font.family, - nullptr, - DWRITE_FONT_WEIGHT(_font.weight), - _font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - _font.size, - L"", - &_textFormat + ThrowIfFailed( + Renderer::getWriteFactory()->CreateTextFormat( + (const WCHAR *)_font.family, + nullptr, + DWRITE_FONT_WEIGHT(_font.weight), + _font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + _font.size, + L"", + &_textFormat + ) ); - if (FAILED(hr)) + // 设置文字对齐方式 + _textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(_style.alignment)); + + // 设置行间距 + if (_style.lineSpacing == 0.f) { - WARN("Text::_createFormat error : Create IDWriteTextFormat failed!"); - _textFormat = nullptr; - return; + _textFormat->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0); } else { - // 设置文字对齐方式 - _textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(_style.alignment)); - // 设置行间距 - if (_style.lineSpacing == 0.f) - { - _textFormat->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0); - } - else - { - _textFormat->SetLineSpacing( - DWRITE_LINE_SPACING_METHOD_UNIFORM, - _style.lineSpacing, - _style.lineSpacing * 0.8f - ); - } - // 打开文本自动换行时,设置换行属性 - if (_style.wrapping) - { - _textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP); - } - else - { - _textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); - } + _textFormat->SetLineSpacing( + DWRITE_LINE_SPACING_METHOD_UNIFORM, + _style.lineSpacing, + _style.lineSpacing * 0.8f + ); + } + + // 打开文本自动换行时,设置换行属性 + if (_style.wrapping) + { + _textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP); + } + else + { + _textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); } } @@ -383,52 +379,60 @@ void e2d::Text::_createLayout() return; } - HRESULT hr; UINT32 length = (UINT32)_text.length(); - auto writeFactory = Game::getInstance()->getRenderer()->getWriteFactory(); + auto writeFactory = Renderer::getWriteFactory(); // 对文本自动换行情况下进行处理 if (_style.wrapping) { - hr = writeFactory->CreateTextLayout( - (const WCHAR *)_text, - length, - _textFormat, - _style.wrappingWidth, - 0, - &_textLayout + ThrowIfFailed( + writeFactory->CreateTextLayout( + (const WCHAR *)_text, + length, + _textFormat, + _style.wrappingWidth, + 0, + &_textLayout + ) ); - if (_textLayout) - { - // 获取文本布局的宽度和高度 - DWRITE_TEXT_METRICS metrics; - _textLayout->GetMetrics(&metrics); - // 重设文本宽高 - this->setSize(metrics.layoutWidth, metrics.height); - } + // 获取文本布局的宽度和高度 + DWRITE_TEXT_METRICS metrics; + _textLayout->GetMetrics(&metrics); + // 重设文本宽高 + this->setSize(metrics.layoutWidth, metrics.height); } else { - hr = writeFactory->CreateTextLayout((const WCHAR *)_text, length, _textFormat, 0, 0, &_textLayout); - // 为防止文本对齐问题,根据刚才创建的 layout 宽度重新创建它 - if (_textLayout) - { - // 获取文本布局的宽度和高度 - DWRITE_TEXT_METRICS metrics; - _textLayout->GetMetrics(&metrics); - // 重设文本宽高 - this->setSize(metrics.width, metrics.height); - // 重新创建 layout - SafeRelease(_textLayout); - hr = writeFactory->CreateTextLayout((const WCHAR *)_text, length, _textFormat, _width, 0, &_textLayout); - } - } + // 为防止文本对齐问题,根据先创建 layout 以获取宽度 + ThrowIfFailed( + writeFactory->CreateTextLayout( + (const WCHAR *)_text, + length, + _textFormat, + 0, + 0, + &_textLayout + ) + ); - if (FAILED(hr)) - { - WARN("Text::_createLayout error : Create IDWriteTextLayout failed!"); - _textLayout = nullptr; - return; + // 获取文本布局的宽度和高度 + DWRITE_TEXT_METRICS metrics; + _textLayout->GetMetrics(&metrics); + // 重设文本宽高 + this->setSize(metrics.width, metrics.height); + + // 重新创建 layout + SafeRelease(_textLayout); + ThrowIfFailed( + writeFactory->CreateTextLayout( + (const WCHAR *)_text, + length, + _textFormat, + _width, + 0, + &_textLayout + ) + ); } // 添加下划线和删除线 diff --git a/core/Tool/File.cpp b/core/Tool/File.cpp index 99b7f16c..f5b2ed92 100644 --- a/core/Tool/File.cpp +++ b/core/Tool/File.cpp @@ -70,7 +70,7 @@ e2d::String e2d::File::getExtension() const { String fileExtension; // 找到文件名中的最后一个 '.' 的位置 - size_t pos = _fileName.getWString().find_last_of(L'.'); + size_t pos = std::wstring(_fileName).find_last_of(L'.'); // 判断 pos 是否是有效位置 if (pos != std::wstring::npos) { @@ -79,7 +79,7 @@ e2d::String e2d::File::getExtension() const // 转换为小写字母 fileExtension = fileExtension.toLower(); } - return fileExtension; + return std::move(fileExtension); } bool e2d::File::del() @@ -160,8 +160,7 @@ bool e2d::File::createFolder(const String & dirPath) e2d::String e2d::File::getSaveFilePath(const String& title, const String& defExt) { - auto window = Game::getInstance()->getWindow(); - HWND hwnd = window->getHWnd(); + HWND hwnd = Window::getInstance()->getHWnd(); // 弹出保存对话框 OPENFILENAME ofn = { 0 }; diff --git a/core/Tool/Path.cpp b/core/Tool/Path.cpp index 5383139d..e08e9afc 100644 --- a/core/Tool/Path.cpp +++ b/core/Tool/Path.cpp @@ -12,7 +12,7 @@ e2d::String e2d::Path::getDataPath() { // 设置数据的保存路径 String localAppDataPath = Path::getLocalAppDataPath(); - String title = Game::getInstance()->getWindow()->getTitle(); + String title = Window::getInstance()->getTitle(); String folderName = String::parse(title.hash()); if (!localAppDataPath.isEmpty()) @@ -37,7 +37,7 @@ e2d::String e2d::Path::getTempPath() { // 设置临时文件保存路径 wchar_t path[_MAX_PATH]; - String title = Game::getInstance()->getWindow()->getTitle(); + String title = Window::getInstance()->getTitle(); String folderName = String::parse(title.hash()); if (0 != ::GetTempPath(_MAX_PATH, path)) diff --git a/core/Transition/BoxTransition.cpp b/core/Transition/BoxTransition.cpp index e05f35a6..2f837db2 100644 --- a/core/Transition/BoxTransition.cpp +++ b/core/Transition/BoxTransition.cpp @@ -20,13 +20,14 @@ void e2d::BoxTransition::_update() { Transition::_update(); + auto size = Window::getInstance()->getSize(); if (_delta <= 0.5) { _outLayerParam.contentBounds = D2D1::RectF( - _windowSize.width * _delta, - _windowSize.height * _delta, - _windowSize.width * (1 - _delta), - _windowSize.height * (1 - _delta) + size.width * _delta, + size.height * _delta, + size.width * (1 - _delta), + size.height * (1 - _delta) ); } else @@ -34,10 +35,10 @@ void e2d::BoxTransition::_update() _outLayerParam.opacity = 0; _inLayerParam.opacity = 1; _inLayerParam.contentBounds = D2D1::RectF( - _windowSize.width * (1 - _delta), - _windowSize.height * (1 - _delta), - _windowSize.width * _delta, - _windowSize.height * _delta + size.width * (1 - _delta), + size.height * (1 - _delta), + size.width * _delta, + size.height * _delta ); if (_delta >= 1) { diff --git a/core/Transition/MoveTransition.cpp b/core/Transition/MoveTransition.cpp index 208dbcbb..e7bc7efd 100644 --- a/core/Transition/MoveTransition.cpp +++ b/core/Transition/MoveTransition.cpp @@ -11,27 +11,26 @@ bool e2d::MoveTransition::_init(Game * game, Scene * prev) { if (Transition::_init(game, prev)) { - float width = _windowSize.width; - float height = _windowSize.height; + auto size = Window::getInstance()->getSize(); if (_direction == Direction::Up) { - _posDelta = Vector2(0, -height); - _startPos = Point(0, height); + _posDelta = Vector2(0, -size.height); + _startPos = Point(0, size.height); } else if (_direction == Direction::Down) { - _posDelta = Vector2(0, height); - _startPos = Point(0, -height); + _posDelta = Vector2(0, size.height); + _startPos = Point(0, -size.height); } else if (_direction == Direction::Left) { - _posDelta = Vector2(-width, 0); - _startPos = Point(width, 0); + _posDelta = Vector2(-size.width, 0); + _startPos = Point(size.width, 0); } else if (_direction == Direction::Right) { - _posDelta = Vector2(width, 0); - _startPos = Point(-width, 0); + _posDelta = Vector2(size.width, 0); + _startPos = Point(-size.width, 0); } if (_outScene) _outScene->setPos(0, 0); diff --git a/core/Transition/Transition.cpp b/core/Transition/Transition.cpp index cf7b5f51..c9678d6b 100644 --- a/core/Transition/Transition.cpp +++ b/core/Transition/Transition.cpp @@ -40,7 +40,7 @@ bool e2d::Transition::_init(Game * game, Scene * prev) _outScene->retain(); HRESULT hr = S_OK; - auto renderer = game->getRenderer(); + auto renderer = Renderer::getInstance(); if (_inScene) { hr = renderer->getRenderTarget()->CreateLayer(&_inLayer); @@ -56,7 +56,6 @@ bool e2d::Transition::_init(Game * game, Scene * prev) return false; } - _windowSize = game->getWindow()->getSize(); _outLayerParam = _inLayerParam = D2D1::LayerParameters( D2D1::InfiniteRect(), nullptr, @@ -83,24 +82,25 @@ void e2d::Transition::_update() } } -void e2d::Transition::_render(Game * game) +void e2d::Transition::_render() { - auto renderTarget = game->getRenderer()->getRenderTarget(); + auto renderTarget = Renderer::getInstance()->getRenderTarget(); + auto size = Window::getInstance()->getSize(); if (_outScene) { - Point rootPos = _outScene->getPos(); + auto rootPos = _outScene->getPos(); auto clipRect = D2D1::RectF( std::max(rootPos.x, 0.f), std::max(rootPos.y, 0.f), - std::min(rootPos.x + _windowSize.width, _windowSize.width), - std::min(rootPos.y + _windowSize.height, _windowSize.height) + std::min(rootPos.x + size.width, size.width), + std::min(rootPos.y + size.height, size.height) ); renderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); renderTarget->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); renderTarget->PushLayer(_outLayerParam, _outLayer); - _outScene->visit(game); + _outScene->visit(); renderTarget->PopLayer(); renderTarget->PopAxisAlignedClip(); @@ -112,14 +112,14 @@ void e2d::Transition::_render(Game * game) auto clipRect = D2D1::RectF( std::max(rootPos.x, 0.f), std::max(rootPos.y, 0.f), - std::min(rootPos.x + _windowSize.width, _windowSize.width), - std::min(rootPos.y + _windowSize.height, _windowSize.height) + std::min(rootPos.x + size.width, size.width), + std::min(rootPos.y + size.height, size.height) ); renderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); renderTarget->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); renderTarget->PushLayer(_inLayerParam, _inLayer); - _inScene->visit(game); + _inScene->visit(); renderTarget->PopLayer(); renderTarget->PopAxisAlignedClip(); diff --git a/core/e2dbase.h b/core/e2dbase.h index f293686f..9114d023 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -33,14 +33,11 @@ public: }; public: - Window( - const String& title, /* 窗体标题 */ - int width, /* 窗体宽度 */ - int height, /* 窗体高度 */ - int iconID = 0 /* 窗体图标 */ - ); + // 获取窗体实例 + static Window * getInstance(); - ~Window(); + // 销毁窗体实例 + static void destroyInstance(); // 创建窗体互斥体 bool createMutex( @@ -84,7 +81,7 @@ public: float getDpi() const; // 获取窗口句柄 - HWND getHWnd() const; + HWND getHWnd(); // 打开或隐藏控制台 void setConsoleEnabled( @@ -109,6 +106,12 @@ public: void poll(); private: + Window(); + + ~Window(); + + E2D_DISABLE_COPY(Window); + // 根据客户区大小定位窗口 Rect _locate( int width, @@ -131,6 +134,8 @@ private: String _title; int _iconID; float _dpi; + + static Window * _instance; }; @@ -138,9 +143,11 @@ private: class Input { public: - Input(); + // 获取输入设备实例 + static Input * getInstance(); - ~Input(); + // 销毁输入设备实例 + static void destroyInstance(); // 检测键盘某按键是否正被按下 bool isDown( @@ -170,20 +177,24 @@ public: // 获得鼠标Z轴(鼠标滚轮)坐标增量 float getMouseDeltaZ(); - // 初始化输入设备 - void initWithWindow( - Window * window - ); - // 刷新输入设备状态 void update(); -private: +protected: + Input(); + + ~Input(); + + E2D_DISABLE_COPY(Input); + +protected: IDirectInput8W* _directInput; IDirectInputDevice8W* _keyboardDevice; IDirectInputDevice8W* _mouseDevice; DIMOUSESTATE _mouseState; char _keyBuffer[256]; + + static Input * _instance; }; @@ -191,9 +202,11 @@ private: class Renderer { public: - Renderer(); + // 获取渲染器实例 + static Renderer * getInstance(); - ~Renderer(); + // 销毁实例 + static void destroyInstance(); // 获取背景色 Color getBackgroundColor(); @@ -209,6 +222,12 @@ public: bool show ); + // 开始渲染 + void beginDraw(); + + // 结束渲染 + void endDraw(); + // 获取文字渲染器 TextRenderer * getTextRenderer() const { return _textRenderer; } @@ -219,35 +238,31 @@ public: ID2D1SolidColorBrush * getSolidColorBrush() const { return _solidBrush; } // 获取 ID2D1Factory 对象 - ID2D1Factory * getFactory() const { return _factory; } + static ID2D1Factory * getFactory(); // 获取 IWICImagingFactory 对象 - IWICImagingFactory * getImagingFactory() const { return _imagingFactory; } + static IWICImagingFactory * getImagingFactory(); // 获取 IDWriteFactory 对象 - IDWriteFactory * getWriteFactory() const { return _writeFactory; } + static IDWriteFactory * getWriteFactory(); // 获取 Miter 样式的 ID2D1StrokeStyle - ID2D1StrokeStyle * getMiterStrokeStyle(); + static ID2D1StrokeStyle * getMiterStrokeStyle(); // 获取 Bevel 样式的 ID2D1StrokeStyle - ID2D1StrokeStyle * getBevelStrokeStyle(); + static ID2D1StrokeStyle * getBevelStrokeStyle(); // 获取 Round 样式的 ID2D1StrokeStyle - ID2D1StrokeStyle * getRoundStrokeStyle(); + static ID2D1StrokeStyle * getRoundStrokeStyle(); - // 初始化渲染器 - void initWithWindow( - Window * window - ); +protected: + Renderer(); - // 开始渲染 - void beginDraw(); + ~Renderer(); - // 结束渲染 - void endDraw(); + E2D_DISABLE_COPY(Renderer); -private: +protected: bool _showFps; int _renderTimes; Time _lastRenderTime; @@ -257,12 +272,14 @@ private: IDWriteTextLayout* _fpsLayout; ID2D1SolidColorBrush* _solidBrush; ID2D1HwndRenderTarget* _renderTarget; - ID2D1Factory* _factory; - IWICImagingFactory* _imagingFactory; - IDWriteFactory* _writeFactory; - ID2D1StrokeStyle* _miterStrokeStyle; - ID2D1StrokeStyle* _bevelStrokeStyle; - ID2D1StrokeStyle* _roundStrokeStyle; + + static ID2D1Factory* _factory; + static IWICImagingFactory* _imagingFactory; + static IDWriteFactory* _writeFactory; + static ID2D1StrokeStyle* _miterStrokeStyle; + static ID2D1StrokeStyle* _bevelStrokeStyle; + static ID2D1StrokeStyle* _roundStrokeStyle; + static Renderer * _instance; }; @@ -278,19 +295,8 @@ public: // 获取 Game 实例 static Game * getInstance(); - // 初始化 - void initWithWindow( - Window * window - ); - - // 获取窗体 - Window * getWindow() const { return _window; } - - // 获取输入设备 - Input * getInput() const { return _input; } - - // 获取图形设备 - Renderer * getRenderer() const { return _renderer; } + // 销毁实例 + static void destroyInstance(); // 启动游戏 void start(); @@ -355,15 +361,17 @@ protected: private: bool _quit; bool _paused; - Window* _window; - Input* _input; - Renderer* _renderer; Timer* _timer; Scene* _currScene; Scene* _nextScene; Transition* _transition; - ActionManager* _actionManager; - std::stack _scenes; + Window* _window; + Input* _input; + Renderer* _renderer; + ActionManager* _actionManager; + std::stack _scenes; + + static Game * _instance; }; diff --git a/core/e2dcommon.h b/core/e2dcommon.h index 249846b4..70baca65 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -144,12 +144,6 @@ public: // 判断字符串是否为空 bool isEmpty() const; - // 获取 Unicode 字符串 - std::wstring getWString() const; - - // 获取 ANSI 字符串 - std::string getCString() const; - // 获取指定位置字符 wchar_t at( int index @@ -244,6 +238,8 @@ public: // 类型转换操作符 E2D_OP_EXPLICIT operator const wchar_t* () const; E2D_OP_EXPLICIT operator wchar_t* () const; + E2D_OP_EXPLICIT operator std::wstring () const; + E2D_OP_EXPLICIT operator std::string () const; // 比较运算符 bool operator== (const String &) const; diff --git a/core/e2dnode.h b/core/e2dnode.h index 5e5d644c..c85860d9 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -14,7 +14,7 @@ class Drawable { public: // 渲染图形 - virtual void draw(Renderer * renderer) const = 0; + virtual void draw() const = 0; }; @@ -430,14 +430,10 @@ public: ); // 遍历节点 - virtual void visit( - Game * game - ); + virtual void visit(); // 渲染节点轮廓 - virtual void drawOutline( - Renderer * renderer - ); + virtual void drawOutline(); // 渲染碰撞体轮廓 virtual void drawCollider(); @@ -523,9 +519,7 @@ public: ); // 遍历节点 - virtual void visit( - Game * game - ) override; + virtual void visit() override; protected: E2D_DISABLE_COPY(Scene); @@ -592,9 +586,7 @@ public: Image * getImage() const; // 渲染精灵 - virtual void draw( - Renderer * renderer - ) const override; + virtual void draw() const override; protected: E2D_DISABLE_COPY(Sprite); @@ -799,9 +791,7 @@ public: ); // 渲染文字 - virtual void draw( - Renderer * renderer - ) const override; + virtual void draw() const override; protected: E2D_DISABLE_COPY(Text); @@ -903,9 +893,7 @@ public: ) override; // 遍历节点 - virtual void visit( - Game * game - ) override; + virtual void visit() override; protected: E2D_DISABLE_COPY(Button); @@ -1203,7 +1191,6 @@ protected: protected: float _strokeWidth; Stroke _stroke; - Renderer * _renderer; ID2D1RenderTarget * _renderTarget; ID2D1SolidColorBrush * _fillBrush; ID2D1SolidColorBrush * _lineBrush; diff --git a/core/e2dtransition.h b/core/e2dtransition.h index f6edd7ef..74cbc39a 100644 --- a/core/e2dtransition.h +++ b/core/e2dtransition.h @@ -36,9 +36,7 @@ protected: virtual void _update(); // 渲染场景过渡动画 - virtual void _render( - Game * game - ); + virtual void _render(); // 停止场景过渡动画 virtual void _stop(); @@ -51,7 +49,6 @@ protected: float _duration; float _delta; Time _started; - Size _windowSize; Scene* _outScene; Scene* _inScene; ID2D1Layer * _outLayer;