diff --git a/core/Collider/CircleCollider.cpp b/core/Collider/CircleCollider.cpp deleted file mode 100644 index 1fc16e05..00000000 --- a/core/Collider/CircleCollider.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "..\e2dcollider.h" -#include "..\e2dnode.h" - -e2d::CircleCollider::CircleCollider() -{ -} - -e2d::CircleCollider::CircleCollider(Point center, double radius) -{ - this->setCircle(center, radius); -} - -e2d::CircleCollider::CircleCollider(Node * node) -{ - double minSide = std::min(node->getRealWidth(), node->getRealHeight()); - this->setCircle( - Point( - node->getRealWidth() / 2, - node->getRealHeight() / 2 - ), - minSide / 2 - ); - this->setAutoResize(true); -} - -e2d::CircleCollider::~CircleCollider() -{ -} - -void e2d::CircleCollider::setCircle(Point center, double radius) -{ - SafeRelease(_geometry); - - ID2D1EllipseGeometry* circle = nullptr; - Renderer::getFactory()->CreateEllipseGeometry( - D2D1::Ellipse( - D2D1::Point2F( - float(center.x), - float(center.y) - ), - float(radius), - float(radius) - ), - &circle - ); - - _geometry = circle; -} - -void e2d::CircleCollider::_resize() -{ - if (_parentNode && _enabled) - { - double minSide = std::min(_parentNode->getRealWidth(), _parentNode->getRealHeight()); - this->setCircle( - Point( - _parentNode->getRealWidth() / 2, - _parentNode->getRealHeight() / 2 - ), - minSide / 2 - ); - } -} diff --git a/core/Collider/EllipseCollider.cpp b/core/Collider/EllipseCollider.cpp deleted file mode 100644 index f5cdc100..00000000 --- a/core/Collider/EllipseCollider.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "..\e2dcollider.h" -#include "..\e2dnode.h" - -e2d::EllipseCollider::EllipseCollider() -{ -} - -e2d::EllipseCollider::EllipseCollider(Point center, double radiusX, double radiusY) -{ - this->setEllipse(center, radiusX, radiusY); -} - -e2d::EllipseCollider::EllipseCollider(Node * node) -{ - this->setEllipse( - Point( - node->getWidth() / 2, - node->getHeight() / 2 - ), - node->getWidth() / 2, - node->getHeight() / 2 - ); - this->setAutoResize(true); -} - -e2d::EllipseCollider::~EllipseCollider() -{ -} - -void e2d::EllipseCollider::setEllipse(Point center, double radiusX, double radiusY) -{ - SafeRelease(_geometry); - - ID2D1EllipseGeometry* ellipse = nullptr; - Renderer::getFactory()->CreateEllipseGeometry( - D2D1::Ellipse( - D2D1::Point2F( - float(center.x), - float(center.y)), - float(radiusX), - float(radiusY)), - &ellipse - ); - _geometry = ellipse; -} - -void e2d::EllipseCollider::_resize() -{ - if (_parentNode && _enabled) - { - this->setEllipse( - Point( - _parentNode->getWidth() / 2, - _parentNode->getHeight() / 2 - ), - _parentNode->getWidth() / 2, - _parentNode->getHeight() / 2 - ); - } -} diff --git a/core/Collider/RectCollider.cpp b/core/Collider/RectCollider.cpp deleted file mode 100644 index 6709f3c4..00000000 --- a/core/Collider/RectCollider.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "..\e2dcollider.h" -#include "..\e2dnode.h" - -e2d::RectCollider::RectCollider() -{ -} - -e2d::RectCollider::RectCollider(double x, double y, double width, double height) -{ - this->setRect(x, y, x + width, y + height); -} - -e2d::RectCollider::RectCollider(Node * node) -{ - this->setRect(0, 0, node->getRealWidth(), node->getRealHeight()); - this->setAutoResize(true); -} - -e2d::RectCollider::~RectCollider() -{ -} - -void e2d::RectCollider::setRect(double left, double top, double right, double bottom) -{ - SafeRelease(_geometry); - - ID2D1RectangleGeometry* rectangle = nullptr; - Renderer::getFactory()->CreateRectangleGeometry( - D2D1::RectF( - float(left), - float(top), - float(right), - float(bottom)), - &rectangle - ); - - _geometry = rectangle; -} - -void e2d::RectCollider::_resize() -{ - if (_parentNode && _enabled) - { - this->setRect(0, 0, _parentNode->getRealWidth(), _parentNode->getRealHeight()); - } -} diff --git a/core/Collider/Collider.cpp b/core/Common/Collider.cpp similarity index 51% rename from core/Collider/Collider.cpp rename to core/Common/Collider.cpp index 21b3cfc2..ef989b7d 100644 --- a/core/Collider/Collider.cpp +++ b/core/Common/Collider.cpp @@ -9,7 +9,7 @@ e2d::Collider::Collider() , _transformed(nullptr) , _geometry(nullptr) , _enabled(true) - , _autoResize(false) + , _type(Collider::Type::None) { } @@ -29,6 +29,16 @@ e2d::Color e2d::Collider::getColor() const return _color; } +ID2D1Geometry * e2d::Collider::getGeometry() const +{ + return _geometry; +} + +ID2D1TransformedGeometry * e2d::Collider::getTransformedGeometry() const +{ + return _transformed; +} + void e2d::Collider::setEnabled(bool enabled) { _enabled = enabled; @@ -44,11 +54,6 @@ void e2d::Collider::setColor(Color color) _color = color; } -void e2d::Collider::setAutoResize(bool enabled) -{ - _autoResize = enabled; -} - void e2d::Collider::_render() { if (_transformed && _enabled) @@ -83,29 +88,90 @@ e2d::Collider::Relation e2d::Collider::getRelationWith(Collider * pCollider) con return Relation::Unknown; } -void e2d::Collider::_transform() +void e2d::Collider::_recreate(Collider::Type type) { - if (_parentNode && _enabled && _geometry) - { - if (_autoResize) - { - this->_resize(); - } + _type = type; - // 释放原碰撞体 + if (_parentNode) + { + SafeRelease(_geometry); SafeRelease(_transformed); - // 根据父节点转换几何图形 + switch (type) + { + case Type::Rect: + { + ID2D1RectangleGeometry* rectangle = nullptr; + Renderer::getFactory()->CreateRectangleGeometry( + D2D1::RectF( + 0, + 0, + float(_parentNode->getRealWidth()), + float(_parentNode->getRealHeight())), + &rectangle + ); + _geometry = rectangle; + } + break; + + case Type::Circle: + { + double minSide = std::min(_parentNode->getRealWidth(), _parentNode->getRealHeight()); + + ID2D1EllipseGeometry* circle = nullptr; + Renderer::getFactory()->CreateEllipseGeometry( + D2D1::Ellipse( + D2D1::Point2F( + float(_parentNode->getRealWidth() / 2), + float(_parentNode->getRealHeight() / 2) + ), + float(minSide / 2), + float(minSide / 2) + ), + &circle + ); + _geometry = circle; + } + break; + + case Type::Ellipse: + { + float halfWidth = float(_parentNode->getWidth() / 2), + halfHeight = float(_parentNode->getHeight() / 2); + + ID2D1EllipseGeometry* ellipse = nullptr; + Renderer::getFactory()->CreateEllipseGeometry( + D2D1::Ellipse( + D2D1::Point2F( + halfWidth, + halfHeight), + halfWidth, + halfHeight), + &ellipse + ); + _geometry = ellipse; + } + break; + + default: + break; + } + } +} + +void e2d::Collider::_transform() +{ + if (_parentNode && _enabled) + { + // 重新生成碰撞体 + _recreate(_type); + // 二维变换 Renderer::getFactory()->CreateTransformedGeometry( _geometry, _parentNode->_finalMatri, &_transformed ); - + // 通知碰撞体管理器 ColliderManager::__updateCollider(this); } - else - { - SafeRelease(_transformed); - } } diff --git a/core/Manager/ColliderManager.cpp b/core/Manager/ColliderManager.cpp index 519480f8..7e190b48 100644 --- a/core/Manager/ColliderManager.cpp +++ b/core/Manager/ColliderManager.cpp @@ -54,11 +54,6 @@ void e2d::ColliderManager::__addCollider(Collider * pCollider) { if (pCollider) { - if (pCollider->_parentNode) - { - WARN("ColliderManager::__add Failed! The shape is already added."); - return; - } pCollider->retain(); s_vColliders.push_back(pCollider); } diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index 4ac23707..1c874fb8 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -31,15 +31,13 @@ e2d::Node::Node() , _needTransform(false) , _autoUpdate(true) , _positionFixed(false) + , _colliderType(Collider::Type::None) { Point defPivot = Game::getInstance()->getConfig()->getNodeDefaultPivot(); - _pivotX = float(defPivot.x); - _pivotY = float(defPivot.y); + this->_pivotX = float(defPivot.x); + this->_pivotY = float(defPivot.y); - if (s_fDefaultColliderType != Collider::Type::None) - { - this->setCollider(s_fDefaultColliderType); - } + this->setColliderType(s_fDefaultColliderType); } e2d::Node::~Node() @@ -189,7 +187,7 @@ void e2d::Node::_updateTransform() _finalMatri = _finalMatri * _parent->_initialMatri; } - // 绑定于自身的碰撞体也进行相应转换 + // 重新生成碰撞体 if (_collider) { _collider->_transform(); @@ -539,55 +537,52 @@ void e2d::Node::setProperty(Property prop) this->setSkew(prop.skewAngleX, prop.skewAngleY); } -void e2d::Node::setCollider(Collider::Type type) +void e2d::Node::setColliderType(Collider::Type type) { - switch (type) + if (_colliderType == type) + return; + + _colliderType = type; + if (_collider) { - case Collider::Type::Rect: - { - this->setCollider(Create(this)); + switch (type) + { + case Collider::Type::Rect: + case Collider::Type::Circle: + case Collider::Type::Ellipse: + { + this->_collider->_recreate(type); + } break; - } - case Collider::Type::Circle: - { - this->setCollider(Create(this)); + default: + { + // 删除碰撞体 + ColliderManager::__removeCollider(_collider); + _collider = nullptr; + } break; - } - - case Collider::Type::Ellipse: - { - this->setCollider(Create(this)); - break; - } - - case Collider::Type::None: - { - this->setCollider(nullptr); - break; - } - - default: - break; - } -} - -void e2d::Node::setCollider(Collider * pCollider) -{ - // 删除旧的碰撞体 - ColliderManager::__removeCollider(_collider); - // 添加新的碰撞体 - ColliderManager::__addCollider(pCollider); - - if (pCollider) - { - // 双向绑定 - this->_collider = pCollider; - pCollider->_parentNode = this; + } } else { - this->_collider = nullptr; + switch (type) + { + case Collider::Type::Rect: + case Collider::Type::Circle: + case Collider::Type::Ellipse: + { + this->_collider = Create(); + this->_collider->_parentNode = this; + this->_collider->_recreate(type); + // 添加新的碰撞体 + ColliderManager::__addCollider(this->_collider); + } + break; + + default: + break; + } } } @@ -813,9 +808,9 @@ bool e2d::Node::containsPoint(const Point& point) const { BOOL ret = 0; // 如果存在碰撞体,用碰撞体判断 - if (_collider) + if (_collider && _collider->getGeometry()) { - _collider->getD2dGeometry()->FillContainsPoint( + _collider->getGeometry()->FillContainsPoint( D2D1::Point2F( float(point.x), float(point.y)), diff --git a/core/e2dcollider.h b/core/e2dcollider.h index 94605e71..4a093db6 100644 --- a/core/e2dcollider.h +++ b/core/e2dcollider.h @@ -122,184 +122,4 @@ private: static void __clearListeners(); }; - -// 碰撞体 -class Collider : - public Object -{ - friend class ColliderManager; - friend class Node; - -public: - // 碰撞体类别 - enum class Type - { - None, /* 无 */ - Rect, /* 矩形 */ - Circle, /* 圆形 */ - Ellipse /* 椭圆形 */ - }; - - // 碰撞体交集关系 - enum class Relation : int - { - Unknown = 0, /* 关系不确定 */ - Disjoin = 1, /* 没有交集 */ - IsContained = 2, /* 完全被包含 */ - Contains = 3, /* 完全包含 */ - Overlap = 4 /* 部分重叠 */ - }; - -public: - Collider(); - - virtual ~Collider(); - - // 判断两碰撞体的交集关系 - virtual Relation getRelationWith( - Collider * pCollider - ) const; - - // 获取父节点 - Node * getParentNode() const; - - // 获取绘制颜色 - Color getColor() const; - - // 启用或关闭该碰撞体 - virtual void setEnabled( - bool enabled - ); - - // 设置碰撞体的可见性 - void setVisiable( - bool bVisiable - ); - - // 设置绘制颜色 - void setColor( - Color color - ); - - // 设置大小跟随 - void setAutoResize( - bool enabled - ); - -protected: - // 转换碰撞体 - virtual void _transform(); - - // 重设大小 - virtual void _resize() = 0; - - // 渲染碰撞体 - virtual void _render(); - -protected: - bool _enabled; - bool _visiable; - bool _autoResize; - Color _color; - Node * _parentNode; - ID2D1Geometry* _geometry; - ID2D1TransformedGeometry* _transformed; -}; - - -// 矩形碰撞体 -class RectCollider : - public Collider -{ -public: - RectCollider(); - - explicit RectCollider( - double x, - double y, - double width, - double height - ); - - explicit RectCollider( - Node * node - ); - - virtual ~RectCollider(); - - // 修改矩形碰撞体大小 - void setRect( - double left, - double top, - double right, - double bottom - ); - -protected: - // 重设大小 - virtual void _resize(); -}; - - -// 圆形碰撞体 -class CircleCollider : - public Collider -{ -public: - CircleCollider(); - - explicit CircleCollider( - Point center, - double radius - ); - - explicit CircleCollider( - Node * node - ); - - virtual ~CircleCollider(); - - // 修改圆形碰撞体大小 - void setCircle( - Point center, - double radius - ); - -protected: - // 重设大小 - virtual void _resize(); -}; - - -// 椭圆形碰撞体 -class EllipseCollider : - public Collider -{ -public: - EllipseCollider(); - - explicit EllipseCollider( - Point center, - double radiusX, - double radiusY - ); - - explicit EllipseCollider( - Node * node - ); - - virtual ~EllipseCollider(); - - // 修改椭圆碰撞体大小 - void setEllipse( - Point center, - double radiusX, - double radiusY - ); - -protected: - // 重设大小 - virtual void _resize(); -}; - } \ No newline at end of file diff --git a/core/e2dcommon.h b/core/e2dcommon.h index b7719b61..6cc7e97b 100644 --- a/core/e2dcommon.h +++ b/core/e2dcommon.h @@ -697,6 +697,95 @@ protected: }; +class ColliderManager; + +// 碰撞体 +class Collider : + public Object +{ + friend class Node; + friend class ColliderManager; + +public: + // 碰撞体类别 + enum class Type + { + None, /* 无 */ + Rect, /* 矩形 */ + Circle, /* 圆形 */ + Ellipse /* 椭圆形 */ + }; + + // 碰撞体交集关系 + enum class Relation : int + { + Unknown = 0, /* 关系不确定 */ + Disjoin = 1, /* 没有交集 */ + IsContained = 2, /* 完全被包含 */ + Contains = 3, /* 完全包含 */ + Overlap = 4 /* 部分重叠 */ + }; + +public: + Collider(); + + virtual ~Collider(); + + // 启用或关闭该碰撞体 + virtual void setEnabled( + bool enabled + ); + + // 设置碰撞体的可见性 + void setVisiable( + bool bVisiable + ); + + // 设置绘制颜色 + void setColor( + Color color + ); + + // 判断两碰撞体的交集关系 + virtual Relation getRelationWith( + Collider * pCollider + ) const; + + // 获取父节点 + Node * getParentNode() const; + + // 获取绘制颜色 + Color getColor() const; + + // 获取 ID2D1Geometry* 对象 + ID2D1Geometry* getGeometry() const; + + // 获取 ID2D1TransformedGeometry* 对象 + ID2D1TransformedGeometry* getTransformedGeometry() const; + +protected: + // 重新生成 + void _recreate( + Collider::Type type + ); + + // 二维变换 + void _transform(); + + // 渲染碰撞体 + void _render(); + +protected: + bool _enabled; + bool _visiable; + Color _color; + Node * _parentNode; + Type _type; + ID2D1Geometry* _geometry; + ID2D1TransformedGeometry* _transformed; +}; + + #if _MSC_VER > 1700 // 创建可自动回收内存的对象 diff --git a/core/e2dnode.h b/core/e2dnode.h index db6dcf45..796eda61 100644 --- a/core/e2dnode.h +++ b/core/e2dnode.h @@ -1,6 +1,5 @@ #pragma once #include "e2dbase.h" -#include "e2dcollider.h" namespace e2d { @@ -8,7 +7,6 @@ namespace e2d class Action; class Transition; -class ColliderManager; class Node : public Object @@ -16,7 +14,6 @@ class Node : friend class Scene; friend class Collider; friend class Transition; - friend class ColliderManager; public: // 节点属性 @@ -334,16 +331,11 @@ public: Property prop ); - // 设置碰撞体 - virtual void setCollider( + // 设置碰撞体类型 + virtual void setColliderType( Collider::Type type ); - // 设置碰撞体 - virtual void setCollider( - Collider * pCollider - ); - // 添加子节点 virtual void addChild( Node * child, @@ -445,6 +437,7 @@ protected: Collider * _collider; Scene * _parentScene; Node * _parent; + Collider::Type _colliderType; D2D1::Matrix3x2F _initialMatri; D2D1::Matrix3x2F _finalMatri; std::vector _children; diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index f8f07eeb..7b55a143 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -58,11 +58,8 @@ - - - - + diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index a60c8ab5..8cdfbf25 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -122,20 +122,11 @@ Base - - Collider - - - Collider - Collider - - Collider - - - Collider + + Common Common diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 92b50233..a0a4085e 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -202,11 +202,8 @@ - - - - + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 0a1f8b44..21464d94 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -122,20 +122,11 @@ Base - - Collider - - - Collider - Collider - - Collider - - - Collider + + Common Common diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 90db2730..df33c02a 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -221,11 +221,8 @@ - - - - + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index c6f17fc0..9e24729d 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -99,9 +99,6 @@ Tool - - Collider - Manager @@ -219,15 +216,6 @@ Transition - - Collider - - - Collider - - - Collider - Action @@ -246,6 +234,9 @@ Common + + Common +