添加碰撞消息监听

This commit is contained in:
Nomango 2017-10-28 18:48:21 +08:00
parent 508a3e0fab
commit 1744e25efe
25 changed files with 661 additions and 126 deletions

View File

@ -348,6 +348,7 @@ void e2d::EApp::_onControl()
ETimerManager::TimerProc(); // 定时器管理器执行程序 ETimerManager::TimerProc(); // 定时器管理器执行程序
EActionManager::ActionProc(); // 动作管理器执行程序 EActionManager::ActionProc(); // 动作管理器执行程序
EPhysicsManager::PhysicsProc(); // 物理引擎执行程序
EObjectManager::__flush(); // 刷新内存池 EObjectManager::__flush(); // 刷新内存池
} }

View File

@ -92,14 +92,4 @@ void e2d::EScene::clearAllChildren()
void e2d::EScene::runAction(EAction * action) void e2d::EScene::runAction(EAction * action)
{ {
this->m_pRoot->runAction(action); this->m_pRoot->runAction(action);
} }
void e2d::EScene::bindListener(EMouseListener * listener)
{
EMsgManager::bindListener(listener, this);
}
void e2d::EScene::bindListener(EKeyboardListener * listener)
{
EMsgManager::bindListener(listener, this);
}

View File

@ -1,20 +1,22 @@
#include "..\ecommon.h" #include "..\ecommon.h"
static e2d::EKeyboardMsg s_KeyboardMsg; UINT e2d::EKeyboardMsg::s_nMsg = 0;
WPARAM e2d::EKeyboardMsg::s_wParam = 0;
LPARAM e2d::EKeyboardMsg::s_lParam = 0;
e2d::EKeyboardMsg::KEYBOARD_MSG e2d::EKeyboardMsg::getMsg() e2d::EKeyboardMsg::KEYBOARD_MSG e2d::EKeyboardMsg::getMsg()
{ {
return KEYBOARD_MSG(s_KeyboardMsg.m_nMsg); return KEYBOARD_MSG(EKeyboardMsg::s_nMsg);
} }
e2d::EKeyboardMsg::KEY e2d::EKeyboardMsg::getVal() e2d::EKeyboardMsg::KEY e2d::EKeyboardMsg::getVal()
{ {
return KEY(s_KeyboardMsg.m_wParam); return KEY(EKeyboardMsg::s_wParam);
} }
DWORD e2d::EKeyboardMsg::getCount() DWORD e2d::EKeyboardMsg::getCount()
{ {
return (((DWORD)s_KeyboardMsg.m_lParam) & 0x0000FFFF); return (((DWORD)EKeyboardMsg::s_lParam) & 0x0000FFFF);
} }
bool e2d::EKeyboardMsg::isKeyDown(KEY key) bool e2d::EKeyboardMsg::isKeyDown(KEY key)
@ -52,8 +54,3 @@ bool e2d::EKeyboardMsg::isScrollLockOn()
} }
return false; return false;
} }
e2d::EKeyboardMsg & e2d::EKeyboardMsg::getKeyboardMsg()
{
return s_KeyboardMsg;
}

View File

@ -1,58 +1,55 @@
#include "..\ecommon.h" #include "..\ecommon.h"
static e2d::EMouseMsg s_MouseMsg; UINT e2d::EMouseMsg::s_nMsg = 0;
WPARAM e2d::EMouseMsg::s_wParam = 0;
LPARAM e2d::EMouseMsg::s_lParam = 0;
DWORD e2d::EMouseMsg::getPosX() DWORD e2d::EMouseMsg::getPosX()
{ {
return LOWORD(s_MouseMsg.m_lParam); return LOWORD(EMouseMsg::s_lParam);
} }
DWORD e2d::EMouseMsg::getPosY() DWORD e2d::EMouseMsg::getPosY()
{ {
return HIWORD(s_MouseMsg.m_lParam); return HIWORD(EMouseMsg::s_lParam);
} }
e2d::EPoint e2d::EMouseMsg::getPos() e2d::EPoint e2d::EMouseMsg::getPos()
{ {
return EPoint(LOWORD(s_MouseMsg.m_lParam), HIWORD(s_MouseMsg.m_lParam)); return EPoint(LOWORD(EMouseMsg::s_lParam), HIWORD(EMouseMsg::s_lParam));
} }
bool e2d::EMouseMsg::isLButtonDown() bool e2d::EMouseMsg::isLButtonDown()
{ {
return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_LBUTTON; return GET_KEYSTATE_WPARAM(EMouseMsg::s_wParam) == MK_LBUTTON;
} }
bool e2d::EMouseMsg::isMButtonDown() bool e2d::EMouseMsg::isMButtonDown()
{ {
return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_MBUTTON; return GET_KEYSTATE_WPARAM(EMouseMsg::s_wParam) == MK_MBUTTON;
} }
bool e2d::EMouseMsg::isRButtonDown() bool e2d::EMouseMsg::isRButtonDown()
{ {
return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_RBUTTON; return GET_KEYSTATE_WPARAM(EMouseMsg::s_wParam) == MK_RBUTTON;
} }
bool e2d::EMouseMsg::isShiftDown() bool e2d::EMouseMsg::isShiftDown()
{ {
return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_SHIFT; return GET_KEYSTATE_WPARAM(EMouseMsg::s_wParam) == MK_SHIFT;
} }
bool e2d::EMouseMsg::isCtrlDown() bool e2d::EMouseMsg::isCtrlDown()
{ {
return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_CONTROL; return GET_KEYSTATE_WPARAM(EMouseMsg::s_wParam) == MK_CONTROL;
} }
DWORD e2d::EMouseMsg::getWheelDelta() DWORD e2d::EMouseMsg::getWheelDelta()
{ {
return GET_WHEEL_DELTA_WPARAM(s_MouseMsg.m_wParam); return GET_WHEEL_DELTA_WPARAM(EMouseMsg::s_wParam);
} }
e2d::EMouseMsg::MOUSE_MSG e2d::EMouseMsg::getMsg() e2d::EMouseMsg::MOUSE_MSG e2d::EMouseMsg::getMsg()
{ {
return MOUSE_MSG(s_MouseMsg.m_nMsg); return MOUSE_MSG(EMouseMsg::s_nMsg);
}
e2d::EMouseMsg & e2d::EMouseMsg::getMouseMsg()
{
return s_MouseMsg;
} }

