From db64bf8e8dd272560c505a7ec5a51a9338da3bed Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sun, 29 Oct 2017 23:48:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A2=B0=E6=92=9E=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E7=9B=91=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Easy2D/Base/EApp.cpp | 4 +- Easy2D/Base/EScene.cpp | 19 +++++++++- Easy2D/Easy2D.vcxproj | 2 +- Easy2D/Geometry/ECircle.cpp | 20 +++++++++- Easy2D/Geometry/EEllipse.cpp | 20 +++++++++- Easy2D/Geometry/EGeometry.cpp | 61 +++++++++++++++++++++++++----- Easy2D/Geometry/ERectangle.cpp | 20 +++++----- Easy2D/Manager/EPhysicsManager.cpp | 60 +++++++++++++++++------------ Easy2D/Node/ENode.cpp | 44 +++++++++++++++------ Easy2D/ebase.h | 6 +++ Easy2D/egeometry.h | 45 ++++++++++++++++++++-- Easy2D/emanagers.h | 5 +++ Easy2D/enodes.h | 3 ++ 13 files changed, 244 insertions(+), 65 deletions(-) diff --git a/Easy2D/Base/EApp.cpp b/Easy2D/Base/EApp.cpp index 8b16f58d..3d0ea9d9 100644 --- a/Easy2D/Base/EApp.cpp +++ b/Easy2D/Base/EApp.cpp @@ -346,10 +346,10 @@ void e2d::EApp::_onControl() // 断言当前场景非空 ASSERT(m_pCurrentScene != nullptr, "Current scene NULL pointer exception."); + EObjectManager::__flush(); // 刷新内存池 ETimerManager::TimerProc(); // 定时器管理器执行程序 EActionManager::ActionProc(); // 动作管理器执行程序 EPhysicsManager::PhysicsProc(); // 物理引擎执行程序 - EObjectManager::__flush(); // 刷新内存池 } // This method discards device-specific @@ -391,7 +391,7 @@ void e2d::EApp::_onRender() if (FAILED(hr)) { - MessageBox(GetHWnd(), L"Game Render Failed!", L"Error", MB_OK); + MessageBox(GetHWnd(), L"Game rendering failed!", L"Error", MB_OK); this->quit(); } } diff --git a/Easy2D/Base/EScene.cpp b/Easy2D/Base/EScene.cpp index 0dd21ab8..944dd717 100644 --- a/Easy2D/Base/EScene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -3,11 +3,13 @@ #include "..\emanagers.h" #include "..\etools.h" #include "..\eactions.h" +#include "..\Win\winbase.h" #include e2d::EScene::EScene() : m_bWillSave(true) , m_bSortNeeded(false) + , m_bGeometryVisiable(false) , m_pRoot(new ENode()) { m_pRoot->_onEnter(); @@ -46,7 +48,17 @@ bool e2d::EScene::onCloseWindow() void e2d::EScene::_onRender() { + // 访问根节点 m_pRoot->_callOn(); + + // 恢复矩阵转换 + GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + + // 绘制所有几何图形 + if (m_bGeometryVisiable) + { + m_pRoot->_drawGeometry(); + } } void e2d::EScene::add(ENode * child, int order /* = 0 */) @@ -92,4 +104,9 @@ void e2d::EScene::clearAllChildren() void e2d::EScene::runAction(EAction * action) { this->m_pRoot->runAction(action); -} \ No newline at end of file +} + +void e2d::EScene::setGeometryVisiable(bool visiable) +{ + m_bGeometryVisiable = visiable; +} diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index becac503..e0e75cb5 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -101,7 +101,7 @@ Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - EditAndContinue + None false diff --git a/Easy2D/Geometry/ECircle.cpp b/Easy2D/Geometry/ECircle.cpp index 7b82b345..15ea3ad4 100644 --- a/Easy2D/Geometry/ECircle.cpp +++ b/Easy2D/Geometry/ECircle.cpp @@ -1,10 +1,10 @@ #include "..\egeometry.h" +#include "..\enodes.h" #include "..\Win\winbase.h" e2d::ECircle::ECircle() : m_pD2dCircle(nullptr) { - this->_setCircle(EPoint(), 0); } e2d::ECircle::ECircle(EPoint center, float radius) @@ -13,6 +13,24 @@ e2d::ECircle::ECircle(EPoint center, float radius) this->_setCircle(center, radius); } +e2d::ECircle::ECircle(ENode * node) + : ECircle() +{ + float minSide = min(node->getRealWidth(), node->getRealHeight()); + this->_setCircle( + EPoint( + node->getRealWidth() / 2, + node->getRealHeight() / 2 + ), + minSide / 2 + ); +} + +e2d::ECircle::~ECircle() +{ + SafeReleaseInterface(&m_pD2dCircle); +} + void e2d::ECircle::_setCircle(EPoint center, float radius) { SafeReleaseInterface(&m_pD2dCircle); diff --git a/Easy2D/Geometry/EEllipse.cpp b/Easy2D/Geometry/EEllipse.cpp index 03cd7fd4..feb3e740 100644 --- a/Easy2D/Geometry/EEllipse.cpp +++ b/Easy2D/Geometry/EEllipse.cpp @@ -1,10 +1,10 @@ #include "..\egeometry.h" +#include "..\enodes.h" #include "..\Win\winbase.h" e2d::EEllipse::EEllipse() : m_pD2dEllipse(nullptr) { - this->_setEllipse(EPoint(), 0, 0); } e2d::EEllipse::EEllipse(EPoint center, float radiusX, float radiusY) @@ -13,6 +13,24 @@ e2d::EEllipse::EEllipse(EPoint center, float radiusX, float radiusY) this->_setEllipse(center, radiusX, radiusY); } +e2d::EEllipse::EEllipse(ENode * node) + : EEllipse() +{ + this->_setEllipse( + EPoint( + node->getWidth() / 2, + node->getHeight() / 2 + ), + node->getWidth() / 2, + node->getHeight() / 2 + ); +} + +e2d::EEllipse::~EEllipse() +{ + SafeReleaseInterface(&m_pD2dEllipse); +} + void e2d::EEllipse::_setEllipse(EPoint center, float radiusX, float radiusY) { SafeReleaseInterface(&m_pD2dEllipse); diff --git a/Easy2D/Geometry/EGeometry.cpp b/Easy2D/Geometry/EGeometry.cpp index 867b018e..d1f60c36 100644 --- a/Easy2D/Geometry/EGeometry.cpp +++ b/Easy2D/Geometry/EGeometry.cpp @@ -3,10 +3,18 @@ #include "..\enodes.h" e2d::EGeometry::EGeometry() - : m_bTransformNeeded(true) + : m_bTransformed(false) + , m_nColor(EColor::RED) + , m_fOpacity(1) , m_pParentNode(nullptr) , m_pTransformedGeometry(nullptr) { + this->autoRelease(); +} + +e2d::EGeometry::~EGeometry() +{ + SafeReleaseInterface(&m_pTransformedGeometry); } e2d::ENode * e2d::EGeometry::getParentNode() const @@ -14,22 +22,54 @@ e2d::ENode * e2d::EGeometry::getParentNode() const return m_pParentNode; } +void e2d::EGeometry::setColor(UINT32 color) +{ + m_nColor = color; +} + +void e2d::EGeometry::setOpacity(float opacity) +{ + m_fOpacity = opacity; +} + +void e2d::EGeometry::_onRender() +{ + if (m_pTransformedGeometry) + { + // 创建画刷 + GetRenderTarget()->CreateSolidColorBrush( + D2D1::ColorF( + m_nColor, + m_fOpacity), + &GetSolidColorBrush() + ); + // 绘制几何形状 + GetRenderTarget()->DrawGeometry(m_pTransformedGeometry, GetSolidColorBrush()); + // 释放临时资源 + SafeReleaseInterface(&GetSolidColorBrush()); + } +} + e2d::EPhysicsMsg::INTERSECT_RELATION e2d::EGeometry::_intersectWith(EGeometry * pGeometry) { - D2D1_GEOMETRY_RELATION relation; + if (m_pTransformedGeometry && pGeometry->m_pTransformedGeometry) + { + D2D1_GEOMETRY_RELATION relation; - m_pTransformedGeometry->CompareWithGeometry( - pGeometry->m_pTransformedGeometry, - D2D1::Matrix3x2F::Identity(), - &relation - ); + m_pTransformedGeometry->CompareWithGeometry( + pGeometry->m_pTransformedGeometry, + D2D1::Matrix3x2F::Identity(), + &relation + ); - return EPhysicsMsg::INTERSECT_RELATION(relation); + return EPhysicsMsg::INTERSECT_RELATION(relation); + } + return EPhysicsMsg::INTERSECT_RELATION::UNKNOWN; } void e2d::EGeometry::_transform() { - if (m_bTransformNeeded && m_pParentNode) + if (m_pParentNode) { SafeReleaseInterface(&m_pTransformedGeometry); @@ -38,6 +78,7 @@ void e2d::EGeometry::_transform() m_pParentNode->m_Matri, &m_pTransformedGeometry ); + + this->m_bTransformed = true; } - m_bTransformNeeded = false; } diff --git a/Easy2D/Geometry/ERectangle.cpp b/Easy2D/Geometry/ERectangle.cpp index 4d269ee2..b8152447 100644 --- a/Easy2D/Geometry/ERectangle.cpp +++ b/Easy2D/Geometry/ERectangle.cpp @@ -5,7 +5,6 @@ e2d::ERectangle::ERectangle() : m_pD2dRectangle(nullptr) { - this->_setRect(0, 0, 0, 0); } e2d::ERectangle::ERectangle(float x, float y, float width, float height) @@ -15,20 +14,21 @@ e2d::ERectangle::ERectangle(float x, float y, float width, float height) } e2d::ERectangle::ERectangle(ENode * node) + : ERectangle() { - // 计算左上角坐标 - D2D1_POINT_2F upperLeftCorner = D2D1::Point2F( - node->getRealWidth() * node->getAnchorX(), - node->getRealHeight() * node->getAnchorY() - ); this->_setRect( - upperLeftCorner.x, - upperLeftCorner.y, - upperLeftCorner.x + node->getRealWidth(), - upperLeftCorner.y + node->getRealHeight() + 0, + 0, + node->getRealWidth(), + node->getRealHeight() ); } +e2d::ERectangle::~ERectangle() +{ + SafeReleaseInterface(&m_pD2dRectangle); +} + void e2d::ERectangle::_setRect(float left, float top, float right, float bottom) { SafeReleaseInterface(&m_pD2dRectangle); diff --git a/Easy2D/Manager/EPhysicsManager.cpp b/Easy2D/Manager/EPhysicsManager.cpp index 7d09e2f1..98eb7c84 100644 --- a/Easy2D/Manager/EPhysicsManager.cpp +++ b/Easy2D/Manager/EPhysicsManager.cpp @@ -14,32 +14,46 @@ void e2d::EPhysicsManager::PhysicsProc() if (s_vListeners.empty() || s_vGeometries.empty() || EApp::isPaused()) return; - // 判断任意两形状间的交集 - for (auto &g1 : s_vGeometries) + for (auto &geometry : s_vGeometries) { + if (!geometry->getParentNode() || + (geometry->getParentNode()->getParentScene() != EApp::getCurrentScene())) + continue; + // 只对进行了变化了对象进行判断 - if (g1->m_bTransformNeeded) + if (geometry->m_bTransformed) { - // 变化对象 - g1->_transform(); - // g1 为主动方 - EPhysicsMsg::s_pActiveGeometry = g1; - // 判断变化后的状态 - for (auto &g2 : s_vGeometries) + // 判断变化后的图形情况 + PhysicsGeometryProc(geometry); + // 取消变化标志 + geometry->m_bTransformed = false; + } + } +} + +void e2d::EPhysicsManager::PhysicsGeometryProc(EGeometry * pActiveGeometry) +{ + // pActiveGeometry 为主动方 + EPhysicsMsg::s_pActiveGeometry = pActiveGeometry; + // 判断变化后的状态 + for (auto &pPassiveGeometry : s_vGeometries) + { + if (!pPassiveGeometry->getParentNode() || + (pPassiveGeometry->getParentNode()->getParentScene() != EApp::getCurrentScene())) + continue; + + if (pActiveGeometry != pPassiveGeometry) + { + // pPassiveGeometry 为被动方 + EPhysicsMsg::s_pPassiveGeometry = pPassiveGeometry; + // 获取两方的关系 + EPhysicsMsg::s_nRelation = pActiveGeometry->_intersectWith(pPassiveGeometry); + // 如果关系不为未知或无交集,响应监听器 + if (EPhysicsMsg::s_nRelation != EPhysicsMsg::UNKNOWN && + EPhysicsMsg::s_nRelation != EPhysicsMsg::DISJOINT) { - if (g1 != g2) - { - // g2 为被动方 - EPhysicsMsg::s_pPassiveGeometry = g2; - // 获取两方的关系 - EPhysicsMsg::s_nRelation = g1->_intersectWith(g2); - // 如果关系不为未知或无交集,响应监听器 - if (EPhysicsMsg::s_nRelation != EPhysicsMsg::UNKNOWN && - EPhysicsMsg::s_nRelation != EPhysicsMsg::DISJOINT) - { - PhysicsListenerProc(); - } - } + // 执行监听器 + PhysicsListenerProc(); } } } @@ -47,8 +61,6 @@ void e2d::EPhysicsManager::PhysicsProc() void e2d::EPhysicsManager::PhysicsListenerProc() { - if (s_vListeners.empty()) return; - // 执行鼠标消息监听函数 for (size_t i = 0; i < s_vListeners.size(); i++) { diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp index 95bade46..0d5ee9f3 100644 --- a/Easy2D/Node/ENode.cpp +++ b/Easy2D/Node/ENode.cpp @@ -109,6 +109,21 @@ void e2d::ENode::_onRender() { } +void e2d::ENode::_drawGeometry() +{ + // 绘制自身的几何形状 + if (m_pGeometry) + { + m_pGeometry->_onRender(); + } + + // 绘制所有子节点的几何形状 + for (auto &child : m_vChildren) + { + child->_drawGeometry(); + } +} + void e2d::ENode::_onEnter() { if (!this->m_bDisplayedInScene && this->isVisiable()) @@ -201,13 +216,19 @@ void e2d::ENode::_updateTransform(ENode * node) { node->m_Matri = node->m_Matri * node->m_pParent->m_Matri; } + // 转换几何形状 + if (node->m_pGeometry) + { + node->m_pGeometry->_transform(); + } // 遍历子节点下的所有节点 node->_updateChildrenTransform(); + // 标志已执行过变换 node->m_bTransformChildrenNeeded = false; // 绑定于自身的形状也进行相应转换 if (node->m_pGeometry) { - node->m_pGeometry->m_bTransformNeeded = true; + node->m_pGeometry->m_bTransformed = true; } } @@ -480,18 +501,19 @@ void e2d::ENode::setAnchor(float anchorX, float anchorY) void e2d::ENode::setGeometry(EGeometry * geometry) { // 删除旧的形状 - if (m_pGeometry) - { - EPhysicsManager::delGeometry(m_pGeometry); - } - // 双向绑定 - this->m_pGeometry = geometry; - if (geometry) geometry->m_pParentNode = this; - + EPhysicsManager::delGeometry(m_pGeometry); + // 添加新的形状 + EPhysicsManager::addGeometry(geometry); + if (geometry) { - m_pGeometry->_transform(); - EPhysicsManager::addGeometry(geometry); + // 双向绑定 + this->m_pGeometry = geometry; + geometry->m_pParentNode = this; + } + else + { + this->m_pGeometry = nullptr; } } diff --git a/Easy2D/ebase.h b/Easy2D/ebase.h index cbed4175..01c5a0ab 100644 --- a/Easy2D/ebase.h +++ b/Easy2D/ebase.h @@ -298,6 +298,11 @@ public: EAction * action ); + // 开启几何图形的渲染 + void setGeometryVisiable( + bool visiable + ); + protected: // 渲染场景画面 void _onRender(); @@ -305,6 +310,7 @@ protected: protected: bool m_bSortNeeded; bool m_bWillSave; + bool m_bGeometryVisiable; ENode * m_pRoot; }; diff --git a/Easy2D/egeometry.h b/Easy2D/egeometry.h index b9fed834..5c85240c 100644 --- a/Easy2D/egeometry.h +++ b/Easy2D/egeometry.h @@ -47,9 +47,21 @@ class EGeometry : public: EGeometry(); + virtual ~EGeometry(); + // 获取父节点 ENode * getParentNode() const; + // 设置绘制颜色 + void setColor( + UINT32 color + ); + + // 设置绘制透明度 + void setOpacity( + float opacity + ); + protected: // 判断两形状的交集关系 virtual EPhysicsMsg::INTERSECT_RELATION _intersectWith( @@ -59,10 +71,15 @@ protected: // 转换形状 virtual void _transform(); + // 渲染几何图形 + virtual void _onRender(); + virtual ID2D1Geometry * _getD2dGeometry() const = 0; protected: - bool m_bTransformNeeded; + bool m_bTransformed; + UINT32 m_nColor; + float m_fOpacity; ENode * m_pParentNode; ID2D1TransformedGeometry * m_pTransformedGeometry; }; @@ -72,10 +89,10 @@ class ERectangle : public EGeometry { public: - // 创建一个空矩形 + // 创建一个空几何矩形 ERectangle(); - // 根据左上角坐标和宽高创建矩形 + // 根据左上角坐标和宽高创建几何矩形 ERectangle( float x, float y, @@ -83,11 +100,13 @@ public: float height ); - // 创建一个和节点位置大小相同的矩形 + // 创建一个和节点位置大小相同的几何矩形 ERectangle( ENode * node ); + virtual ~ERectangle(); + protected: void _setRect( float left, @@ -107,13 +126,22 @@ class ECircle : public EGeometry { public: + // 创建一个空的几何圆形 ECircle(); + // 根据圆心和半径创建几何圆形 ECircle( EPoint center, float radius ); + // 创建一个和节点位置大小相同的几何圆形 + ECircle( + ENode * node + ); + + virtual ~ECircle(); + protected: void _setCircle( EPoint center, @@ -131,14 +159,23 @@ class EEllipse : public EGeometry { public: + // 创建一个空的几何椭圆 EEllipse(); + // 根据圆心和半径创建几何椭圆 EEllipse( EPoint center, float radiusX, float radiusY ); + // 创建一个和节点位置大小相同的几何椭圆 + EEllipse( + ENode * node + ); + + virtual ~EEllipse(); + protected: void _setEllipse( EPoint center, diff --git a/Easy2D/emanagers.h b/Easy2D/emanagers.h index 67966c91..ece88ea3 100644 --- a/Easy2D/emanagers.h +++ b/Easy2D/emanagers.h @@ -398,6 +398,11 @@ private: // 物理引擎执行程序 static void PhysicsProc(); + // 几何图形判断程序 + static void PhysicsGeometryProc( + EGeometry * pActiveGeometry + ); + // 物理碰撞监听器执行程序 static void PhysicsListenerProc(); }; diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h index 2adb80ba..7deb5a6d 100644 --- a/Easy2D/enodes.h +++ b/Easy2D/enodes.h @@ -306,6 +306,9 @@ protected: // 渲染节点 virtual void _onRender(); + // 渲染几何图形 + virtual void _drawGeometry(); + // 节点被添加到场景时的执行程序 virtual void _onEnter();