添加碰撞消息监听

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."); ASSERT(m_pCurrentScene != nullptr, "Current scene NULL pointer exception.");
EObjectManager::__flush(); // 刷新内存池
ETimerManager::TimerProc(); // 定时器管理器执行程序 ETimerManager::TimerProc(); // 定时器管理器执行程序
EActionManager::ActionProc(); // 动作管理器执行程序 EActionManager::ActionProc(); // 动作管理器执行程序
EPhysicsManager::PhysicsProc(); // 物理引擎执行程序 EPhysicsManager::PhysicsProc(); // 物理引擎执行程序
EObjectManager::__flush(); // 刷新内存池
} }
// This method discards device-specific // This method discards device-specific
@ -391,7 +391,7 @@ void e2d::EApp::_onRender()
if (FAILED(hr)) 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(); this->quit();
} }
} }

View File

@ -3,11 +3,13 @@
#include "..\emanagers.h" #include "..\emanagers.h"
#include "..\etools.h" #include "..\etools.h"
#include "..\eactions.h" #include "..\eactions.h"
#include "..\Win\winbase.h"
#include <algorithm> #include <algorithm>
e2d::EScene::EScene() e2d::EScene::EScene()
: m_bWillSave(true) : m_bWillSave(true)
, m_bSortNeeded(false) , m_bSortNeeded(false)
, m_bGeometryVisiable(false)
, m_pRoot(new ENode()) , m_pRoot(new ENode())
{ {
m_pRoot->_onEnter(); m_pRoot->_onEnter();
@ -46,7 +48,17 @@ bool e2d::EScene::onCloseWindow()
void e2d::EScene::_onRender() void e2d::EScene::_onRender()
{ {
// 访问根节点
m_pRoot->_callOn(); m_pRoot->_callOn();
// 恢复矩阵转换
GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
// 绘制所有几何图形
if (m_bGeometryVisiable)
{
m_pRoot->_drawGeometry();
}
} }
void e2d::EScene::add(ENode * child, int order /* = 0 */) void e2d::EScene::add(ENode * child, int order /* = 0 */)
@ -93,3 +105,8 @@ void e2d::EScene::runAction(EAction * action)
{ {
this->m_pRoot->runAction(action); this->m_pRoot->runAction(action);
} }
void e2d::EScene::setGeometryVisiable(bool visiable)
{
m_bGeometryVisiable = visiable;
}

View File

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

View File

@ -1,10 +1,10 @@
#include "..\egeometry.h" #include "..\egeometry.h"
#include "..\enodes.h"
#include "..\Win\winbase.h" #include "..\Win\winbase.h"
e2d::ECircle::ECircle() e2d::ECircle::ECircle()
: m_pD2dCircle(nullptr) : m_pD2dCircle(nullptr)
{ {
this->_setCircle(EPoint(), 0);
} }
e2d::ECircle::ECircle(EPoint center, float radius) e2d::ECircle::ECircle(EPoint center, float radius)
@ -13,6 +13,24 @@ e2d::ECircle::ECircle(EPoint center, float radius)
this->_setCircle(center, 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) void e2d::ECircle::_setCircle(EPoint center, float radius)
{ {
SafeReleaseInterface(&m_pD2dCircle); SafeReleaseInterface(&m_pD2dCircle);

View File

@ -1,10 +1,10 @@
#include "..\egeometry.h" #include "..\egeometry.h"
#include "..\enodes.h"
#include "..\Win\winbase.h" #include "..\Win\winbase.h"
e2d::EEllipse::EEllipse() e2d::EEllipse::EEllipse()
: m_pD2dEllipse(nullptr) : m_pD2dEllipse(nullptr)
{ {
this->_setEllipse(EPoint(), 0, 0);
} }
e2d::EEllipse::EEllipse(EPoint center, float radiusX, float radiusY) 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); 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) void e2d::EEllipse::_setEllipse(EPoint center, float radiusX, float radiusY)
{ {
SafeReleaseInterface(&m_pD2dEllipse); SafeReleaseInterface(&m_pD2dEllipse);

View File

@ -3,10 +3,18 @@
#include "..\enodes.h" #include "..\enodes.h"
e2d::EGeometry::EGeometry() e2d::EGeometry::EGeometry()
: m_bTransformNeeded(true) : m_bTransformed(false)
, m_nColor(EColor::RED)
, m_fOpacity(1)
, m_pParentNode(nullptr) , m_pParentNode(nullptr)
, m_pTransformedGeometry(nullptr) , m_pTransformedGeometry(nullptr)
{ {
this->autoRelease();
}
e2d::EGeometry::~EGeometry()
{
SafeReleaseInterface(&m_pTransformedGeometry);
} }
e2d::ENode * e2d::EGeometry::getParentNode() const e2d::ENode * e2d::EGeometry::getParentNode() const
@ -14,22 +22,54 @@ e2d::ENode * e2d::EGeometry::getParentNode() const
return m_pParentNode; 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) 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( m_pTransformedGeometry->CompareWithGeometry(
pGeometry->m_pTransformedGeometry, pGeometry->m_pTransformedGeometry,
D2D1::Matrix3x2F::Identity(), D2D1::Matrix3x2F::Identity(),
&relation &relation
); );
return EPhysicsMsg::INTERSECT_RELATION(relation); return EPhysicsMsg::INTERSECT_RELATION(relation);
}
return EPhysicsMsg::INTERSECT_RELATION::UNKNOWN;
} }
void e2d::EGeometry::_transform() void e2d::EGeometry::_transform()
{ {
if (m_bTransformNeeded && m_pParentNode) if (m_pParentNode)
{ {
SafeReleaseInterface(&m_pTransformedGeometry); SafeReleaseInterface(&m_pTransformedGeometry);
@ -38,6 +78,7 @@ void e2d::EGeometry::_transform()
m_pParentNode->m_Matri, m_pParentNode->m_Matri,
&m_pTransformedGeometry &m_pTransformedGeometry
); );
this->m_bTransformed = true;
} }
m_bTransformNeeded = false;
} }