View File

@ -215,6 +215,7 @@
<ClCompile Include="Geometry\ECircle.cpp" /> <ClCompile Include="Geometry\ECircle.cpp" />
<ClCompile Include="Geometry\EEllipse.cpp" /> <ClCompile Include="Geometry\EEllipse.cpp" />
<ClCompile Include="Geometry\EGeometry.cpp" /> <ClCompile Include="Geometry\EGeometry.cpp" />
<ClCompile Include="Geometry\EPhysicsMsg.cpp" />
<ClCompile Include="Geometry\ERectangle.cpp" /> <ClCompile Include="Geometry\ERectangle.cpp" />
<ClCompile Include="Listener\ECollisionListener.cpp" /> <ClCompile Include="Listener\ECollisionListener.cpp" />
<ClCompile Include="Listener\EKeyboardListener.cpp" /> <ClCompile Include="Listener\EKeyboardListener.cpp" />
@ -225,6 +226,7 @@
<ClCompile Include="Listener\EMouseDragListener.cpp" /> <ClCompile Include="Listener\EMouseDragListener.cpp" />
<ClCompile Include="Listener\EMouseListener.cpp" /> <ClCompile Include="Listener\EMouseListener.cpp" />
<ClCompile Include="Listener\EMousePressListener.cpp" /> <ClCompile Include="Listener\EMousePressListener.cpp" />
<ClCompile Include="Listener\EPhysicsListener.cpp" />
<ClCompile Include="Manager\EActionManager.cpp" /> <ClCompile Include="Manager\EActionManager.cpp" />
<ClCompile Include="Manager\EMsgManager.cpp" /> <ClCompile Include="Manager\EMsgManager.cpp" />
<ClCompile Include="Manager\EObjectManager.cpp" /> <ClCompile Include="Manager\EObjectManager.cpp" />

View File

@ -204,6 +204,12 @@
<ClCompile Include="Manager\EPhysicsManager.cpp"> <ClCompile Include="Manager\EPhysicsManager.cpp">
<Filter>Manager</Filter> <Filter>Manager</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Listener\EPhysicsListener.cpp">
<Filter>Listener</Filter>
</ClCompile>
<ClCompile Include="Geometry\EPhysicsMsg.cpp">
<Filter>Geometry</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Win\winbase.h"> <ClInclude Include="Win\winbase.h">

View File

@ -2,11 +2,13 @@
#include "..\Win\winbase.h" #include "..\Win\winbase.h"
e2d::ECircle::ECircle() e2d::ECircle::ECircle()
: m_pD2dCircle(nullptr)
{ {
this->_setCircle(EPoint(), 0); this->_setCircle(EPoint(), 0);
} }
e2d::ECircle::ECircle(EPoint center, float radius) e2d::ECircle::ECircle(EPoint center, float radius)
: ECircle()
{ {
this->_setCircle(center, radius); this->_setCircle(center, radius);
} }

View File

@ -2,11 +2,13 @@
#include "..\Win\winbase.h" #include "..\Win\winbase.h"
e2d::EEllipse::EEllipse() e2d::EEllipse::EEllipse()
: m_pD2dEllipse(nullptr)
{ {
this->_setEllipse(EPoint(), 0, 0); this->_setEllipse(EPoint(), 0, 0);
} }
e2d::EEllipse::EEllipse(EPoint center, float radiusX, float radiusY) e2d::EEllipse::EEllipse(EPoint center, float radiusX, float radiusY)
: EEllipse()
{ {
this->_setEllipse(center, radiusX, radiusY); this->_setEllipse(center, radiusX, radiusY);
} }

