From 7e3b224b6934fedf3568538d1c976939b886af2a Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sat, 7 Jul 2018 18:04:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=8A=82=E7=82=B9=E8=BD=AE?= =?UTF-8?q?=E5=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Common/Collider.cpp | 59 +++++-------- core/Common/Config.cpp | 11 +++ core/Common/Scene.cpp | 8 +- core/Manager/ColliderManager.cpp | 5 +- core/Node/Node.cpp | 144 ++++++++++++++----------------- core/e2dcommon.h | 21 ++--- core/e2dnode.h | 8 +- 7 files changed, 123 insertions(+), 133 deletions(-) diff --git a/core/Common/Collider.cpp b/core/Common/Collider.cpp index d542db76..ebce1fa5 100644 --- a/core/Common/Collider.cpp +++ b/core/Common/Collider.cpp @@ -4,9 +4,8 @@ e2d::Collider::Collider(Node * parent) : _visible(true) - , _color(Color::Red, 0.7) + , _color(Color::Blue, 0.7) , _parentNode(parent) - , _transformed(nullptr) , _geometry(nullptr) , _enabled(true) , _type(Collider::Type::None) @@ -16,7 +15,6 @@ e2d::Collider::Collider(Node * parent) e2d::Collider::~Collider() { - SafeRelease(_transformed); SafeRelease(_geometry); } @@ -30,11 +28,6 @@ ID2D1Geometry * e2d::Collider::getGeometry() const return _geometry; } -ID2D1TransformedGeometry * e2d::Collider::getTransformedGeometry() const -{ - return _transformed; -} - void e2d::Collider::setEnabled(bool enabled) { _enabled = enabled; @@ -52,7 +45,7 @@ void e2d::Collider::setColor(Color color) void e2d::Collider::_render() { - if (_transformed && _enabled) + if (_geometry && _enabled) { auto renderer = Renderer::getInstance(); // 获取纯色画刷 @@ -61,20 +54,19 @@ void e2d::Collider::_render() brush->SetColor(_color.toD2DColorF()); brush->SetOpacity(1.f); // 绘制几何碰撞体 - renderer->getRenderTarget()->DrawGeometry(_transformed, brush); + renderer->getRenderTarget()->DrawGeometry(_geometry, brush); } } -e2d::Collider::Relation e2d::Collider::getRelationWith(Collider * pCollider) const +e2d::Collider::Relation e2d::Collider::getRelationWith(Collider * collider) const { - if (_transformed && pCollider->_transformed) + if (_geometry && collider->_geometry) { - if (_enabled && pCollider->_enabled) + if (_enabled && collider->_enabled) { D2D1_GEOMETRY_RELATION relation; - - _transformed->CompareWithGeometry( - pCollider->_transformed, + _geometry->CompareWithGeometry( + collider->_geometry, D2D1::Matrix3x2F::Identity(), &relation ); @@ -85,14 +77,14 @@ e2d::Collider::Relation e2d::Collider::getRelationWith(Collider * pCollider) con return Relation::Unknown; } -void e2d::Collider::_recreate(Collider::Type type) +void e2d::Collider::_recreate() { - _type = type; - SafeRelease(_geometry); - SafeRelease(_transformed); - switch (type) + if (_type == Type::None) + return; + + switch (_type) { case Type::Rect: { @@ -147,23 +139,14 @@ void e2d::Collider::_recreate(Collider::Type type) _geometry = ellipse; } break; - - default: - break; } -} -void e2d::Collider::_transform() -{ - if (_enabled && _type != Type::None) - { - // 重新生成碰撞体 - _recreate(_type); - // 二维变换 - Renderer::getFactory()->CreateTransformedGeometry( - _geometry, - _parentNode->_finalMatri, - &_transformed - ); - } + ID2D1TransformedGeometry * _transformed; + Renderer::getFactory()->CreateTransformedGeometry( + _geometry, + _parentNode->_finalMatri, + &_transformed + ); + SafeRelease(_geometry); + _geometry = _transformed; } diff --git a/core/Common/Config.cpp b/core/Common/Config.cpp index 9033edf2..78da7fd3 100644 --- a/core/Common/Config.cpp +++ b/core/Common/Config.cpp @@ -5,6 +5,7 @@ e2d::Config::Config() : _gameName() , _nodeDefPivot() , _soundEnabled(true) + , _outlineVisible(false) , _collisionEnabled(false) , _colliderVisible(false) , _nodeDefColliderType(Collider::Type::None) @@ -21,6 +22,11 @@ void e2d::Config::setGameName(const String & name) _gameName = name; } +void e2d::Config::setOutlineVisible(bool visible) +{ + _outlineVisible = visible; +} + void e2d::Config::setSoundEnabled(bool enabled) { if (_soundEnabled != enabled) @@ -63,6 +69,11 @@ bool e2d::Config::isSoundEnabled() const return _soundEnabled; } +bool e2d::Config::isOutlineVisible() const +{ + return _outlineVisible; +} + bool e2d::Config::isCollisionEnabled() const { return _collisionEnabled; diff --git a/core/Common/Scene.cpp b/core/Common/Scene.cpp index 67b46a78..7fd4ff07 100644 --- a/core/Common/Scene.cpp +++ b/core/Common/Scene.cpp @@ -20,11 +20,15 @@ void e2d::Scene::_render() { _root->_render(); + if (Game::getInstance()->getConfig()->isOutlineVisible()) + { + Renderer::getInstance()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + _root->_renderOutline(); + } + if (Game::getInstance()->getConfig()->isColliderVisible()) { - // 恢复矩阵转换 Renderer::getInstance()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); - // 绘制所有几何图形 _root->_renderCollider(); } } diff --git a/core/Manager/ColliderManager.cpp b/core/Manager/ColliderManager.cpp index 5a71a6f7..deb15476 100644 --- a/core/Manager/ColliderManager.cpp +++ b/core/Manager/ColliderManager.cpp @@ -47,7 +47,7 @@ void e2d::ColliderManager::updateCollider(Node * node) { if (node->getCollider()->_type != Collider::Type::None) { - node->getCollider()->_transform(); + node->getCollider()->_recreate(); _nodes.insert(node); } } @@ -79,7 +79,8 @@ void e2d::ColliderManager::update() // 判断两碰撞体交集情况 Collider::Relation relation = node1->getCollider()->getRelationWith(node2->getCollider()); // 忽略 UNKNOWN 和 DISJOIN 情况 - if (relation != Collider::Relation::Unknown && relation != Collider::Relation::Disjoin) + if (relation != Collider::Relation::Unknown && + relation != Collider::Relation::Disjoin) { // 更新碰撞监听器 Collision::__update(node1, node2); diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 0eb4ce90..6c0dc243 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -22,7 +22,6 @@ e2d::Node::Node() , _initialMatri(D2D1::Matrix3x2F::Identity()) , _finalMatri(D2D1::Matrix3x2F::Identity()) , _visible(true) - , _collider(this) , _parent(nullptr) , _parentScene(nullptr) , _hashName(0) @@ -30,6 +29,8 @@ e2d::Node::Node() , _needTransform(false) , _autoUpdate(true) , _positionFixed(false) + , _outline(nullptr) + , _collider(this) { // 设置默认中心点位置 Point defPivot = Game::getInstance()->getConfig()->getNodeDefaultPivot(); @@ -39,6 +40,8 @@ e2d::Node::Node() e2d::Node::~Node() { + SafeRelease(_outline); + ActionManager::getInstance()->clearAllBindedWith(this); ColliderManager::getInstance()->__remove(this); for (auto child : _children) @@ -143,6 +146,27 @@ void e2d::Node::_render() } } +void e2d::Node::_renderOutline() +{ + if (_outline) + { + auto renderer = Renderer::getInstance(); + // 获取纯色画刷 + ID2D1SolidColorBrush * brush = renderer->getSolidColorBrush(); + // 设置画刷颜色和透明度 + brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.7f)); + brush->SetOpacity(1.f); + // 渲染轮廓 + renderer->getRenderTarget()->DrawGeometry(_outline, brush); + } + + // 渲染所有子节点的轮廓 + for (auto child : _children) + { + child->_renderOutline(); + } +} + void e2d::Node::_renderCollider() { // 绘制自身的几何碰撞体 @@ -190,6 +214,25 @@ void e2d::Node::_updateTransform() _finalMatri = _finalMatri * _parent->_initialMatri; } + // 为节点创建一个轮廓 + ID2D1RectangleGeometry * rectGeo; + ID2D1TransformedGeometry * transformedGeo; + + auto factory = Renderer::getFactory(); + factory->CreateRectangleGeometry( + D2D1::RectF(0, 0, _width, _height), + &rectGeo + ); + factory->CreateTransformedGeometry( + rectGeo, + _finalMatri, + &transformedGeo + ); + + SafeRelease(rectGeo); + SafeRelease(_outline); + _outline = transformedGeo; + // 更新碰撞体 ColliderManager::getInstance()->updateCollider(this); // 标志已执行过变换 @@ -541,7 +584,7 @@ void e2d::Node::setColliderType(Collider::Type type) { if (_collider._type != type) { - _collider._recreate(type); + _collider._type = type; _needTransform = true; } } @@ -760,101 +803,44 @@ void e2d::Node::stopAction(const String& name) } } -bool e2d::Node::containsPoint(const Point& point) const +bool e2d::Node::containsPoint(const Point& point) { - BOOL ret = 0; - // 如果存在碰撞体,用碰撞体判断 - if (_collider.getGeometry()) + _updateTransform(); + if (_outline) { - _collider.getGeometry()->FillContainsPoint( - D2D1::Point2F( - float(point.x), - float(point.y)), - _finalMatri, + BOOL ret = 0; + _outline->FillContainsPoint( + D2D1::Point2F(float(point.x), float(point.y)), + D2D1::Matrix3x2F::Identity(), &ret ); - } - else - { - // 为节点创建一个临时碰撞体 - ID2D1RectangleGeometry * rect; - Renderer::getFactory()->CreateRectangleGeometry( - D2D1::RectF(0, 0, _width, _height), - &rect - ); - // 判断点是否在碰撞体内 - rect->FillContainsPoint( - D2D1::Point2F( - float(point.x), - float(point.y)), - _finalMatri, - &ret - ); - // 删除临时创建的碰撞体 - SafeRelease(rect); - } - - if (ret) - { - return true; - } - - return false; -} - -bool e2d::Node::intersects(Node * node) const -{ - // 如果存在碰撞体,用碰撞体判断 - if (this->_collider.getGeometry() && node->_collider.getGeometry()) - { - Collider::Relation relation = this->_collider.getRelationWith(&node->_collider); - if ((relation != Collider::Relation::Unknown) && - (relation != Collider::Relation::Disjoin)) + if (ret) { return true; } } - else - { - // 为节点创建一个临时碰撞体 - ID2D1RectangleGeometry * pRect1; - ID2D1RectangleGeometry * pRect2; - ID2D1TransformedGeometry * pCollider; - D2D1_GEOMETRY_RELATION relation; + return false; +} - // 根据自身大小位置创建矩形 - Renderer::getFactory()->CreateRectangleGeometry( - D2D1::RectF(0, 0, _width, _height), - &pRect1 - ); - // 根据二维矩阵进行转换 - Renderer::getFactory()->CreateTransformedGeometry( - pRect1, - _finalMatri, - &pCollider - ); - // 根据相比较节点的大小位置创建矩形 - Renderer::getFactory()->CreateRectangleGeometry( - D2D1::RectF(0, 0, node->_width, node->_height), - &pRect2 - ); +bool e2d::Node::intersects(Node * node) +{ + _updateTransform(); + node->_updateTransform(); + if (_outline) + { + D2D1_GEOMETRY_RELATION relation; // 获取相交状态 - pCollider->CompareWithGeometry( - pRect2, - node->_finalMatri, + _outline->CompareWithGeometry( + node->_outline, + D2D1::Matrix3x2F::Identity(), &relation ); - // 删除临时创建的碰撞体 - SafeRelease(pRect1); - SafeRelease(pRect2); - SafeRelease(pCollider); if ((relation != D2D1_GEOMETRY_RELATION_UNKNOWN) && (relation != D2D1_GEOMETRY_RELATION_DISJOINT)) { return true; } } - return false; } diff --git a/core/e2dcommon.h b/core/e2dcommon.h index bce6cab2..d6aa2603 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -496,9 +496,6 @@ public: // 获取 ID2D1Geometry* 对象 ID2D1Geometry* getGeometry() const; - // 获取 ID2D1TransformedGeometry* 对象 - ID2D1TransformedGeometry* getTransformedGeometry() const; - protected: Collider( Node * parent @@ -509,12 +506,7 @@ protected: E2D_DISABLE_COPY(Collider); // 重新生成 - void _recreate( - Collider::Type type - ); - - // 二维变换 - void _transform(); + void _recreate(); // 渲染碰撞体 void _render(); @@ -526,7 +518,6 @@ protected: Node * _parentNode; Type _type; ID2D1Geometry* _geometry; - ID2D1TransformedGeometry* _transformed; }; @@ -757,6 +748,12 @@ public: const String& name ); + // 显示或隐藏节点轮廓 + // 默认:隐藏 + void setOutlineVisible( + bool visible + ); + // 打开或关闭声音 // 默认:打开 void setSoundEnabled( @@ -793,6 +790,9 @@ public: // 获取声音打开状态 bool isSoundEnabled() const; + // 获取节点轮廓显示状态 + bool isOutlineVisible() const; + // 获取碰撞监听状态 bool isCollisionEnabled() const; @@ -811,6 +811,7 @@ protected: protected: bool _unconfigured; bool _soundEnabled; + bool _outlineVisible; bool _collisionEnabled; bool _colliderVisible; String _gameName; diff --git a/core/e2dnode.h b/core/e2dnode.h index ab99ee4a..40a34a99 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -51,12 +51,12 @@ public: // 判断点是否在节点内 virtual bool containsPoint( const Point& point - ) const; + ); // 判断两物体是否相交 virtual bool intersects( Node * node - ) const; + ); // 获取节点名称 virtual String getName() const; @@ -386,6 +386,9 @@ protected: // 渲染节点 void _render(); + // 渲染节点轮廓 + void _renderOutline(); + // 渲染碰撞体轮廓 void _renderCollider(); @@ -431,6 +434,7 @@ protected: Collider _collider; Scene * _parentScene; Node * _parent; + ID2D1Geometry* _outline; D2D1::Matrix3x2F _initialMatri; D2D1::Matrix3x2F _finalMatri; std::vector _children;