diff --git a/core/Action/Animate.cpp b/core/Action/Animate.cpp index 385b9b46..2c187440 100644 --- a/core/Action/Animate.cpp +++ b/core/Action/Animate.cpp @@ -26,7 +26,7 @@ e2d::Animation * e2d::Animate::getAnimation() const void e2d::Animate::setAnimation(Animation * animation) { - if (animation && animation != _animation) + if (animation && animation != _animation && !animation->getFrames().empty()) { if (_animation) _animation->release(); _animation = animation; diff --git a/core/Action/Animation.cpp b/core/Action/Animation.cpp index 642a2627..42d0a933 100644 --- a/core/Action/Animation.cpp +++ b/core/Action/Animation.cpp @@ -37,6 +37,7 @@ void e2d::Animation::setInterval(float interval) void e2d::Animation::add(Image * frame) { + WARN_IF(frame == nullptr, "Animation::add failed, frame is nullptr."); if (frame) { _frames.push_back(frame); diff --git a/core/Base/Config.cpp b/core/Base/Config.cpp deleted file mode 100644 index 0a59dcb4..00000000 --- a/core/Base/Config.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "..\e2dbase.h" -#include "..\e2dtool.h" - -e2d::Config::Config() - : _gameName() - , _showFps(false) - , _outlineVisible(false) - , _collisionEnabled(false) - , _colliderVisible(false) -{ -} - -e2d::Config::~Config() -{ -} - -void e2d::Config::setGameName(const String & name) -{ - _gameName = name; -} - -void e2d::Config::showFps(bool show) -{ - _showFps = show; -} - -void e2d::Config::setOutlineVisible(bool visible) -{ - _outlineVisible = visible; -} - -void e2d::Config::setCollisionEnabled(bool enabled) -{ - _collisionEnabled = enabled; -} - -void e2d::Config::setColliderVisible(bool visible) -{ - _colliderVisible = visible; -} - -e2d::String e2d::Config::getGameName() const -{ - return _gameName; -} - -bool e2d::Config::isFpsShow() const -{ - return _showFps; -} - -bool e2d::Config::isOutlineVisible() const -{ - return _outlineVisible; -} - -bool e2d::Config::isCollisionEnabled() const -{ - return _collisionEnabled; -} - -bool e2d::Config::isColliderVisible() const -{ - return _colliderVisible; -} diff --git a/core/Base/GC.cpp b/core/Base/GC.cpp index 8de1a327..e3721700 100644 --- a/core/Base/GC.cpp +++ b/core/Base/GC.cpp @@ -22,9 +22,6 @@ void operator delete(void * block, e2d::autorelease_t const &) E2D_NOEXCEPT } -// GC 机制,用于销毁所有单例 -GC GC::_instance; - e2d::GC::GC() : _notifyed(false) , _cleanup(false) @@ -39,11 +36,6 @@ e2d::GC::~GC() // 清除图片缓存 Image::clearCache(); - - // 删除所有单例 - Timer::destroyInstance(); - ActionManager::destroyInstance(); - CollisionManager::destroyInstance(); } @@ -85,6 +77,7 @@ void e2d::GC::clear() e2d::GC * e2d::GC::getInstance() { + static GC _instance; return &_instance; } diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 987c30a7..b26df78e 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -9,7 +9,6 @@ e2d::Game::Game() : _quit(true) , _paused(false) - , _config() , _window(nullptr) , _input(nullptr) , _renderer(nullptr) @@ -22,6 +21,8 @@ e2d::Game::Game() _input = new (std::nothrow) Input; _renderer = new (std::nothrow) Renderer; + _timer = Timer::getInstance(); + _actionManager = ActionManager::getInstance(); } e2d::Game::~Game() @@ -32,9 +33,6 @@ e2d::Game::~Game() if (_input) delete _input; - if (_window) - delete _window; - CoUninitialize(); } @@ -44,6 +42,13 @@ e2d::Game * e2d::Game::getInstance() return &instance; } +void e2d::Game::initWithWindow(Window * window) +{ + _window = window; + _renderer->initWithWindow(_window); + _input->initWithWindow(_window); +} + void e2d::Game::start() { _quit = false; @@ -66,9 +71,14 @@ void e2d::Game::start() { last = now; _input->update(); - Timer::getInstance()->update(); - ActionManager::getInstance()->update(); - updateScene(); + + if (!_paused) + { + _timer->update(); + _actionManager->update(); + updateScene(); + } + drawScene(); _window->poll(); GC::getInstance()->flush(); @@ -96,8 +106,8 @@ void e2d::Game::resume() { if (_paused && !_quit) { - Timer::getInstance()->updateTime(); - ActionManager::getInstance()->updateTime(); + _timer->updateTime(); + _actionManager->updateTime(); } _paused = false; } @@ -107,23 +117,6 @@ bool e2d::Game::isPaused() return _paused; } -void e2d::Game::setConfig(const Config& config) -{ - _config = config; -} - -const e2d::Config& e2d::Game::getConfig() const -{ - return _config; -} - -void e2d::Game::setWindow(Window * window) -{ - _window = window; - _renderer->init(_window); - _input->init(_window); -} - void e2d::Game::quit() { _quit = true; @@ -161,7 +154,7 @@ void e2d::Game::pushScene(Transition * transition, bool saveCurrentScene) _transition->retain(); // 初始化场景切换动画 - if (!_transition->_init(_currScene)) + if (!_transition->_init(this, _currScene)) { WARN("Transition initialize failed!"); _transition->release(); @@ -205,7 +198,7 @@ e2d::Scene * e2d::Game::popScene(Transition * transition) _transition->_inScene->retain(); // 初始化场景切换动画 - if (!_transition->_init(_currScene)) + if (!_transition->_init(this, _currScene)) { WARN("Transition initialize failed!"); _transition->release(); @@ -277,34 +270,15 @@ void e2d::Game::updateScene() void e2d::Game::drawScene() { - // 渲染画面 _renderer->beginDraw(); { if (_transition) { - _transition->_render(); + _transition->_render(this); } 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(); + _currScene->visit(this); } } _renderer->endDraw(); diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index e2c2ca26..f02ab4b0 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -38,7 +38,7 @@ e2d::Input::~Input() CoUninitialize(); } -void e2d::Input::init(Window * window) +void e2d::Input::initWithWindow(Window * window) { HWND hwnd = window->getHWnd(); diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index 13d992ef..0eedb7cd 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -4,7 +4,8 @@ e2d::Renderer::Renderer() - : _lastRenderTime(Time::now()) + : _showFps(false) + , _lastRenderTime(Time::now()) , _renderTimes(0) , _fpsFormat(nullptr) , _fpsLayout(nullptr) @@ -65,11 +66,8 @@ e2d::Renderer::~Renderer() CoUninitialize(); } -void e2d::Renderer::init(Window * window) +void e2d::Renderer::initWithWindow(Window * window) { - if (!window) - return; - HWND hWnd = window->getHWnd(); RECT rc; @@ -122,6 +120,69 @@ void e2d::Renderer::beginDraw() void e2d::Renderer::endDraw() { + if (_showFps) + { + int duration = (Time::now() - _lastRenderTime).milliseconds(); + + ++_renderTimes; + if (duration >= 100) + { + String fpsText = String::format(L"FPS: %.1f", (1000.f / duration * _renderTimes)); + _lastRenderTime = Time::now(); + _renderTimes = 0; + + if (!_fpsFormat) + { + ThrowIfFailed( + _writeFactory->CreateTextFormat( + L"", + nullptr, + DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + 20, + L"", + &_fpsFormat + ) + ); + + ThrowIfFailed( + _fpsFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP) + ); + } + + SafeRelease(_fpsLayout); + + ThrowIfFailed( + _writeFactory->CreateTextLayout( + (const WCHAR *)fpsText, + (UINT32)fpsText.length(), + _fpsFormat, + 0, + 0, + &_fpsLayout + ) + ); + } + + if (_fpsLayout) + { + _renderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); + _solidBrush->SetOpacity(1.0f); + _textRenderer->SetTextStyle( + D2D1::ColorF(D2D1::ColorF::White), + TRUE, + D2D1::ColorF(D2D1::ColorF::Black, 0.4f), + 1.5f, + D2D1_LINE_JOIN_ROUND + ); + + ThrowIfFailed( + _fpsLayout->Draw(nullptr, _textRenderer, 10, 0) + ); + } + } + // 终止渲染 HRESULT hr = _renderTarget->EndDraw(); @@ -144,69 +205,6 @@ void e2d::Renderer::endDraw() } } -void e2d::Renderer::drawFps() -{ - int duration = (Time::now() - _lastRenderTime).milliseconds(); - - ++_renderTimes; - if (duration >= 100) - { - String fpsText = String::format(L"FPS: %.1f", (1000.f / duration * _renderTimes)); - _lastRenderTime = Time::now(); - _renderTimes = 0; - - if (!_fpsFormat) - { - ThrowIfFailed( - _writeFactory->CreateTextFormat( - L"", - nullptr, - DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - 20, - L"", - &_fpsFormat - ) - ); - - ThrowIfFailed( - _fpsFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP) - ); - } - - SafeRelease(_fpsLayout); - - ThrowIfFailed( - _writeFactory->CreateTextLayout( - (const WCHAR *)fpsText, - (UINT32)fpsText.getLength(), - _fpsFormat, - 0, - 0, - &_fpsLayout - ) - ); - } - - if (_fpsLayout) - { - _renderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); - _solidBrush->SetOpacity(1.0f); - _textRenderer->SetTextStyle( - D2D1::ColorF(D2D1::ColorF::White), - TRUE, - D2D1::ColorF(D2D1::ColorF::Black, 0.4f), - 1.5f, - D2D1_LINE_JOIN_ROUND - ); - - ThrowIfFailed( - _fpsLayout->Draw(nullptr, _textRenderer, 10, 0) - ); - } -} - e2d::Color e2d::Renderer::getBackgroundColor() { return Color(_clearColor.r, _clearColor.g, _clearColor.b, _clearColor.a); @@ -217,6 +215,11 @@ void e2d::Renderer::setBackgroundColor(Color color) _clearColor = (D2D1_COLOR_F)color; } +void e2d::Renderer::showFps(bool show) +{ + _showFps = show; +} + ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle() { if (!_miterStrokeStyle) diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index 1aa52929..25a37e87 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -18,6 +18,9 @@ e2d::Window::Window(const String & title, int width, int height, int iconID) { CoInitialize(nullptr); + // 获取系统 DPI + _dpi = static_cast(::GetDpiForSystem()); + WNDCLASSEX wcex = { 0 }; wcex.cbSize = sizeof(WNDCLASSEX); wcex.lpszClassName = REGISTER_CLASS; @@ -47,7 +50,7 @@ e2d::Window::Window(const String & title, int width, int height, int iconID) RegisterClassEx(&wcex); // 计算窗口大小 - Rect clientRect = __adjustWindow(_width, _height); + Rect clientRect = _locate(_width, _height); // 创建窗口 _hWnd = ::CreateWindowEx( @@ -76,8 +79,6 @@ e2d::Window::Window(const String & title, int width, int height, int iconID) HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE); ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); } - // 获取 DPI - _dpi = static_cast(::GetDpiForWindow(_hWnd)); } else { @@ -136,14 +137,10 @@ bool e2d::Window::createMutex(const String & mutex) return true; } -e2d::Rect e2d::Window::__adjustWindow(int width, int height) +e2d::Rect e2d::Window::_locate(int width, int height) { - float dpiScaleX = 0.f, dpiScaleY = 0.f; - auto renderer = Game::getInstance()->getRenderer(); - renderer->getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); - Rect result; - RECT wRECT = { 0, 0, LONG(ceil(width * dpiScaleX / 96.f)), LONG(ceil(height * dpiScaleY / 96.f)) }; + RECT wRECT = { 0, 0, LONG(ceil(width * _dpi / 96.f)), LONG(ceil(height * _dpi / 96.f)) }; int maxWidth = ::GetSystemMetrics(SM_CXSCREEN); int maxHeight = ::GetSystemMetrics(SM_CYSCREEN); @@ -210,7 +207,7 @@ void e2d::Window::setSize(int width, int height) if (_hWnd) { - Rect wRect = __adjustWindow(width, height); + Rect wRect = _locate(width, height); ::MoveWindow( _hWnd, int(wRect.origin.x), @@ -295,12 +292,9 @@ void e2d::Window::setConsoleEnabled(bool enabled) hwnd = ::GetConsoleWindow(); // 重定向输入输出 FILE * stdoutStream, * stdinStream, * stderrStream; - errno_t err = freopen_s(&stdoutStream, "conout$", "w+t", stdout); - WARN_IF(err != 0, "freopen stdout failed!"); - err = freopen_s(&stdinStream, "conin$", "r+t", stdin); - WARN_IF(err != 0, "freopen stdin failed!"); - err = freopen_s(&stderrStream, "conout$", "w+t", stderr); - WARN_IF(err != 0, "freopen stderr failed!"); + freopen_s(&stdoutStream, "conout$", "w+t", stdout); + freopen_s(&stdinStream, "conin$", "r+t", stdin); + freopen_s(&stderrStream, "conout$", "w+t", stderr); // 禁用控制台关闭按钮 HMENU hmenu = ::GetSystemMenu(hwnd, FALSE); ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); diff --git a/core/Common/Resource.cpp b/core/Common/Resource.cpp index 86bd4008..ec34b1cc 100644 --- a/core/Common/Resource.cpp +++ b/core/Common/Resource.cpp @@ -38,7 +38,7 @@ const e2d::String & e2d::Resource::getResType() const size_t e2d::Resource::getKey() const { - return _isFile ? _fileName.getHashCode() : _resNameId; + return _isFile ? _fileName.hash() : _resNameId; } bool e2d::Resource::operator>(const Resource &res) const diff --git a/core/Common/String.cpp b/core/Common/String.cpp index 7a81d63e..a85c0b58 100644 --- a/core/Common/String.cpp +++ b/core/Common/String.cpp @@ -332,31 +332,17 @@ e2d::String::operator wchar_t*() const return const_cast(_str.c_str()); } -e2d::String::operator const char*() const -{ - static std::string strTmp; - strTmp = static_cast(_bstr_t(_str.c_str())); - return strTmp.c_str(); -} - -e2d::String::operator char*() const -{ - static std::string strTmp; - strTmp = static_cast(_bstr_t(_str.c_str())); - return const_cast(strTmp.c_str()); -} - bool e2d::String::isEmpty() const { return _str.empty(); } -int e2d::String::getLength() const +int e2d::String::length() const { return static_cast(_str.size()); } -size_t e2d::String::getHashCode() const +size_t e2d::String::hash() const { std::hash hash; return hash(_str); diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index b86dc126..a356b5d9 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -3,22 +3,10 @@ #include "..\e2dnode.h" -e2d::ActionManager * e2d::ActionManager::_instance = nullptr; - e2d::ActionManager * e2d::ActionManager::getInstance() { - if (!_instance) - _instance = new (std::nothrow) ActionManager; - return _instance; -} - -void e2d::ActionManager::destroyInstance() -{ - if (_instance) - { - delete _instance; - _instance = nullptr; - } + static ActionManager instance; + return &instance; } e2d::ActionManager::ActionManager() @@ -33,7 +21,7 @@ e2d::ActionManager::~ActionManager() void e2d::ActionManager::update() { - if (_runningActions.empty() || Game::getInstance()->isPaused()) + if (_runningActions.empty()) return; std::vector currActions; diff --git a/core/Manager/CollisionManager.cpp b/core/Manager/CollisionManager.cpp index 08d21728..a8694932 100644 --- a/core/Manager/CollisionManager.cpp +++ b/core/Manager/CollisionManager.cpp @@ -3,25 +3,14 @@ #include "..\e2dtool.h" -e2d::CollisionManager * e2d::CollisionManager::_instance = nullptr; - e2d::CollisionManager * e2d::CollisionManager::getInstance() { - if (!_instance) - _instance = new (std::nothrow) CollisionManager; - return _instance; -} - -void e2d::CollisionManager::destroyInstance() -{ - if (_instance) - { - delete _instance; - _instance = nullptr; - } + static CollisionManager instance; + return &instance; } e2d::CollisionManager::CollisionManager() + : _collisionEnabled(false) { } @@ -45,10 +34,7 @@ void e2d::CollisionManager::__removeCollider(Collider * collider) void e2d::CollisionManager::__updateCollider(Collider* collider) { - auto game = Game::getInstance(); - if (game->isPaused() || - !game->getConfig().isCollisionEnabled() || - game->isTransitioning()) + if (!_collisionEnabled) return; std::vector currColliders; @@ -92,11 +78,16 @@ void e2d::CollisionManager::__updateCollider(Collider* collider) } } +void e2d::CollisionManager::setCollisionEnabled(bool enabled) +{ + _collisionEnabled = enabled; +} + void e2d::CollisionManager::addName(const String & name1, const String & name2) { if (!name1.isEmpty() && !name2.isEmpty()) { - _collisionList.insert(std::make_pair(name1.getHashCode(), name2.getHashCode())); + _collisionList.insert(std::make_pair(name1.hash(), name2.hash())); } } @@ -106,7 +97,7 @@ void e2d::CollisionManager::addName(const std::vector { if (!name.first.isEmpty() && !name.second.isEmpty()) { - _collisionList.insert(std::make_pair(name.first.getHashCode(), name.second.getHashCode())); + _collisionList.insert(std::make_pair(name.first.hash(), name.second.hash())); } } } @@ -118,8 +109,8 @@ bool e2d::CollisionManager::isCollidable(Node * node1, Node * node2) bool e2d::CollisionManager::isCollidable(const String & name1, const String & name2) { - size_t hashName1 = name1.getHashCode(), - hashName2 = name2.getHashCode(); + size_t hashName1 = name1.hash(), + hashName2 = name2.hash(); auto pair1 = std::make_pair(hashName1, hashName2), pair2 = std::make_pair(hashName2, hashName1); for (const auto& pair : _collisionList) diff --git a/core/Node/Button.cpp b/core/Node/Button.cpp index 19aeaba0..d248e343 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(Renderer* renderer) +void e2d::Button::visit(Game * game) { - Node::visit(renderer); + Node::visit(game); if (_visible && !_enabled && _normal && - _normal->containsPoint(Game::getInstance()->getInput()->getMousePos())) + _normal->containsPoint(game->getInput()->getMousePos())) { - Game::getInstance()->getWindow()->setCursor(Window::Cursor::No); + game->getWindow()->setCursor(Window::Cursor::No); } else if (_status == Status::Mouseover || _status == Status::Selected) { - Game::getInstance()->getWindow()->setCursor(Window::Cursor::Hand); + game->getWindow()->setCursor(Window::Cursor::Hand); } } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index f57635b1..accb7eb2 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -79,7 +79,7 @@ e2d::Node::~Node() } } -void e2d::Node::visit(Renderer * renderer) +void e2d::Node::visit(Game * game) { if (!_visible) return; @@ -90,11 +90,12 @@ void e2d::Node::visit(Renderer * renderer) // 保留差别属性 _extrapolate = this->getProperty(); - auto pRT = renderer->getRenderTarget(); + auto renderer = game->getRenderer(); + auto renderTarget = renderer->getRenderTarget(); if (_clipEnabled) { - pRT->SetTransform(_finalMatri); - pRT->PushAxisAlignedClip( + renderTarget->SetTransform(_finalMatri); + renderTarget->PushAxisAlignedClip( D2D1::RectF(0, 0, _width, _height), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE ); @@ -102,7 +103,7 @@ void e2d::Node::visit(Renderer * renderer) if (_children.empty()) { - pRT->SetTransform(_finalMatri); + renderTarget->SetTransform(_finalMatri); this->draw(renderer); } else @@ -117,7 +118,7 @@ void e2d::Node::visit(Renderer * renderer) // 访问 Order 小于零的节点 if (child->getOrder() < 0) { - child->visit(renderer); + child->visit(game); } else { @@ -125,17 +126,17 @@ void e2d::Node::visit(Renderer * renderer) } } - pRT->SetTransform(_finalMatri); + renderTarget->SetTransform(_finalMatri); this->draw(renderer); // 访问剩余节点 for (; i < _children.size(); ++i) - _children[i]->visit(renderer); + _children[i]->visit(game); } if (_clipEnabled) { - pRT->PopAxisAlignedClip(); + renderTarget->PopAxisAlignedClip(); } } @@ -659,7 +660,7 @@ e2d::Scene * e2d::Node::getParentScene() const std::vector e2d::Node::getChildren(const String& name) const { std::vector vChildren; - size_t hash = name.getHashCode(); + size_t hash = name.hash(); for (const auto& child : _children) { @@ -674,7 +675,7 @@ std::vector e2d::Node::getChildren(const String& name) const e2d::Node * e2d::Node::getChild(const String& name) const { - size_t hash = name.getHashCode(); + size_t hash = name.hash(); for (const auto& child : _children) { @@ -744,7 +745,7 @@ void e2d::Node::removeChildren(const String& childName) } // 计算名称 Hash 值 - size_t hash = childName.getHashCode(); + size_t hash = childName.hash(); auto iter = std::find_if( _children.begin(), @@ -935,7 +936,7 @@ void e2d::Node::setName(const String& name) // 保存节点名 _name = name; // 保存节点 Hash 名 - _hashName = name.getHashCode(); + _hashName = name.hash(); } } diff --git a/core/Node/Scene.cpp b/core/Node/Scene.cpp index d55af33c..31110ad5 100644 --- a/core/Node/Scene.cpp +++ b/core/Node/Scene.cpp @@ -3,9 +3,39 @@ #include "..\e2dmanager.h" e2d::Scene::Scene() + : _outlineVisible(false) + , _colliderVisible(false) { } e2d::Scene::~Scene() { } + +void e2d::Scene::setOutlineVisible(bool visible) +{ + _outlineVisible = visible; +} + +void e2d::Scene::setColliderVisible(bool visible) +{ + _colliderVisible = visible; +} + +void e2d::Scene::visit(Game * game) +{ + Node::visit(game); + + if (_outlineVisible) + { + auto brush = game->getRenderer()->getSolidColorBrush(); + brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f)); + brush->SetOpacity(1.f); + this->drawOutline(game->getRenderer()); + } + if (_colliderVisible) + { + game->getRenderer()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + this->drawCollider(); + } +} diff --git a/core/Node/Text.cpp b/core/Node/Text.cpp index 08749d95..5cb74ff7 100644 --- a/core/Node/Text.cpp +++ b/core/Node/Text.cpp @@ -384,7 +384,7 @@ void e2d::Text::_createLayout() } HRESULT hr; - UINT32 length = (UINT32)_text.getLength(); + UINT32 length = (UINT32)_text.length(); auto writeFactory = Game::getInstance()->getRenderer()->getWriteFactory(); // 对文本自动换行情况下进行处理 diff --git a/core/Tool/File.cpp b/core/Tool/File.cpp index 125d9c0c..14d0702d 100644 --- a/core/Tool/File.cpp +++ b/core/Tool/File.cpp @@ -122,7 +122,7 @@ void e2d::File::addSearchPath(const String & path) { String tmp = path; tmp.replace(L"/", L"\\"); - if (tmp[tmp.getLength() - 1] != L'\\') + if (tmp[tmp.length() - 1] != L'\\') { tmp << L"\\"; } @@ -135,11 +135,11 @@ void e2d::File::addSearchPath(const String & path) bool e2d::File::createFolder(const String & dirPath) { - if (dirPath.isEmpty() || dirPath.getLength() >= MAX_PATH) + if (dirPath.isEmpty() || dirPath.length() >= MAX_PATH) return false; wchar_t tmpDirPath[_MAX_PATH] = { 0 }; - int length = dirPath.getLength(); + int length = dirPath.length(); for (int i = 0; i < length; ++i) { @@ -177,7 +177,7 @@ e2d::String e2d::File::getSaveFilePath(const String& title, const String& defExt ofn.lpstrTitle = (LPCWSTR)title; // 标题 ofn.lpstrDefExt = (LPCWSTR)defExt; // 默认追加的扩展名 - if (GetSaveFileName(&ofn)) + if (::GetSaveFileName(&ofn)) { return strFilename; } diff --git a/core/Tool/Path.cpp b/core/Tool/Path.cpp index 4f32ba29..5383139d 100644 --- a/core/Tool/Path.cpp +++ b/core/Tool/Path.cpp @@ -12,10 +12,12 @@ e2d::String e2d::Path::getDataPath() { // 设置数据的保存路径 String localAppDataPath = Path::getLocalAppDataPath(); - String gameName = Game::getInstance()->getConfig().getGameName(); - if (!localAppDataPath.isEmpty() && !gameName.isEmpty()) + String title = Game::getInstance()->getWindow()->getTitle(); + String folderName = String::parse(title.hash()); + + if (!localAppDataPath.isEmpty()) { - dataPath = localAppDataPath + L"\\Easy2DGameData\\" << gameName << L"\\"; + dataPath = localAppDataPath + L"\\Easy2DGameData\\" << folderName << L"\\"; File file(dataPath); if (!file.exists() && !File::createFolder(dataPath)) @@ -35,11 +37,12 @@ e2d::String e2d::Path::getTempPath() { // 设置临时文件保存路径 wchar_t path[_MAX_PATH]; - String gameName = Game::getInstance()->getConfig().getGameName(); + String title = Game::getInstance()->getWindow()->getTitle(); + String folderName = String::parse(title.hash()); - if (0 != ::GetTempPath(_MAX_PATH, path) && !gameName.isEmpty()) + if (0 != ::GetTempPath(_MAX_PATH, path)) { - tempPath << path << L"\\Easy2DGameTemp\\" << gameName << L"\\"; + tempPath << path << L"\\Easy2DGameTemp\\" << folderName << L"\\"; File file(tempPath); if (!file.exists() && !File::createFolder(tempPath)) diff --git a/core/Tool/Timer.cpp b/core/Tool/Timer.cpp index caeda070..29a6f859 100644 --- a/core/Tool/Timer.cpp +++ b/core/Tool/Timer.cpp @@ -1,21 +1,10 @@ #include "..\e2dtool.h" -e2d::Timer * e2d::Timer::_instance = nullptr; e2d::Timer * e2d::Timer::getInstance() { - if (!_instance) - _instance = new (std::nothrow) Timer; - return _instance; -} - -void e2d::Timer::destroyInstance() -{ - if (_instance) - { - delete _instance; - _instance = nullptr; - } + static Timer instance; + return &instance; } e2d::Timer::Timer() @@ -112,7 +101,7 @@ void e2d::Timer::clearAllTasks() void e2d::Timer::update() { - if (_tasks.empty() || Game::getInstance()->isPaused()) + if (_tasks.empty()) return; std::vector currTasks; diff --git a/core/Transition/BoxTransition.cpp b/core/Transition/BoxTransition.cpp index 61c06c05..e05f35a6 100644 --- a/core/Transition/BoxTransition.cpp +++ b/core/Transition/BoxTransition.cpp @@ -6,9 +6,9 @@ e2d::BoxTransition::BoxTransition(Scene* scene, float duration) { } -bool e2d::BoxTransition::_init(Scene * prev) +bool e2d::BoxTransition::_init(Game * game, Scene * prev) { - if (Transition::_init(prev)) + if (Transition::_init(game, prev)) { _inLayerParam.opacity = 0; return true; diff --git a/core/Transition/EmergeTransition.cpp b/core/Transition/EmergeTransition.cpp index 9aabb5aa..ff11f1a6 100644 --- a/core/Transition/EmergeTransition.cpp +++ b/core/Transition/EmergeTransition.cpp @@ -6,9 +6,9 @@ e2d::EmergeTransition::EmergeTransition(Scene* scene, float duration) { } -bool e2d::EmergeTransition::_init(Scene * prev) +bool e2d::EmergeTransition::_init(Game * game, Scene * prev) { - if (Transition::_init(prev)) + if (Transition::_init(game, prev)) { _outLayerParam.opacity = 1; _inLayerParam.opacity = 0; diff --git a/core/Transition/FadeTransition.cpp b/core/Transition/FadeTransition.cpp index 23edb392..be5b3a00 100644 --- a/core/Transition/FadeTransition.cpp +++ b/core/Transition/FadeTransition.cpp @@ -6,9 +6,9 @@ e2d::FadeTransition::FadeTransition(Scene* scene, float duration) { } -bool e2d::FadeTransition::_init(Scene * prev) +bool e2d::FadeTransition::_init(Game * game, Scene * prev) { - if (Transition::_init(prev)) + if (Transition::_init(game, prev)) { _outLayerParam.opacity = 1; _inLayerParam.opacity = 0; diff --git a/core/Transition/MoveTransition.cpp b/core/Transition/MoveTransition.cpp index b5dae0e1..208dbcbb 100644 --- a/core/Transition/MoveTransition.cpp +++ b/core/Transition/MoveTransition.cpp @@ -7,9 +7,9 @@ e2d::MoveTransition::MoveTransition(Scene* scene, float duration, Direction dire { } -bool e2d::MoveTransition::_init(Scene * prev) +bool e2d::MoveTransition::_init(Game * game, Scene * prev) { - if (Transition::_init(prev)) + if (Transition::_init(game, prev)) { float width = _windowSize.width; float height = _windowSize.height; diff --git a/core/Transition/Transition.cpp b/core/Transition/Transition.cpp index 2544ed7c..cf7b5f51 100644 --- a/core/Transition/Transition.cpp +++ b/core/Transition/Transition.cpp @@ -31,7 +31,7 @@ bool e2d::Transition::isDone() return _end; } -bool e2d::Transition::_init(Scene * prev) +bool e2d::Transition::_init(Game * game, Scene * prev) { _started = Time::now(); _outScene = prev; @@ -39,9 +39,8 @@ bool e2d::Transition::_init(Scene * prev) if (_outScene) _outScene->retain(); - // 创建图层 HRESULT hr = S_OK; - auto renderer = Game::getInstance()->getRenderer(); + auto renderer = game->getRenderer(); if (_inScene) { hr = renderer->getRenderTarget()->CreateLayer(&_inLayer); @@ -57,7 +56,7 @@ bool e2d::Transition::_init(Scene * prev) return false; } - _windowSize = Game::getInstance()->getWindow()->getSize(); + _windowSize = game->getWindow()->getSize(); _outLayerParam = _inLayerParam = D2D1::LayerParameters( D2D1::InfiniteRect(), nullptr, @@ -84,10 +83,9 @@ void e2d::Transition::_update() } } -void e2d::Transition::_render() +void e2d::Transition::_render(Game * game) { - auto renderer = Game::getInstance()->getRenderer(); - auto pRT = renderer->getRenderTarget(); + auto renderTarget = game->getRenderer()->getRenderTarget(); if (_outScene) { @@ -98,14 +96,14 @@ void e2d::Transition::_render() std::min(rootPos.x + _windowSize.width, _windowSize.width), std::min(rootPos.y + _windowSize.height, _windowSize.height) ); - pRT->SetTransform(D2D1::Matrix3x2F::Identity()); - pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - pRT->PushLayer(_outLayerParam, _outLayer); + renderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); + renderTarget->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); + renderTarget->PushLayer(_outLayerParam, _outLayer); - _outScene->visit(renderer); + _outScene->visit(game); - pRT->PopLayer(); - pRT->PopAxisAlignedClip(); + renderTarget->PopLayer(); + renderTarget->PopAxisAlignedClip(); } if (_inScene) @@ -117,14 +115,14 @@ void e2d::Transition::_render() std::min(rootPos.x + _windowSize.width, _windowSize.width), std::min(rootPos.y + _windowSize.height, _windowSize.height) ); - pRT->SetTransform(D2D1::Matrix3x2F::Identity()); - pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - pRT->PushLayer(_inLayerParam, _inLayer); + renderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); + renderTarget->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); + renderTarget->PushLayer(_inLayerParam, _inLayer); - _inScene->visit(renderer); + _inScene->visit(game); - pRT->PopLayer(); - pRT->PopAxisAlignedClip(); + renderTarget->PopLayer(); + renderTarget->PopAxisAlignedClip(); } } diff --git a/core/e2dbase.h b/core/e2dbase.h index 17539ea2..f293686f 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -10,68 +10,6 @@ namespace e2d { -// 配置 -class Config -{ -public: - Config(); - - virtual ~Config(); - - // 修改游戏名称 - // 默认:空 - void setGameName( - const String& name - ); - - // 显示或隐藏 FPS - // 默认:隐藏 - void showFps( - bool show - ); - - // 显示或隐藏节点轮廓 - // 默认:隐藏 - void setOutlineVisible( - bool visible - ); - - // 打开或关闭碰撞监听 - // 默认:关闭 - void setCollisionEnabled( - bool enabled - ); - - // 打开或关闭碰撞体可视化 - // 默认:关闭 - void setColliderVisible( - bool visible - ); - - // 获取游戏名称 - String getGameName() const; - - // 获取 FPS 显示状态 - bool isFpsShow() const; - - // 获取节点轮廓显示状态 - bool isOutlineVisible() const; - - // 获取碰撞监听状态 - bool isCollisionEnabled() const; - - // 获取碰撞体可视化状态 - bool isColliderVisible() const; - -protected: - bool _showFps; - bool _outlineVisible; - bool _collisionEnabled; - bool _colliderVisible; - String _gameName; -}; - - // 窗体 class Window { @@ -171,8 +109,8 @@ public: void poll(); private: - // 根据客户区大小计算合适的窗口区域 - Rect __adjustWindow( + // 根据客户区大小定位窗口 + Rect _locate( int width, int height ); @@ -232,14 +170,14 @@ public: // 获得鼠标Z轴(鼠标滚轮)坐标增量 float getMouseDeltaZ(); - // 刷新输入设备状态 - void update(); - - // 初始化渲染器(不应手动调用该函数) - void init( + // 初始化输入设备 + void initWithWindow( Window * window ); + // 刷新输入设备状态 + void update(); + private: IDirectInput8W* _directInput; IDirectInputDevice8W* _keyboardDevice; @@ -249,7 +187,7 @@ private: }; -// 图形设备 +// 渲染器 class Renderer { public: @@ -265,6 +203,12 @@ public: Color color ); + // 显示或隐藏 FPS + // 默认:隐藏 + void showFps( + bool show + ); + // 获取文字渲染器 TextRenderer * getTextRenderer() const { return _textRenderer; } @@ -292,8 +236,8 @@ public: // 获取 Round 样式的 ID2D1StrokeStyle ID2D1StrokeStyle * getRoundStrokeStyle(); - // 初始化渲染器(不应手动调用该函数) - void init( + // 初始化渲染器 + void initWithWindow( Window * window ); @@ -303,10 +247,8 @@ public: // 结束渲染 void endDraw(); - // 渲染 FPS - void drawFps(); - private: + bool _showFps; int _renderTimes; Time _lastRenderTime; D2D1_COLOR_F _clearColor; @@ -324,6 +266,8 @@ private: }; +class Timer; +class ActionManager; class Scene; class Transition; @@ -334,6 +278,11 @@ public: // 获取 Game 实例 static Game * getInstance(); + // 初始化 + void initWithWindow( + Window * window + ); + // 获取窗体 Window * getWindow() const { return _window; } @@ -343,19 +292,6 @@ public: // 获取图形设备 Renderer * getRenderer() const { return _renderer; } - // 获取游戏配置 - const Config& getConfig() const; - - // 设置窗体 - void setWindow( - Window * window - ); - - // 修改游戏配置 - void setConfig( - const Config& config - ); - // 启动游戏 void start(); @@ -419,18 +355,19 @@ protected: private: bool _quit; bool _paused; - Config _config; Window* _window; Input* _input; Renderer* _renderer; + Timer* _timer; Scene* _currScene; Scene* _nextScene; Transition* _transition; + ActionManager* _actionManager; std::stack _scenes; }; -// 垃圾回收器 +// 垃圾回收池 class GC { public: @@ -464,8 +401,6 @@ private: bool _notifyed; bool _cleanup; std::set _pool; - - static GC _instance; }; } \ No newline at end of file diff --git a/core/e2dcommon.h b/core/e2dcommon.h index 0274d56f..ddfde679 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -135,14 +135,14 @@ public: ~String(); - // 判断字符串是否为空 - bool isEmpty() const; - // 获取字符串长度 - int getLength() const; + int length() const; // 获取该字符串的散列值 - size_t getHashCode() const; + size_t hash() const; + + // 判断字符串是否为空 + bool isEmpty() const; // 获取 Unicode 字符串 std::wstring getWString() const; @@ -244,8 +244,6 @@ public: // 类型转换操作符 E2D_OP_EXPLICIT operator const wchar_t* () const; E2D_OP_EXPLICIT operator wchar_t* () const; - E2D_OP_EXPLICIT operator const char* () const; - E2D_OP_EXPLICIT operator char* () const; // 比较运算符 bool operator== (const String &) const; diff --git a/core/e2dmanager.h b/core/e2dmanager.h index 57dcfa93..0f6ada8d 100644 --- a/core/e2dmanager.h +++ b/core/e2dmanager.h @@ -18,9 +18,6 @@ public: // 获取动作管理器实例 static ActionManager * getInstance(); - // 销毁实例 - static void destroyInstance(); - // 获取所有名称相同的动作 std::vector get( const String& name @@ -100,8 +97,6 @@ private: private: std::vector _actions; std::vector _runningActions; - - static ActionManager * _instance; }; @@ -115,8 +110,11 @@ public: // 获取碰撞体管理器实例 static CollisionManager * getInstance(); - // 销毁实例 - static void destroyInstance(); + // 打开或关闭碰撞监听 + // 默认:关闭 + void setCollisionEnabled( + bool enabled + ); // 添加可互相碰撞物体的名称 void addName( @@ -164,10 +162,9 @@ private: ); private: + bool _collisionEnabled; std::vector _colliders; std::set> _collisionList; - - static CollisionManager * _instance; }; } \ No newline at end of file diff --git a/core/e2dnode.h b/core/e2dnode.h index 5a041c02..bc61510d 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -398,7 +398,7 @@ public: // 遍历节点 virtual void visit( - Renderer * renderer + Game * game ); // 渲染节点轮廓 @@ -474,8 +474,29 @@ public: // 说明:返回 false 将阻止窗口关闭 virtual bool onCloseWindow() { return true; } + // 显示或隐藏节点轮廓 + // 默认:隐藏 + void setOutlineVisible( + bool visible + ); + + // 打开或关闭碰撞体可视化 + // 默认:关闭 + void setColliderVisible( + bool visible + ); + + // 遍历节点 + virtual void visit( + Game * game + ) override; + protected: E2D_DISABLE_COPY(Scene); + +protected: + bool _outlineVisible; + bool _colliderVisible; }; @@ -843,9 +864,9 @@ public: bool handled ) override; - // 渲染节点 + // 遍历节点 virtual void visit( - Renderer * renderer + Game * game ) override; protected: diff --git a/core/e2dtool.h b/core/e2dtool.h index 352b24f3..6708e351 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -283,9 +283,6 @@ public: // 获取定时器实例 static Timer * getInstance(); - // 销毁实例 - static void destroyInstance(); - // 添加任务 void addTask( Task * task @@ -333,8 +330,6 @@ private: private: std::vector _tasks; - - static Timer * _instance; }; diff --git a/core/e2dtransition.h b/core/e2dtransition.h index 75348c9c..f6edd7ef 100644 --- a/core/e2dtransition.h +++ b/core/e2dtransition.h @@ -28,6 +28,7 @@ public: protected: // 初始化场景过渡动画 virtual bool _init( + Game * game, Scene * prev ); @@ -35,7 +36,9 @@ protected: virtual void _update(); // 渲染场景过渡动画 - virtual void _render(); + virtual void _render( + Game * game + ); // 停止场景过渡动画 virtual void _stop(); @@ -73,6 +76,7 @@ protected: virtual void _update() override; virtual bool _init( + Game * game, Scene * prev ) override; }; @@ -92,6 +96,7 @@ protected: virtual void _update() override; virtual bool _init( + Game * game, Scene * prev ) override; }; @@ -111,6 +116,7 @@ protected: virtual void _update() override; virtual bool _init( + Game * game, Scene * prev ) override; }; @@ -131,6 +137,7 @@ protected: virtual void _update() override; virtual bool _init( + Game * game, Scene * prev ) override; diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index 1ff56162..dfa03e46 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -51,7 +51,6 @@ - diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index 39cdad0d..c8bd501b 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -232,9 +232,6 @@ Event - - Base - Node diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 12e0a26a..5398932d 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -195,7 +195,6 @@ - diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 49e106d8..66eaa534 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -232,9 +232,6 @@ Event - - Base - Node diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 7cc4a6c2..4085a90d 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -215,7 +215,6 @@ - diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 44bca1b5..250d3c49 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -225,9 +225,6 @@ Common - - Base - Node