View File

@ -1,28 +1,43 @@
#include "..\egeometry.h" #include "..\egeometry.h"
#include "..\Win\winbase.h" #include "..\Win\winbase.h"
#include "..\enodes.h"
e2d::EGeometry::EGeometry() e2d::EGeometry::EGeometry()
: m_bTransformed(true) : m_bTransformNeeded(true)
, m_pParentNode(nullptr) , m_pParentNode(nullptr)
, m_pTransformedGeometry(nullptr)
{ {
} }
bool e2d::EGeometry::_isCollisionWith(EGeometry * pGeometry) e2d::ENode * e2d::EGeometry::getParentNode() const
{
return m_pParentNode;
}
e2d::EPhysicsMsg::INTERSECT_RELATION e2d::EGeometry::_intersectWith(EGeometry * pGeometry)
{ {
D2D1_GEOMETRY_RELATION relation; D2D1_GEOMETRY_RELATION relation;
HRESULT hr = this->_getD2dGeometry()->CompareWithGeometry( m_pTransformedGeometry->CompareWithGeometry(
pGeometry->_getD2dGeometry(), pGeometry->m_pTransformedGeometry,
D2D1::Matrix3x2F::Identity(), D2D1::Matrix3x2F::Identity(),
&relation &relation
); );
if (SUCCEEDED(hr)) return EPhysicsMsg::INTERSECT_RELATION(relation);
{ }
return (relation == D2D1_GEOMETRY_RELATION::D2D1_GEOMETRY_RELATION_OVERLAP) ||
(relation == D2D1_GEOMETRY_RELATION::D2D1_GEOMETRY_RELATION_CONTAINS) ||
(relation == D2D1_GEOMETRY_RELATION::D2D1_GEOMETRY_RELATION_IS_CONTAINED);
}
return false; void e2d::EGeometry::_transform()
} {
if (m_bTransformNeeded && m_pParentNode)
{
SafeReleaseInterface(&m_pTransformedGeometry);
GetFactory()->CreateTransformedGeometry(
_getD2dGeometry(),
m_pParentNode->m_Matri,
&m_pTransformedGeometry
);
}
m_bTransformNeeded = false;
}

View File

@ -0,0 +1,20 @@
#include "..\egeometry.h"
e2d::EPhysicsMsg::INTERSECT_RELATION e2d::EPhysicsMsg::s_nRelation = e2d::EPhysicsMsg::INTERSECT_RELATION::UNKNOWN;
e2d::EGeometry * e2d::EPhysicsMsg::s_pActiveGeometry = nullptr;
e2d::EGeometry * e2d::EPhysicsMsg::s_pPassiveGeometry = nullptr;
e2d::EPhysicsMsg::INTERSECT_RELATION e2d::EPhysicsMsg::getMsg()
{
return EPhysicsMsg::s_nRelation;
}
e2d::EGeometry * e2d::EPhysicsMsg::getActiveGeometry()
{
return EPhysicsMsg::s_pActiveGeometry;
}
e2d::EGeometry * e2d::EPhysicsMsg::getPassiveGeometry()
{
return EPhysicsMsg::s_pPassiveGeometry;
}

View File