View File

@ -5,7 +5,6 @@
e2d::ERectangle::ERectangle() e2d::ERectangle::ERectangle()
: m_pD2dRectangle(nullptr) : m_pD2dRectangle(nullptr)
{ {
this->_setRect(0, 0, 0, 0);
} }
e2d::ERectangle::ERectangle(float x, float y, float width, float height) 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) e2d::ERectangle::ERectangle(ENode * node)
: ERectangle()
{ {
// 计算左上角坐标
D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(
node->getRealWidth() * node->getAnchorX(),
node->getRealHeight() * node->getAnchorY()
);
this->_setRect( this->_setRect(
upperLeftCorner.x, 0,
upperLeftCorner.y, 0,
upperLeftCorner.x + node->getRealWidth(), node->getRealWidth(),
upperLeftCorner.y + node->getRealHeight() node->getRealHeight()
); );
} }
e2d::ERectangle::~ERectangle()
{
SafeReleaseInterface(&m_pD2dRectangle);
}
void e2d::ERectangle::_setRect(float left, float top, float right, float bottom) void e2d::ERectangle::_setRect(float left, float top, float right, float bottom)
{ {
SafeReleaseInterface(&m_pD2dRectangle); SafeReleaseInterface(&m_pD2dRectangle);

View File

@ -14,32 +14,46 @@ void e2d::EPhysicsManager::PhysicsProc()
if (s_vListeners.empty() || s_vGeometries.empty() || EApp::isPaused()) if (s_vListeners.empty() || s_vGeometries.empty() || EApp::isPaused())
return; return;
// 判断任意两形状间的交集 for (auto &geometry : s_vGeometries)
for (auto &g1 : s_vGeometries)
{ {
if (!geometry->getParentNode() ||
(geometry->getParentNode()->getParentScene() != EApp::getCurrentScene()))
continue;
// 只对进行了变化了对象进行判断 // 只对进行了变化了对象进行判断
if (g1->m_bTransformNeeded) if (geometry->m_bTransformed)
{ {
// 变化对象 // 判断变化后的图形情况
g1->_transform(); PhysicsGeometryProc(geometry);
// g1 为主动方 // 取消变化标志
EPhysicsMsg::s_pActiveGeometry = g1; geometry->m_bTransformed = false;
// 判断变化后的状态 }
for (auto &g2 : s_vGeometries) }
}
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) // 执行监听器
{ PhysicsListenerProc();
// g2 为被动方
EPhysicsMsg::s_pPassiveGeometry = g2;
// 获取两方的关系
EPhysicsMsg::s_nRelation = g1->_intersectWith(g2);
// 如果关系不为未知或无交集,响应监听器
if (EPhysicsMsg::s_nRelation != EPhysicsMsg::UNKNOWN &&
EPhysicsMsg::s_nRelation != EPhysicsMsg::DISJOINT)
{
PhysicsListenerProc();
}
}
} }
} }
} }
@ -47,8 +61,6 @@ void e2d::EPhysicsManager::PhysicsProc()
void e2d::EPhysicsManager::PhysicsListenerProc() void e2d::EPhysicsManager::PhysicsListenerProc()
{ {
if (s_vListeners.empty()) return;
// 执行鼠标消息监听函数 // 执行鼠标消息监听函数
for (size_t i = 0; i < s_vListeners.size(); i++) 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() void e2d::ENode::_onEnter()
{ {
if (!this->m_bDisplayedInScene && this->isVisiable()) 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; node->m_Matri = node->m_Matri * node->m_pParent->m_Matri;
} }
// 转换几何形状
if (node->m_pGeometry)
{
node->m_pGeometry->_transform();
}
// 遍历子节点下的所有节点 // 遍历子节点下的所有节点
node->_updateChildrenTransform(); node->_updateChildrenTransform();
// 标志已执行过变换
node->m_bTransformChildrenNeeded = false; node->m_bTransformChildrenNeeded = false;
// 绑定于自身的形状也进行相应转换 // 绑定于自身的形状也进行相应转换
if (node->m_pGeometry) 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) void e2d::ENode::setGeometry(EGeometry * geometry)
{ {
// 删除旧的形状 // 删除旧的形状
if (m_pGeometry) EPhysicsManager::delGeometry(m_pGeometry);
{ // 添加新的形状
EPhysicsManager::delGeometry(m_pGeometry); EPhysicsManager::addGeometry(geometry);
}
// Ë«Ïò°ó¶¨
this->m_pGeometry = geometry;
if (geometry) geometry->m_pParentNode = this;
if (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 EAction * action
); );
// 开启几何图形的渲染
void setGeometryVisiable(
bool visiable
);
protected: protected:
// äÖȾ³¡¾°»­Ãæ // äÖȾ³¡¾°»­Ãæ
void _onRender(); void _onRender();
@ -305,6 +310,7 @@ protected:
protected: protected:
bool m_bSortNeeded; bool m_bSortNeeded;
bool m_bWillSave; bool m_bWillSave;
bool m_bGeometryVisiable;
ENode * m_pRoot; ENode * m_pRoot;
}; };

