添加碰撞消息监听

This commit is contained in:
Nomango 2017-10-29 23:48:32 +08:00
parent 1744e25efe
commit db64bf8e8d
13 changed files with 244 additions and 65 deletions

View File

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

View File

@ -3,11 +3,13 @@
#include "..\emanagers.h"
#include "..\etools.h"
#include "..\eactions.h"
#include "..\Win\winbase.h"
#include <algorithm>
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);
}
}
void e2d::EScene::setGeometryVisiable(bool visiable)
{
m_bGeometryVisiable = visiable;
}

View File

@ -101,7 +101,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DebugInformationFormat>None</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>

View File

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

View File

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

View File

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

View File

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

View File

@ -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++)
{

View File

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

View File

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

View File

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

View File

@ -398,6 +398,11 @@ private:
// 物理引擎执行程序
static void PhysicsProc();
// 섯부暠近털뙤넋埼
static void PhysicsGeometryProc(
EGeometry * pActiveGeometry
);
// 物理碰撞监听器执行程序
static void PhysicsListenerProc();
};

View File

@ -306,6 +306,9 @@ protected:
// 渲染节点
virtual void _onRender();
// 斡횡섯부暠近
virtual void _drawGeometry();
// 节点被添加到场景时的执行程序
virtual void _onEnter();