@ -3,11 +3,13 @@
#include "..\Win\winbase.h" #include "..\Win\winbase.h"
e2d::ERectangle::ERectangle() e2d::ERectangle::ERectangle()
: m_pD2dRectangle(nullptr)
{ {
this->_setRect(0, 0, 0, 0); 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)
: ERectangle()
{ {
this->_setRect(x, y, x + width, y + height); this->_setRect(x, y, x + width, y + height);
} }
@ -16,8 +18,8 @@ e2d::ERectangle::ERectangle(ENode * node)
{ {
// 计算左上角坐标 // 计算左上角坐标
D2D1_POINT_2F upperLeftCorner = D2D1::Point2F( D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(
node->getPosX() - node->getRealWidth() * node->getAnchorX(), node->getRealWidth() * node->getAnchorX(),
node->getPosY() - node->getRealHeight() * node->getAnchorY() node->getRealHeight() * node->getAnchorY()
); );
this->_setRect( this->_setRect(
upperLeftCorner.x, upperLeftCorner.x,

View File

@ -0,0 +1,37 @@
#include "..\elisteners.h"
#include "..\egeometry.h"
e2d::ECollisionListener::ECollisionListener()
: EPhysicsListener()
{
}
e2d::ECollisionListener::ECollisionListener(const EString & name)
: EPhysicsListener(name)
{
}
e2d::ECollisionListener::ECollisionListener(const COLLISION_LISTENER_CALLBACK & callback)
: EPhysicsListener()
{
this->m_Callback = callback;
}
e2d::ECollisionListener::ECollisionListener(const EString & name, const COLLISION_LISTENER_CALLBACK & callback)
: EPhysicsListener(name)
{
this->m_Callback = callback;
}
void e2d::ECollisionListener::_callOn()
{
if (EPhysicsMsg::getMsg() == EPhysicsMsg::OVERLAP ||
EPhysicsMsg::getMsg() == EPhysicsMsg::CONTAINS ||
EPhysicsMsg::getMsg() == EPhysicsMsg::IS_CONTAINED)
{
m_Callback(
EPhysicsMsg::getActiveGeometry()->getParentNode(),
EPhysicsMsg::getPassiveGeometry()->getParentNode()
);
}
}

View File

@ -35,7 +35,7 @@ void e2d::EKeyboardListener::setCallback(const KEY_LISTENER_CALLBACK & callback)
void e2d::EKeyboardListener::bindWith(EScene * pParentScene) void e2d::EKeyboardListener::bindWith(EScene * pParentScene)
{ {
WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); WARN_IF(m_pParentNode != nullptr, "A listener cannot bind with two object.");
if (pParentScene) if (pParentScene)
{ {
@ -45,9 +45,9 @@ void e2d::EKeyboardListener::bindWith(EScene * pParentScene)
void e2d::EKeyboardListener::bindWith(ENode * pParentNode) void e2d::EKeyboardListener::bindWith(ENode * pParentNode)
{ {
WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); WARN_IF(m_pParentNode != nullptr, "A listener cannot bind with two object.");
if (pParentNode != nullptr && m_pParentScene == nullptr) if (pParentNode)
{ {
EMsgManager::bindListener(this, pParentNode); EMsgManager::bindListener(this, pParentNode);
} }

View File

@ -35,7 +35,7 @@ void e2d::EMouseListener::setCallback(const MOUSE_LISTENER_CALLBACK & callback)
void e2d::EMouseListener::bindWith(EScene * pParentScene) void e2d::EMouseListener::bindWith(EScene * pParentScene)
{ {
WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); WARN_IF(m_pParentNode != nullptr, "A listener cannot bind with two object.");
if (pParentScene) if (pParentScene)
{ {
@ -45,9 +45,9 @@ void e2d::EMouseListener::bindWith(EScene * pParentScene)
void e2d::EMouseListener::bindWith(ENode * pParentNode) void e2d::EMouseListener::bindWith(ENode * pParentNode)
{ {
WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); WARN_IF(m_pParentNode != nullptr, "A listener cannot bind with two object.");
if (pParentNode != nullptr && m_pParentScene == nullptr) if (pParentNode != nullptr)
{ {
EMsgManager::bindListener(this, pParentNode); EMsgManager::bindListener(this, pParentNode);
} }

View File

@ -0,0 +1,59 @@
#include "..\elisteners.h"
#include "..\egeometry.h"
#include "..\emanagers.h"
e2d::EPhysicsListener::EPhysicsListener()
: EListener()
{
}
e2d::EPhysicsListener::EPhysicsListener(const EString & name)
: EListener(name)
{
}
e2d::EPhysicsListener::EPhysicsListener(const PHYSICS_LISTENER_CALLBACK & callback)
: EListener()
{
m_Callback = callback;
}
e2d::EPhysicsListener::EPhysicsListener(const EString & name, const PHYSICS_LISTENER_CALLBACK & callback)
: EListener(name)
{
m_Callback = callback;
}
void e2d::EPhysicsListener::_callOn()
{
m_Callback(
EPhysicsMsg::getActiveGeometry()->getParentNode(),
EPhysicsMsg::getPassiveGeometry()->getParentNode(),
EPhysicsMsg::getMsg()
);
}
void e2d::EPhysicsListener::setCallback(const PHYSICS_LISTENER_CALLBACK & callback)
{
m_Callback = callback;
}
void e2d::EPhysicsListener::bindWith(EScene * pParentScene)
{
WARN_IF(m_pParentNode != nullptr, "A listener cannot bind with two object.");
if (pParentScene)
{
EPhysicsManager::bindListener(this, pParentScene);
}
}
void e2d::EPhysicsListener::bindWith(ENode * pParentNode)
{
WARN_IF(m_pParentNode != nullptr, "A listener cannot bind with two object.");
if (pParentNode != nullptr)
{
EPhysicsManager::bindListener(this, pParentNode);
}
}

View File

@ -13,9 +13,9 @@ e2d::EVector<e2d::EKeyboardListener*> s_vKeyboardListeners;
void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam) void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam)
{ {
// 保存鼠标消息 // 保存鼠标消息
EMouseMsg::getMouseMsg().m_nMsg = message; EMouseMsg::s_nMsg = message;
EMouseMsg::getMouseMsg().m_wParam = wParam; EMouseMsg::s_wParam = wParam;
EMouseMsg::getMouseMsg().m_lParam = lParam; EMouseMsg::s_lParam = lParam;
// 执行鼠标消息监听函数 // 执行鼠标消息监听函数
for (size_t i = 0; i < s_vMouseListeners.size(); i++) for (size_t i = 0; i < s_vMouseListeners.size(); i++)
{ {
@ -38,9 +38,9 @@ void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam)
void e2d::EMsgManager::KeyboardProc(UINT message, WPARAM wParam, LPARAM lParam) void e2d::EMsgManager::KeyboardProc(UINT message, WPARAM wParam, LPARAM lParam)
{ {
// 保存按键消息 // 保存按键消息
EKeyboardMsg::getKeyboardMsg().m_nMsg = message; EKeyboardMsg::s_nMsg = message;
EKeyboardMsg::getKeyboardMsg().m_wParam = wParam; EKeyboardMsg::s_wParam = wParam;
EKeyboardMsg::getKeyboardMsg().m_lParam = lParam; EKeyboardMsg::s_lParam = lParam;
// 执行按键消息监听函数 // 执行按键消息监听函数
for (size_t i = 0; i < s_vKeyboardListeners.size(); i++) for (size_t i = 0; i < s_vKeyboardListeners.size(); i++)
{ {

View File

@ -1,26 +1,226 @@
#include "..\emanagers.h" #include "..\emanagers.h"
#include "..\enodes.h"
#include "..\elisteners.h"
#include "..\egeometry.h" #include "..\egeometry.h"
// 监听器集合
e2d::EVector<e2d::EPhysicsListener*> s_vListeners;
// 形状集合
e2d::EVector<e2d::EGeometry*> s_vGeometries; e2d::EVector<e2d::EGeometry*> s_vGeometries;
void e2d::EPhysicsManager::bindWith(EGeometry * geometry, ENode * node)
{
WARN_IF(geometry == nullptr, "EGeometry NULL pointer exception!");
WARN_IF(node == nullptr, "EGeometry add to a NULL ENode pointer!");
if (geometry && node) void e2d::EPhysicsManager::PhysicsProc()
{
if (s_vListeners.empty() || s_vGeometries.empty() || EApp::isPaused())
return;
// 判断任意两形状间的交集
for (auto &g1 : s_vGeometries)
{
// 只对进行了变化了对象进行判断
if (g1->m_bTransformNeeded)
{
// 变化对象
g1->_transform();
// g1 为主动方
EPhysicsMsg::s_pActiveGeometry = g1;
// 判断变化后的状态
for (auto &g2 : s_vGeometries)
{
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();
}
}
}
}
}
}
void e2d::EPhysicsManager::PhysicsListenerProc()
{
if (s_vListeners.empty()) return;
// 执行鼠标消息监听函数
for (size_t i = 0; i < s_vListeners.size(); i++)
{
auto &listener = s_vListeners[i];
if (listener->isRunning())
{
if (listener->getParentNode() &&
listener->getParentNode()->getParentScene() == EApp::getCurrentScene())
{
listener->_callOn();
}
}
}
}
void e2d::EPhysicsManager::bindListener(EPhysicsListener * listener, EScene * pParentScene)
{
EPhysicsManager::bindListener(listener, pParentScene->getRoot());
}
void e2d::EPhysicsManager::bindListener(EPhysicsListener * listener, ENode * pParentNode)
{
WARN_IF(listener == nullptr, "EPhysicsListener NULL pointer exception!");
WARN_IF(pParentNode == nullptr, "EPhysicsListener add to a NULL ENode pointer!");
if (listener && pParentNode)
{ {
ASSERT( ASSERT(
!geometry->m_pParentNode, !listener->m_pParentNode,
"The geometry is already added, it cannot bind again!" "The listener is already binded, it cannot bind again!"
); );
listener->retain();
listener->start();
listener->m_pParentNode = pParentNode;
s_vListeners.push_back(listener);
}
}
void e2d::EPhysicsManager::addGeometry(EGeometry * geometry)
{
if (geometry)
{
geometry->retain(); geometry->retain();
geometry->m_pParentNode = node;
s_vGeometries.push_back(geometry); s_vGeometries.push_back(geometry);
} }
} }
void e2d::EPhysicsManager::PhysicsProc() void e2d::EPhysicsManager::delGeometry(EGeometry * geometry)
{ {
if (geometry)
{
for (size_t i = 0; i < s_vGeometries.size(); i++)
{
if (s_vGeometries[i] == geometry)
{
SafeReleaseAndClear(&geometry);
s_vGeometries.erase(s_vGeometries.begin() + i);
return;
}
}
}
}
void e2d::EPhysicsManager::startListeners(const EString & name)
{
for (auto listener : s_vListeners)
{
if (listener->getName() == name)
{
listener->start();
}
}
}
void e2d::EPhysicsManager::stopListeners(const EString & name)
{
for (auto listener : s_vListeners)
{
if (listener->getName() == name)
{
listener->stop();
}
}
}
void e2d::EPhysicsManager::delListeners(const EString & name)
{
EVector<EPhysicsListener*>::iterator iter;
for (iter = s_vListeners.begin(); iter != s_vListeners.end();)
{
if ((*iter)->getName() == name)
{
SafeReleaseAndClear(&(*iter));
iter = s_vListeners.erase(iter);
}
else
{
iter++;
}
}
}
void e2d::EPhysicsManager::startAllListenersBindedWith(EScene * pParentScene)
{
EPhysicsManager::startAllListenersBindedWith(pParentScene->getRoot());
}
void e2d::EPhysicsManager::stopAllListenersBindedWith(EScene * pParentScene)
{
EPhysicsManager::stopAllListenersBindedWith(pParentScene->getRoot());
}
void e2d::EPhysicsManager::startAllListenersBindedWith(ENode * pParentNode)
{
for (auto listener : s_vListeners)
{
if (listener->getParentNode() == pParentNode)
{
listener->start();
}
}
for (auto child : pParentNode->getChildren())
{
EPhysicsManager::startAllListenersBindedWith(child);
}
}
void e2d::EPhysicsManager::stopAllListenersBindedWith(ENode * pParentNode)
{
for (auto listener : s_vListeners)
{
if (listener->getParentNode() == pParentNode)
{
listener->stop();
}
}
for (auto child : pParentNode->getChildren())
{
EPhysicsManager::stopAllListenersBindedWith(child);
}
}
void e2d::EPhysicsManager::startAllListeners()
{
EPhysicsManager::startAllListenersBindedWith(EApp::getCurrentScene());
}
void e2d::EPhysicsManager::stopAllListeners()
{
EPhysicsManager::stopAllListenersBindedWith(EApp::getCurrentScene());
}
void e2d::EPhysicsManager::_clearManager()
{
s_vListeners.clear();
}
void e2d::EPhysicsManager::_clearAllListenersBindedWith(ENode * pParentNode)
{
for (size_t i = 0; i < s_vListeners.size();)
{
auto listener = s_vListeners[i];
if (listener->getParentNode() == pParentNode)
{
SafeReleaseAndClear(&listener);
s_vListeners.erase(s_vListeners.begin() + i);
}
else
{
i++;
}
}
} }

View File

@ -127,7 +127,7 @@ void e2d::ETimerManager::stopAllTimersBindedWith(ENode * pParentNode)
} }
for (auto child : pParentNode->getChildren()) for (auto child : pParentNode->getChildren())
{ {
ETimerManager::startAllTimersBindedWith(child); ETimerManager::stopAllTimersBindedWith(child);
} }
} }

View File

@ -41,11 +41,12 @@ e2d::ENode::~ENode()
EMsgManager::_clearAllMouseListenersBindedWith(this); EMsgManager::_clearAllMouseListenersBindedWith(this);
EMsgManager::_clearAllKeyboardListenersBindedWith(this); EMsgManager::_clearAllKeyboardListenersBindedWith(this);
EActionManager::_clearAllActionsBindedWith(this); EActionManager::_clearAllActionsBindedWith(this);
EPhysicsManager::_clearAllListenersBindedWith(this);
EPhysicsManager::delGeometry(m_pGeometry);
for (auto child : m_vChildren) for (auto child : m_vChildren)
{ {
SafeReleaseAndClear(&child); SafeReleaseAndClear(&child);
} }
SafeReleaseAndClear(&m_pGeometry);
} }
void e2d::ENode::onEnter() void e2d::ENode::onEnter()
@ -200,10 +201,14 @@ 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;
} }
// ת»»¾ØÕóºóÅжÏ
// 遍历子节点下的所有节点 // 遍历子节点下的所有节点
node->_updateChildrenTransform(); node->_updateChildrenTransform();
node->m_bTransformChildrenNeeded = false; node->m_bTransformChildrenNeeded = false;
// 绑定于自身的形状也进行相应转换
if (node->m_pGeometry)
{
node->m_pGeometry->m_bTransformNeeded = true;
}
} }
void e2d::ENode::_updateChildrenOpacity() void e2d::ENode::_updateChildrenOpacity()
@ -474,7 +479,20 @@ void e2d::ENode::setAnchor(float anchorX, float anchorY)
void e2d::ENode::setGeometry(EGeometry * geometry) void e2d::ENode::setGeometry(EGeometry * geometry)
{ {
EPhysicsManager::bindWith(geometry, this); // 删除旧的形状
if (m_pGeometry)
{
EPhysicsManager::delGeometry(m_pGeometry);
}
// 双向绑定
this->m_pGeometry = geometry;
if (geometry) geometry->m_pParentNode = this;
if (geometry)
{
m_pGeometry->_transform();
EPhysicsManager::addGeometry(geometry);
}
} }
void e2d::ENode::addChild(ENode * child, int order /* = 0 */) void e2d::ENode::addChild(ENode * child, int order /* = 0 */)

View File

@ -298,12 +298,6 @@ public:
EAction * action EAction * action
); );
// 绑定鼠标消息监听器
void bindListener(EMouseListener * listener);
// 绑定按键消息监听器
void bindListener(EKeyboardListener * listener);
protected: protected:
// äÖȾ³¡¾°»­Ãæ // äÖȾ³¡¾°»­Ãæ
void _onRender(); void _onRender();

View File

@ -111,31 +111,6 @@ template<typename T>
using EVector = std::vector<T>; using EVector = std::vector<T>;
// 定时器回调函数(参数为该定时器被调用的次数,从 0 开始)
typedef std::function<void(int)> TIMER_CALLBACK;
// 按钮点击回调函数
typedef std::function<void()> BUTTON_CLICK_CALLBACK;
// 按键消息监听回调函数
typedef std::function<void()> KEY_LISTENER_CALLBACK;
// 鼠标消息监听回调函数
typedef std::function<void()> MOUSE_LISTENER_CALLBACK;
// 鼠标点击消息监听回调函数(参数为点击位置)
typedef std::function<void(EPoint mousePos)> MOUSE_CLICK_LISTENER_CALLBACK;
// 鼠标按下消息监听回调函数(参数为按下位置)
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_PRESS_LISTENER_CALLBACK;
// 鼠标双击消息监听回调函数(参数为双击位置)
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_DBLCLK_LISTENER_CALLBACK;
// 鼠标拖动消息监听函数(参数为拖动前位置和拖动后位置)
typedef std::function<void(EPoint begin, EPoint end)> MOUSE_DRAG_LISTENER_CALLBACK;
class EColor class EColor
{ {
public: public:
@ -361,13 +336,10 @@ public:
// 获取当前鼠标消息类型 // 获取当前鼠标消息类型
static MOUSE_MSG getMsg(); static MOUSE_MSG getMsg();
// 获取当前鼠标消息
static EMouseMsg & getMouseMsg();
public: public:
UINT m_nMsg = 0; static UINT s_nMsg;
WPARAM m_wParam = 0; static WPARAM s_wParam;
LPARAM m_lParam = 0; static LPARAM s_lParam;
}; };
@ -433,13 +405,35 @@ public:
// 获取滑动锁定状态 // 获取滑动锁定状态
static bool isScrollLockOn(); static bool isScrollLockOn();
// 获取当前按键消息
static EKeyboardMsg & getKeyboardMsg();
public: public:
UINT m_nMsg = 0; static UINT s_nMsg;
WPARAM m_wParam = 0; static WPARAM s_wParam;
LPARAM m_lParam = 0; static LPARAM s_lParam;
}; };
// 定时器回调函数(参数为该定时器被调用的次数,从 0 开始)
typedef std::function<void(int)> TIMER_CALLBACK;
// 按钮点击回调函数
typedef std::function<void()> BUTTON_CLICK_CALLBACK;
// 按键消息监听回调函数
typedef std::function<void()> KEY_LISTENER_CALLBACK;
// 鼠标消息监听回调函数
typedef std::function<void()> MOUSE_LISTENER_CALLBACK;
// 鼠标点击消息监听回调函数(参数为点击位置)
typedef std::function<void(EPoint mousePos)> MOUSE_CLICK_LISTENER_CALLBACK;
// 鼠标按下消息监听回调函数(参数为按下位置)
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_PRESS_LISTENER_CALLBACK;
// 鼠标双击消息监听回调函数(参数为双击位置)
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_DBLCLK_LISTENER_CALLBACK;
// 鼠标拖动消息监听回调函数(参数为拖动前位置和拖动后位置)
typedef std::function<void(EPoint begin, EPoint end)> MOUSE_DRAG_LISTENER_CALLBACK;
} }

