From 489fa780ca3e939b5d1a0116e68c5df9feb1c373 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sat, 14 Oct 2017 18:43:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0ENode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/Demo.vcxproj | 2 +- Demo/main.cpp | 29 ++-- Easy2D/Base/EApp.cpp | 36 ++--- Easy2D/Base/EScene.cpp | 123 +++++++++------- Easy2D/Easy2D.vcxproj | 3 +- Easy2D/Easy2D.vcxproj.filters | 3 + Easy2D/Node/ENode.cpp | 267 ++++++++++++++++++++++++++-------- Easy2D/Node/ERectangle.cpp | 19 +++ Easy2D/Win/winbase.cpp | 7 + Easy2D/Win/winbase.h | 2 + Easy2D/ebase.h | 18 ++- Easy2D/enodes.h | 76 ++++++++-- Easy2D/etools.h | 8 + 13 files changed, 420 insertions(+), 173 deletions(-) create mode 100644 Easy2D/Node/ERectangle.cpp diff --git a/Demo/Demo.vcxproj b/Demo/Demo.vcxproj index a61d8f52..1f739914 100644 --- a/Demo/Demo.vcxproj +++ b/Demo/Demo.vcxproj @@ -23,7 +23,7 @@ {9D85A92F-BCCE-4EF0-BAD3-601C0086661C} Win32Proj Demo - 10.0.16299.0 + 10.0.15063.0 diff --git a/Demo/main.cpp b/Demo/main.cpp index 21517e10..9d44fbba 100644 --- a/Demo/main.cpp +++ b/Demo/main.cpp @@ -10,37 +10,26 @@ int WINAPI WinMain( { EApp app; - if (app.init(L"Easy2D Demo", 640, 480, true)) + if (app.init(L"Easy2D Demo", 640, 480)) { auto scene = new EScene(); - auto node = new ENode(); + auto node = new ENode(L"node1"); node->setPos(50, 80); - node->setSize(30, 180); + node->setSize(30, 30); scene->add(node); - auto mlistener = new EMouseClickListener([=](EPoint) { - node->setPos(EMouseMsg::getPos()); - }); + auto node2 = new ENode(L"node2"); + node2->setPos(20, 20); + node2->setSize(40, 40); + node->addChild(node2); - auto klistener = new EKeyPressListener([=] { - if (EKeyMsg::isCapitalLockOn()) - { - if (EKeyMsg::getVal() == EKeyMsg::KEY::LEFT) - { - node->move(-3, 0); - } - if (EKeyMsg::getVal() == EKeyMsg::KEY::RIGHT) - { - node->move(3, 0); - } - } + auto mlistener = new EMouseClickListener([](EPoint) { + EApp::getCurrentScene()->getChild(L"node1")->setPos(EMouseMsg::getPos()); }); mlistener->bindWith(node); - scene->bindListener(klistener); - app.enterScene(scene); app.run(); diff --git a/Easy2D/Base/EApp.cpp b/Easy2D/Base/EApp.cpp index 3190abd6..9e746923 100644 --- a/Easy2D/Base/EApp.cpp +++ b/Easy2D/Base/EApp.cpp @@ -21,7 +21,6 @@ std::stack s_SceneStack; e2d::EApp::EApp() : m_bRunning(false) , m_ClearColor(EColor::Black) - , m_bSaveScene(true) , m_pCurrentScene(nullptr) , m_pNextScene(nullptr) { @@ -340,15 +339,22 @@ void e2d::EApp::enterScene(EScene * scene, bool save /* = true */) // 保存下一场景的指针 get()->m_pNextScene = scene; // 切换场景时,是否保存当前场景 - get()->m_bSaveScene = save; + if (get()->m_pCurrentScene) + { + get()->m_pCurrentScene->m_bWillSave = save; + } } void e2d::EApp::backScene() { // 从栈顶取出场景指针,作为下一场景 get()->m_pNextScene = s_SceneStack.top(); + s_SceneStack.pop(); // 不保存当前场景 - get()->m_bSaveScene = false; + if (get()->m_pCurrentScene) + { + get()->m_pCurrentScene->m_bWillSave = false; + } } void e2d::EApp::clearScene() @@ -404,7 +410,7 @@ void e2d::EApp::free() SafeDelete(&temp); s_SceneStack.pop(); } - // 删除所有定时器、监听器 + // 删除所有定时器、监听器和动画 //Timer::clearAllTimers(); EMsgManager::clearAllKeyboardListeners(); EMsgManager::clearAllMouseListeners(); @@ -425,36 +431,18 @@ void e2d::EApp::end() void e2d::EApp::_enterNextScene() { - // 若下一场景处于栈顶,说明正在返回上一场景 - if (s_SceneStack.size() && m_pNextScene == s_SceneStack.top()) - { - // 返回上一场景时,恢复场景上的定时器 - //Timer::notifyAllSceneTimers(m_pNextScene); - EMsgManager::notifyAllListenersBindWithScene(m_pNextScene); - //ActionManager::notifyAllSceneActions(m_pNextScene); - // 删除栈顶场景 - s_SceneStack.pop(); - } - // 执行当前场景的 onExit 函数 if (m_pCurrentScene) { m_pCurrentScene->onExit(); - if (m_bSaveScene) + + if (m_pCurrentScene->m_bWillSave) { // 若要保存当前场景,把它放入栈中 s_SceneStack.push(m_pCurrentScene); - // 暂停当前场景上运行的所有定时器 - //Timer::waitAllSceneTimers(m_pCurrentScene); - EMsgManager::waitAllListenersBindWithScene(m_pCurrentScene); - //ActionManager::waitAllSceneActions(m_pCurrentScene); } else { - // 不保存场景时,停止当前场景上运行的所有定时器,并删除当前场景 - //Timer::clearAllSceneTimers(m_pCurrentScene); - EMsgManager::clearAllListenersBindWithScene(m_pCurrentScene); - //ActionManager::stopAllSceneActions(m_pCurrentScene); SafeDelete(&m_pCurrentScene); } } diff --git a/Easy2D/Base/EScene.cpp b/Easy2D/Base/EScene.cpp index 50b69dd5..03dc47ed 100644 --- a/Easy2D/Base/EScene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -1,79 +1,91 @@ #include "..\ebase.h" #include "..\enodes.h" #include "..\emsg.h" +#include +e2d::EScene::EScene() + : m_bWillSave(true) + , m_bSortNeeded(false) +{ +} e2d::EScene::~EScene() { clearAllChildren(); } -/*void e2d::EScene::_exec() -{ - // active 标志画面是否取得焦点 - bool active = true; - // 逆序执行,最后绘制的节点(即位于画面最上方)最先被访问 - for (int i = int(m_vChildren.size()) - 1; i >= 0; i--) - { - if (m_vChildren[i]->_exec(active)) // 执行节点程序 - { - active = false; // 若子节点取得焦点,将标志置 false - } - } -}*/ - void e2d::EScene::_onRender() { - // 绘制所有节点 + this->_sortChildren(); + + // 访问所有节点 for (auto child : m_vChildren) { - child->_onRender(); + child->callOn(); + } +} + +void e2d::EScene::_sortChildren() +{ + if (m_bSortNeeded) + { + m_bSortNeeded = false; + + // 子节点排序 + std::sort( + std::begin(m_vChildren), + std::end(m_vChildren), + [](ENode * n1, ENode * n2) { + return n1->getOrder() < n2->getOrder(); + } + ); } } void e2d::EScene::onEnter() { + // 启用场景上的所有定时器、监听器和动画 + //Timer::notifyAllSceneTimers(m_pNextScene); + EMsgManager::notifyAllListenersBindWithScene(this); + //ActionManager::notifyAllSceneActions(m_pNextScene); } void e2d::EScene::onExit() { -} - -void e2d::EScene::add(ENode * child, int zOrder /* = 0 */) -{ - // 断言添加的节点非空 - ASSERT(child != nullptr, "Scene::add NULL pointer exception."); - // 忽略空指针 - if (child == nullptr) return; - // 设置节点的父场景 - child->setParentScene(this); - // 设置 z 轴顺序 - child->setZOrder(zOrder); - // 对象的引用计数加一 - child->retain(); - - // 按 z 轴顺序插入节点 - size_t size = m_vChildren.size(); - for (unsigned i = 0; i <= size; i++) + if (m_bWillSave) { - if (i == size) - { - m_vChildren.push_back(child); - break; - } - else - { - auto temp = m_vChildren.at(i); - if (temp->getZOrder() > zOrder) - { - m_vChildren.insert(m_vChildren.begin() + i, child); - break; - } - } + //Timer::waitAllSceneTimers(m_pCurrentScene); + EMsgManager::waitAllListenersBindWithScene(this); + //ActionManager::waitAllSceneActions(m_pCurrentScene); + } + else + { + //Timer::clearAllSceneTimers(m_pCurrentScene); + EMsgManager::clearAllListenersBindWithScene(this); + //ActionManager::stopAllSceneActions(m_pCurrentScene); } } -bool e2d::EScene::del(ENode * child, bool autoRelease /* = true */) +void e2d::EScene::add(ENode * child, int order /* = 0 */) +{ + ASSERT(child != nullptr, "Scene::add NULL pointer exception."); + ASSERT(child->getParentScene() == nullptr, "Child already added. It can't be added again!"); + + if (child) + { + child->setParentScene(this); + + child->setOrder(order); + + child->retain(); + + m_vChildren.push_back(child); + + m_bSortNeeded = true; + } +} + +bool e2d::EScene::remove(ENode * child, bool autoRelease /* = true */) { if (child == nullptr) return false; @@ -84,7 +96,8 @@ bool e2d::EScene::del(ENode * child, bool autoRelease /* = true */) // 找到相同节点 if (*iter == child) { - if (autoRelease) (*iter)->autoRelease(); + if (autoRelease) + (*iter)->autoRelease(); // 对象的引用计数减一 (*iter)->release(); // 去掉该节点 @@ -101,6 +114,16 @@ std::vector& e2d::EScene::getChildren() return m_vChildren; } +size_t e2d::EScene::getChildrenCount() const +{ + return m_vChildren.size(); +} + +e2d::ENode * e2d::EScene::getChild(EString childName) const +{ + return ENode::getChild(childName, m_vChildren); +} + void e2d::EScene::clearAllChildren() { // 所有节点的引用计数减一 diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index 8873f141..7903b83a 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -23,7 +23,7 @@ {FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF} Win32Proj Easy2D - 10.0.16299.0 + 10.0.15063.0 @@ -203,6 +203,7 @@ + diff --git a/Easy2D/Easy2D.vcxproj.filters b/Easy2D/Easy2D.vcxproj.filters index 6b1a5adf..caaf10a1 100644 --- a/Easy2D/Easy2D.vcxproj.filters +++ b/Easy2D/Easy2D.vcxproj.filters @@ -63,6 +63,9 @@ Msg\Listener + + Node + diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp index 3dd71628..ffe10e75 100644 --- a/Easy2D/Node/ENode.cpp +++ b/Easy2D/Node/ENode.cpp @@ -1,12 +1,15 @@ #include "..\enodes.h" #include "..\Win\winbase.h" +#include e2d::ENode::ENode() - : m_nZOrder(0) + : m_nOrder(0) , m_bVisiable(true) , m_pParent(nullptr) , m_pParentScene(nullptr) , m_nHashName(0) + , m_bSortNeeded(false) + , m_bTransformNeeded(false) { } @@ -20,46 +23,114 @@ e2d::ENode::~ENode() { } +void e2d::ENode::callOn() +{ + if (!m_bVisiable) + { + return; + } + + this->_transfrom(); + + if (!m_vChildren.empty()) + { + this->_sortChildren(); + + size_t size = m_vChildren.size(); + size_t i; + for (i = 0; i < size; i++) + { + auto child = m_vChildren[i]; + // 访问 Order 小于零的节点 + if (child->getOrder() < 0) + { + child->callOn(); + } + else + { + break; + } + } + + // 渲染自身 + this->_onRender(); + + // 访问剩余节点 + for (; i < size; i++) + m_vChildren[i]->callOn(); + } + else + { + // 渲染自身 + this->_onRender(); + } +} + void e2d::ENode::_onRender() { - D2D1_RECT_F rectangle = D2D1::RectF( - m_Rect.left, - m_Rect.top, - m_Rect.right, - m_Rect.bottom - ); - ID2D1SolidColorBrush* m_pLightSlateGrayBrush; - GetRenderTarget()->CreateSolidColorBrush( - D2D1::ColorF(D2D1::ColorF::LightSlateGray), - &m_pLightSlateGrayBrush - ); - GetRenderTarget()->FillRectangle(&rectangle, m_pLightSlateGrayBrush); +} + +void e2d::ENode::_onTransfrom() +{ +} + +void e2d::ENode::_sortChildren() +{ + if (m_bSortNeeded) + { + // 子节点排序 + std::sort( + std::begin(m_vChildren), + std::end(m_vChildren), + [](ENode * n1, ENode * n2) { + return n1->getOrder() < n2->getOrder(); + } + ); + + m_bSortNeeded = false; + } +} + +void e2d::ENode::_transfrom() +{ + if (m_bTransformNeeded) + { + // 更新自身属性 + if (m_pParent) + { + this->setPos(m_pParent->getX() + m_Pos.x, m_pParent->getY() + m_Pos.y); + } + + // 根据子节点特殊性进行更新 + _onTransfrom(); + + // 提示子节点更新属性 + for (const auto &child : m_vChildren) + { + child->m_bTransformNeeded = true; + } + + m_bTransformNeeded = false; + } +} + +bool e2d::ENode::isVisiable() const +{ + return m_bVisiable; } int e2d::ENode::getX() const { - if (m_pParent) - { - return m_pParent->getX() + m_Rect.TopLeft().x; - } return m_Rect.TopLeft().x; } int e2d::ENode::getY() const { - if (m_pParent) - { - return m_pParent->getY() + m_Rect.TopLeft().y; - } return m_Rect.TopLeft().y; } CPoint e2d::ENode::getPos() const { - if (m_pParent) - { - return m_pParent->getPos() + m_Rect.TopLeft(); - } return m_Rect.TopLeft(); } @@ -85,22 +156,31 @@ e2d::ERect e2d::ENode::getRect() const void e2d::ENode::setX(int x) { - m_Rect.MoveToX(x); + this->setPos(x, m_Rect.TopLeft().y); } void e2d::ENode::setY(int y) { - m_Rect.MoveToY(y); -} - -void e2d::ENode::setPos(int x, int y) -{ - m_Rect.MoveToXY(x, y); + this->setPos(m_Rect.TopLeft().x, y); } void e2d::ENode::setPos(EPoint p) { - m_Rect.MoveToXY(p.x, p.y); + this->setPos(p.x, p.y); +} + +void e2d::ENode::setPos(int x, int y) +{ + if (getX() == x && getY() == y) + return; + + if (!m_bTransformNeeded) + { + m_Pos.x = x; + m_Pos.y = y; + m_bTransformNeeded = true; + } + m_Rect.MoveToXY(x, y); } void e2d::ENode::move(int x, int y) @@ -125,13 +205,13 @@ void e2d::ENode::setHeight(UINT32 height) void e2d::ENode::setSize(UINT32 width, UINT32 height) { - setWidth(width); - setHeight(height); + m_Rect.BottomRight().x = m_Rect.TopLeft().x + width; + m_Rect.BottomRight().y = m_Rect.TopLeft().y + height; } void e2d::ENode::setSize(ESize size) { - setSize(size.cx, size.cy); + this->setSize(size.cx, size.cy); } void e2d::ENode::setRect(int x1, int y1, int x2, int y2) @@ -150,40 +230,58 @@ void e2d::ENode::setRect(ERect rect) m_Rect = rect; } -int e2d::ENode::getZOrder() const +int e2d::ENode::getOrder() const { - return m_nZOrder; + return m_nOrder; } -void e2d::ENode::setZOrder(int z) +void e2d::ENode::setOrder(int order) { - m_nZOrder = z; + m_nOrder = order; } void e2d::ENode::setParent(ENode * parent) { - m_pParent = parent; + if (m_pParent) + { + m_pParent->addChild(this); + } + else + { + removeFromParent(); + } } -void e2d::ENode::addChild(ENode * child) +void e2d::ENode::addChild(ENode * child, int order /* = 0 */) { - WARN_IF(child == nullptr, "NULL ENode pointer exception."); + WARN_IF(child == nullptr, "ENode::addChild NULL pointer exception."); + ASSERT(child->m_pParent == nullptr, "Child already added. It can't be added again!"); if (child) { for (ENode * parent = this; parent != nullptr; parent = parent->getParent()) { - ASSERT(child != parent, "A ENode cannot be the child of his own children"); + ASSERT(child != parent, "A ENode cannot be the child of his own children!"); } + + m_vChildren.push_back(child); + + child->m_pParent = this; + + child->setOrder(order); + + child->retain(); + + m_bSortNeeded = true; } } -e2d::ENode *& e2d::ENode::getParent() +e2d::ENode * e2d::ENode::getParent() const { return m_pParent; } -e2d::EScene * &e2d::ENode::getParentScene() +e2d::EScene * e2d::ENode::getParentScene() const { return m_pParentScene; } @@ -193,19 +291,24 @@ std::vector& e2d::ENode::getChildren() return m_vChildren; } -int e2d::ENode::getChildrenCount() const +size_t e2d::ENode::getChildrenCount() const { return m_vChildren.size(); } -e2d::ENode * e2d::ENode::getChild(EString name) +e2d::ENode * e2d::ENode::getChild(EString name) const +{ + return ENode::getChild(name, this->m_vChildren); +} + +e2d::ENode * e2d::ENode::getChild(EString name, const std::vector &children) { WARN_IF(name.empty(), "Invalid ENode name."); std::hash h; size_t hash = h(name); - for (const auto& child : m_vChildren) + for (const auto& child : children) { // 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度 if (child->m_nHashName == hash && child->m_sName == name) @@ -216,19 +319,72 @@ e2d::ENode * e2d::ENode::getChild(EString name) void e2d::ENode::setParentScene(EScene * scene) { - m_pParentScene = scene; + if (m_pParentScene) + { + m_pParentScene = scene; + } } -void e2d::ENode::removeFromParent(bool release) +void e2d::ENode::removeFromParent(bool release /* = false */) { + if (m_pParent) + { + m_pParent->removeChild(this, release); + } } -void e2d::ENode::removeChild(ENode * child, bool release) +void e2d::ENode::removeChild(ENode * child, bool release /* = false */) { + WARN_IF(child == nullptr, "ENode::removeChild NULL pointer exception."); + + if (m_vChildren.empty()) + { + return; + } + + if (child) + { + size_t size = m_vChildren.size(); + for (size_t i = 0; i < size; i++) + { + if (m_vChildren[i] == child) + { + m_vChildren.erase(m_vChildren.begin() + i); + child->m_pParent = nullptr; + child->release(); + if (release) + child->autoRelease(); + return; + } + } + } } -void e2d::ENode::removeChild(EString childName, bool release) +void e2d::ENode::removeChild(EString childName, bool release /* = false */) { + WARN_IF(childName.empty(), "Invalid ENode name."); + + if (m_vChildren.empty()) + { + return; + } + + std::hash h; + size_t hash = h(childName); + size_t size = m_vChildren.size(); + for (size_t i = 0; i < size; i++) + { + auto child = m_vChildren[i]; + if (child->m_nHashName == hash && child->m_sName == childName) + { + m_vChildren.erase(m_vChildren.begin() + i); + child->m_pParent = nullptr; + child->release(); + if (release) + child->autoRelease(); + return; + } + } } void e2d::ENode::setVisiable(bool value) @@ -249,8 +405,3 @@ void e2d::ENode::setName(EString name) m_nHashName = h(name); } } - -bool e2d::ENode::isVisiable() const -{ - return m_bVisiable; -} \ No newline at end of file diff --git a/Easy2D/Node/ERectangle.cpp b/Easy2D/Node/ERectangle.cpp new file mode 100644 index 00000000..64239f12 --- /dev/null +++ b/Easy2D/Node/ERectangle.cpp @@ -0,0 +1,19 @@ +#include "..\enodes.h" +#include "..\Win\winbase.h" + + +void e2d::ERectangle::_onRender() +{ + static D2D1_RECT_F rectangle = D2D1::RectF( + m_Rect.left, + m_Rect.top, + m_Rect.right, + m_Rect.bottom + ); + GetRenderTarget()->FillRectangle(&rectangle, GetSolidColorBrush(D2D1::ColorF(D2D1::ColorF::LightSlateGray))); +} + +void e2d::ERectangle::_onTransfrom() +{ + +} diff --git a/Easy2D/Win/winbase.cpp b/Easy2D/Win/winbase.cpp index 56c472b9..705429a8 100644 --- a/Easy2D/Win/winbase.cpp +++ b/Easy2D/Win/winbase.cpp @@ -4,6 +4,7 @@ HWND hwnd = nullptr; ID2D1Factory * pDirect2dFactory = nullptr; ID2D1HwndRenderTarget * pRenderTarget = nullptr; +ID2D1SolidColorBrush * m_pSolidBrush = nullptr; HWND &GetHWnd() @@ -21,3 +22,9 @@ ID2D1HwndRenderTarget * &GetRenderTarget() return pRenderTarget; } +ID2D1SolidColorBrush *& GetSolidColorBrush(D2D1_COLOR_F & color) +{ + pRenderTarget->CreateSolidColorBrush(color, &m_pSolidBrush); + return m_pSolidBrush; +} + diff --git a/Easy2D/Win/winbase.h b/Easy2D/Win/winbase.h index 83642c4a..be5cfbe2 100644 --- a/Easy2D/Win/winbase.h +++ b/Easy2D/Win/winbase.h @@ -12,6 +12,8 @@ ID2D1Factory * &GetFactory(); ID2D1HwndRenderTarget * &GetRenderTarget(); +ID2D1SolidColorBrush * &GetSolidColorBrush(D2D1_COLOR_F &color); + template inline void SafeReleaseInterface( diff --git a/Easy2D/ebase.h b/Easy2D/ebase.h index 3b705674..c6526bcc 100644 --- a/Easy2D/ebase.h +++ b/Easy2D/ebase.h @@ -149,7 +149,6 @@ protected: protected: bool m_bRunning; - bool m_bSaveScene; EString m_sTitle; EString m_sAppName; EColor::Enum m_ClearColor; @@ -164,7 +163,7 @@ class EScene friend EApp; public: - EScene() = default; + EScene(); ~EScene(); @@ -181,7 +180,7 @@ public: ); // 删除子成员 - bool del( + bool remove( e2d::ENode * child, bool autoRelease = true ); @@ -189,6 +188,14 @@ public: // 获取所有子节点 std::vector &getChildren(); + // 获取子节点数量 + size_t getChildrenCount() const; + + // 根据名称获取子节点 + ENode * getChild( + EString childName + ) const; + // 清空所有子成员 void clearAllChildren(); @@ -202,7 +209,12 @@ protected: // 渲染场景画面 void _onRender(); + // 子节点排序 + void _sortChildren(); + protected: + bool m_bSortNeeded; + bool m_bWillSave; std::vector m_vChildren; }; diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h index cfc778b8..7376842e 100644 --- a/Easy2D/enodes.h +++ b/Easy2D/enodes.h @@ -7,8 +7,6 @@ namespace e2d class ENode : public EObject { - friend EScene; - public: ENode(); @@ -22,7 +20,7 @@ public: virtual bool isVisiable() const; // 获取节点绘图顺序 - virtual int getZOrder() const; + virtual int getOrder() const; // 获取节点横坐标 virtual int getX() const; @@ -46,19 +44,27 @@ public: virtual ERect getRect() const; // 获取父节点 - virtual ENode * &getParent(); + virtual ENode * getParent() const; // 获取节点所在场景 - virtual EScene * &getParentScene(); + virtual EScene * getParentScene() const; // 获取所有子节点 virtual std::vector &getChildren(); // 获取子节点数量 - virtual int getChildrenCount() const; + virtual size_t getChildrenCount() const; // 根据名字获取子节点 - virtual ENode * getChild(EString name); + virtual ENode * getChild( + EString name + ) const; + + // 根据名字获取子节点 + static ENode * getChild( + EString name, + const std::vector &children + ); // 设置节点是否显示 virtual void setVisiable( @@ -66,7 +72,9 @@ public: ); // 设置节点名称 - virtual void setName(EString name); + virtual void setName( + EString name + ); // 设置节点横坐标 virtual void setX( @@ -140,9 +148,9 @@ public: ERect rect ); - // 设置节点绘图顺序(0为最先绘制,显示在最底层) - virtual void setZOrder( - int z + // 设置节点绘图顺序 + virtual void setOrder( + int order ); // 设置节点所在场景 @@ -156,30 +164,66 @@ public: ); // 添加子节点 - virtual void addChild(ENode * child); + virtual void addChild( + ENode * child, + int order = 0 + ); // 从父节点移除 - virtual void removeFromParent(bool release = false); + virtual void removeFromParent( + bool release = false + ); // 移除子节点 - virtual void removeChild(ENode * child, bool release = false); + virtual void removeChild( + ENode * child, + bool release = false + ); // 移除子节点 - virtual void removeChild(EString childName, bool release = false); + virtual void removeChild( + EString childName, + bool release = false + ); + + // 访问节点 + virtual void callOn(); protected: // 渲染节点 virtual void _onRender(); + // 节点状态转换 + virtual void _onTransfrom(); + + // 子节点排序 + void _sortChildren(); + + // 节点状态转换 + void _transfrom(); + protected: EString m_sName; size_t m_nHashName; - int m_nZOrder; + int m_nOrder; bool m_bVisiable; + bool m_bSortNeeded; + bool m_bTransformNeeded; ERect m_Rect; + EPoint m_Pos; EScene * m_pParentScene; ENode * m_pParent; std::vector m_vChildren; }; + +class ERectangle : + public ENode +{ +protected: + virtual void _onRender() override; + + virtual void _onTransfrom() override; +}; + } \ No newline at end of file diff --git a/Easy2D/etools.h b/Easy2D/etools.h index c1559737..4e150748 100644 --- a/Easy2D/etools.h +++ b/Easy2D/etools.h @@ -27,6 +27,14 @@ private: }; +// 定时器 +class ETimer : + public EObject +{ + +}; + + // 定时器管理器 class ETimerManager {