View File

@ -47,9 +47,21 @@ class EGeometry :
public: public:
EGeometry(); EGeometry();
virtual ~EGeometry();
// 获取父节点 // 获取父节点
ENode * getParentNode() const; ENode * getParentNode() const;
// 设置绘制颜色
void setColor(
UINT32 color
);
// 设置绘制透明度
void setOpacity(
float opacity
);
protected: protected:
// 判断两形状的交集关系 // 判断两形状的交集关系
virtual EPhysicsMsg::INTERSECT_RELATION _intersectWith( virtual EPhysicsMsg::INTERSECT_RELATION _intersectWith(
@ -59,10 +71,15 @@ protected:
// 转换形状 // 转换形状
virtual void _transform(); virtual void _transform();
// 渲染几何图形
virtual void _onRender();
virtual ID2D1Geometry * _getD2dGeometry() const = 0; virtual ID2D1Geometry * _getD2dGeometry() const = 0;
protected: protected:
bool m_bTransformNeeded; bool m_bTransformed;
UINT32 m_nColor;
float m_fOpacity;
ENode * m_pParentNode; ENode * m_pParentNode;
ID2D1TransformedGeometry * m_pTransformedGeometry; ID2D1TransformedGeometry * m_pTransformedGeometry;
}; };
@ -72,10 +89,10 @@ class ERectangle :
public EGeometry public EGeometry
{ {
public: public:
// 创建一个空矩形 // 创建一个空几何矩形
ERectangle(); ERectangle();
// 根据左上角坐标和宽高创建矩形 // 根据左上角坐标和宽高创建几何矩形
ERectangle( ERectangle(
float x, float x,
float y, float y,
@ -83,11 +100,13 @@ public:
float height float height
); );
// 创建一个和节点位置大小相同的矩形 // 创建一个和节点位置大小相同的几何矩形
ERectangle( ERectangle(
ENode * node ENode * node
); );
virtual ~ERectangle();
protected: protected:
void _setRect( void _setRect(
float left, float left,
@ -107,13 +126,22 @@ class ECircle :
public EGeometry public EGeometry
{ {
public: public:
// 创建一个空的几何圆形
ECircle(); ECircle();
// 根据圆心和半径创建几何圆形
ECircle( ECircle(
EPoint center, EPoint center,
float radius float radius
); );
// 创建一个和节点位置大小相同的几何圆形
ECircle(
ENode * node
);
virtual ~ECircle();
protected: protected:
void _setCircle( void _setCircle(
EPoint center, EPoint center,
@ -131,14 +159,23 @@ class EEllipse :
public EGeometry public EGeometry
{ {
public: public:
// 创建一个空的几何椭圆
EEllipse(); EEllipse();
// 根据圆心和半径创建几何椭圆
EEllipse( EEllipse(
EPoint center, EPoint center,
float radiusX, float radiusX,
float radiusY float radiusY
); );
// 创建一个和节点位置大小相同的几何椭圆
EEllipse(
ENode * node
);
virtual ~EEllipse();
protected: protected:
void _setEllipse( void _setEllipse(
EPoint center, EPoint center,

View File

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

View File

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