View File

@ -6,24 +6,65 @@ namespace e2d
{ {
class EPhysicsManager; class EPhysicsManager;
class ENode;
class EGeometry;
class EPhysicsMsg
{
friend EPhysicsManager;
public:
enum INTERSECT_RELATION
{
UNKNOWN = 0, /* 关系不确定 */
DISJOINT = 1, /* 没有交集 */
IS_CONTAINED = 2, /* 完全被包含 */
CONTAINS = 3, /* 完全包含 */
OVERLAP = 4 /* 部分重叠 */
};
// 获取当前物理碰撞消息类型
static INTERSECT_RELATION getMsg();
// 获取主动方
static EGeometry * getActiveGeometry();
// 获取被动方
static EGeometry * getPassiveGeometry();
public:
static INTERSECT_RELATION s_nRelation;
static EGeometry * s_pActiveGeometry;
static EGeometry * s_pPassiveGeometry;
};
class EGeometry : class EGeometry :
public EObject public EObject
{ {
friend EPhysicsManager; friend EPhysicsManager;
friend ENode;
public: public:
EGeometry(); EGeometry();
// 获取父节点
ENode * getParentNode() const;
protected: protected:
virtual bool _isCollisionWith( // 判断两形状的交集关系
virtual EPhysicsMsg::INTERSECT_RELATION _intersectWith(
EGeometry * pGeometry EGeometry * pGeometry
); );
// 转换形状
virtual void _transform();
virtual ID2D1Geometry * _getD2dGeometry() const = 0; virtual ID2D1Geometry * _getD2dGeometry() const = 0;
protected: protected:
bool m_bTransformed; bool m_bTransformNeeded;
ENode * m_pParentNode; ENode * m_pParentNode;
ID2D1TransformedGeometry * m_pTransformedGeometry;
}; };

View File

@ -1,12 +1,13 @@
#pragma once #pragma once
#include "ebase.h" #include "ebase.h"
#include "egeometry.h"
namespace e2d namespace e2d
{ {
class ENode; class ENode;
class EMsgManager; class EMsgManager;
class EPhysicsManager;
// 监听器 // 监听器
class EListener : class EListener :
@ -321,4 +322,86 @@ protected:
virtual void _callOn() override; virtual void _callOn() override;
}; };
// 物理世界消息监听器回调函数(参数:主动方、被动方、两方关系)
typedef std::function<void(ENode *active, ENode *passive, int relation)> PHYSICS_LISTENER_CALLBACK;
// 碰撞消息监听器回调函数(参数:主动方、被动方)
typedef std::function<void(ENode *active, ENode *passive)> COLLISION_LISTENER_CALLBACK;
// 物理世界消息监听器
class EPhysicsListener :
public EListener
{
friend EPhysicsManager;
public:
EPhysicsListener();
EPhysicsListener(
const EString &name
);
EPhysicsListener(
const PHYSICS_LISTENER_CALLBACK &callback
);
EPhysicsListener(
const EString &name,
const PHYSICS_LISTENER_CALLBACK &callback
);
// 设置监听器回调函数
void setCallback(
const PHYSICS_LISTENER_CALLBACK &callback
);
// 将监听器与场景绑定
virtual void bindWith(
EScene * pParentScene
) override;
// 将监听器与节点绑定
virtual void bindWith(
ENode * pParentNode
) override;
protected:
// 执行监听器回调函数
virtual void _callOn() override;
protected:
PHYSICS_LISTENER_CALLBACK m_Callback;
};
class ECollisionListener :
public EPhysicsListener
{
friend EMsgManager;
public:
ECollisionListener();
ECollisionListener(
const EString &name
);
ECollisionListener(
const COLLISION_LISTENER_CALLBACK &callback
);
ECollisionListener(
const EString &name,
const COLLISION_LISTENER_CALLBACK &callback
);
protected:
// 执行监听器回调函数
virtual void _callOn() override;
protected:
COLLISION_LISTENER_CALLBACK m_Callback;
};
} }

