增加节点轮廓

This commit is contained in:
Nomango 2018-07-07 18:04:18 +08:00
parent de951eaa40
commit 7e3b224b69
7 changed files with 123 additions and 133 deletions

View File

@ -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();
// 삿혤늉<ED98A4>뺌岬
@ -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);
// 二维变换
ID2D1TransformedGeometry * _transformed;
Renderer::getFactory()->CreateTransformedGeometry(
_geometry,
_parentNode->_finalMatri,
&_transformed
);
}
SafeRelease(_geometry);
_geometry = _transformed;
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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)
{
_updateTransform();
if (_outline)
{
BOOL ret = 0;
// 如果存在碰撞体,用碰撞体判断
if (_collider.getGeometry())
{
_collider.getGeometry()->FillContainsPoint(
D2D1::Point2F(
float(point.x),
float(point.y)),
_finalMatri,
_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
bool e2d::Node::intersects(Node * node)
{
// 如果存在碰撞体,用碰撞体判断
if (this->_collider.getGeometry() && node->_collider.getGeometry())
_updateTransform();
node->_updateTransform();
if (_outline)
{
Collider::Relation relation = this->_collider.getRelationWith(&node->_collider);
if ((relation != Collider::Relation::Unknown) &&
(relation != Collider::Relation::Disjoin))
{
return true;
}
}
else
{
// 为节点创建一个临时碰撞体
ID2D1RectangleGeometry * pRect1;
ID2D1RectangleGeometry * pRect2;
ID2D1TransformedGeometry * pCollider;
D2D1_GEOMETRY_RELATION relation;
// 根据自身大小位置创建矩形
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
);
// 获取相交状态
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;
}

View File

@ -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;

View File

@ -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<Node*> _children;