View File

@ -13,6 +13,8 @@ class ETimer;
class EAction; class EAction;
class EMouseListener; class EMouseListener;
class EKeyboardListener; class EKeyboardListener;
class EGeometry;
class EPhysicsListener;
// 对象管理器 // 对象管理器
class EObjectManager class EObjectManager
@ -316,16 +318,88 @@ private:
class EPhysicsManager class EPhysicsManager
{ {
friend EApp;
friend EScene;
friend ENode;
public: public:
// 绑定形状到节点 // 添加形状
static void bindWith( static void addGeometry(
EGeometry * geometry, EGeometry * geometry
ENode * node );
// 删除已绑定的形状
static void delGeometry(
EGeometry * geometry
);
// 将监听器与场景绑定
static void bindListener(
EPhysicsListener * listener,
EScene * pParentScene
);
// 将监听器与节点绑定
static void bindListener(
EPhysicsListener * listener,
ENode * pParentNode
);
// 启动具有相同名称的监听器
static void startListeners(
const EString &name
);
// 停止具有相同名称的监听器
static void stopListeners(
const EString &name
);
// 删除具有相同名称的监听器
static void delListeners(
const EString &name
);
// 启动绑定在场景及其子节点上的所有监听器
static void startAllListenersBindedWith(
EScene * pParentScene
);
// 停止绑定在场景及其子节点上的所有监听器
static void stopAllListenersBindedWith(
EScene * pParentScene
);
// 启动绑定在节点上的所有监听器
static void startAllListenersBindedWith(
ENode * pParentNode
);
// 停止绑定在节点上的所有监听器
static void stopAllListenersBindedWith(
ENode * pParentNode
);
// 启动所有监听器
static void startAllListeners();
// 停止所有监听器
static void stopAllListeners();
private:
// 清空监听器管理器
static void _clearManager();
// 清空绑定在节点上的所有监听器
static void _clearAllListenersBindedWith(
ENode * pParentNode
); );
protected:
// 物理引擎执行程序 // 物理引擎执行程序
static void PhysicsProc(); static void PhysicsProc();
// 物理碰撞监听器执行程序
static void PhysicsListenerProc();
}; };
} }

View File

@ -15,6 +15,7 @@ class ENode :
{ {
friend EScene; friend EScene;
friend EButton; friend EButton;
friend EGeometry;
public: public:
ENode(); ENode();