更新ENode矩形变换,增加按下和双击鼠标消息监听器

This commit is contained in:
Nomango 2017-10-15 23:58:39 +08:00
parent 1e24823452
commit 05bcd762e0
20 changed files with 811 additions and 156 deletions

View File

@ -14,7 +14,7 @@ int WINAPI WinMain(
{ {
auto scene = new EScene(); auto scene = new EScene();
auto node = new ENode(L"node1"); /*auto node = new ENode(L"node1");
node->setPos(50, 80); node->setPos(50, 80);
node->setSize(30, 30); node->setSize(30, 30);
scene->add(node); scene->add(node);
@ -28,10 +28,26 @@ int WINAPI WinMain(
EApp::getCurrentScene()->getChild(L"node1")->setPos(p.x, p.y); EApp::getCurrentScene()->getChild(L"node1")->setPos(p.x, p.y);
}); });
mlistener->bindWith(node); mlistener->bindWith(node);*/
auto sprite = new ESprite(L"test.png");
sprite->setAnchor(0.5f, 0.5f);
sprite->setPos(sprite->getWidth() / 2, sprite->getHeight() / 2);
auto sprite2 = new ESprite(L"test.png");
sprite2->setScale(0.5);
sprite2->setRotation(45);
sprite->addChild(sprite2);
auto mlistener = new EMouseClickListener([=](EPoint p) {
sprite->setRotation(sprite->getRotation() + 10);
});
mlistener->bindWith(sprite);
scene->add(sprite);
app.enterScene(scene); app.enterScene(scene);
app.run(); app.run();
} }

BIN
Demo/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -9,12 +9,6 @@ using namespace std::chrono;
using namespace std::this_thread; using namespace std::this_thread;
#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif
e2d::EApp * s_pInstance = nullptr; e2d::EApp * s_pInstance = nullptr;
std::stack<e2d::EScene*> s_SceneStack; std::stack<e2d::EScene*> s_SceneStack;
@ -134,7 +128,7 @@ bool e2d::EApp::init(e2d::EString title, UINT32 width, UINT32 height, bool bShow
// 获取窗口大小(包含菜单栏) // 获取窗口大小(包含菜单栏)
tagRECT rcWindow; tagRECT rcWindow;
GetWindowRect(GetHWnd(), &rcWindow); GetWindowRect(GetHWnd(), &rcWindow);
// 修改窗口大小,并设置窗口在屏幕居中 // 设置窗口在屏幕居中
MoveWindow( MoveWindow(
GetHWnd(), GetHWnd(),
(screenWidth - (rcWindow.right - rcWindow.left)) / 2, (screenWidth - (rcWindow.right - rcWindow.left)) / 2,
@ -432,6 +426,7 @@ void e2d::EApp::_enterNextScene()
if (m_pCurrentScene) if (m_pCurrentScene)
{ {
m_pCurrentScene->onExit(); m_pCurrentScene->onExit();
m_pCurrentScene->_onExit();
if (m_pCurrentScene->m_bWillSave) if (m_pCurrentScene->m_bWillSave)
{ {
@ -444,7 +439,9 @@ void e2d::EApp::_enterNextScene()
} }
} }
m_pNextScene->onEnter(); // 执行下一场景的 onEnter 函数 // 执行下一场景的 onEnter 函数
m_pNextScene->_onEnter();
m_pNextScene->onEnter();
m_pCurrentScene = m_pNextScene; // 切换场景 m_pCurrentScene = m_pNextScene; // 切换场景
m_pNextScene = nullptr; // 下一场景置空 m_pNextScene = nullptr; // 下一场景置空
@ -474,32 +471,10 @@ HRESULT e2d::EApp::_createDeviceIndependentResources()
// changes, the window is remoted, etc. // changes, the window is remoted, etc.
HRESULT e2d::EApp::_createDeviceResources() HRESULT e2d::EApp::_createDeviceResources()
{ {
HRESULT hr = S_OK; // 这个函数将自动创建设备相关资源
GetRenderTarget();
if (!GetRenderTarget()) return S_OK;
{
RECT rc;
GetClientRect(GetHWnd(), &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// Create a Direct2D render target.
hr = GetFactory()->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(GetHWnd(), size),
&GetRenderTarget()
);
}
if (FAILED(hr))
{
MessageBox(nullptr, L"Create Device Resources Failed!", L"Error", MB_OK);
}
return hr;
} }
// Discards device-dependent resources. These resources must be // Discards device-dependent resources. These resources must be

View File

@ -14,6 +14,14 @@ e2d::EScene::~EScene()
clearAllChildren(); clearAllChildren();
} }
void e2d::EScene::onEnter()
{
}
void e2d::EScene::onExit()
{
}
void e2d::EScene::_onRender() void e2d::EScene::_onRender()
{ {
this->_sortChildren(); this->_sortChildren();
@ -23,7 +31,7 @@ void e2d::EScene::_onRender()
// 访问所有节点 // 访问所有节点
for (auto child : m_vChildren) for (auto child : m_vChildren)
{ {
child->callOn(); child->_callOn();
} }
} }
@ -44,7 +52,7 @@ void e2d::EScene::_sortChildren()
} }
} }
void e2d::EScene::onEnter() void e2d::EScene::_onEnter()
{ {
// 启用场景上的所有定时器、监听器和动画 // 启用场景上的所有定时器、监听器和动画
//Timer::notifyAllSceneTimers(m_pNextScene); //Timer::notifyAllSceneTimers(m_pNextScene);
@ -52,7 +60,7 @@ void e2d::EScene::onEnter()
//ActionManager::notifyAllSceneActions(m_pNextScene); //ActionManager::notifyAllSceneActions(m_pNextScene);
} }
void e2d::EScene::onExit() void e2d::EScene::_onExit()
{ {
if (m_bWillSave) if (m_bWillSave)
{ {

View File

@ -200,10 +200,13 @@
<ClCompile Include="Msg\Listener\EKeyPressListener.cpp" /> <ClCompile Include="Msg\Listener\EKeyPressListener.cpp" />
<ClCompile Include="Msg\Listener\EListener.cpp" /> <ClCompile Include="Msg\Listener\EListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseClickListener.cpp" /> <ClCompile Include="Msg\Listener\EMouseClickListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseDraggedListener.cpp" /> <ClCompile Include="Msg\Listener\EMouseDoubleClickListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseDragListener.cpp" />
<ClCompile Include="Msg\Listener\EMouseListener.cpp" /> <ClCompile Include="Msg\Listener\EMouseListener.cpp" />
<ClCompile Include="Msg\Listener\EMousePressListener.cpp" />
<ClCompile Include="Node\ENode.cpp" /> <ClCompile Include="Node\ENode.cpp" />
<ClCompile Include="Node\ERectangle.cpp" /> <ClCompile Include="Node\ERectangle.cpp" />
<ClCompile Include="Node\ESprite.cpp" />
<ClCompile Include="Tool\EObjectManager.cpp" /> <ClCompile Include="Tool\EObjectManager.cpp" />
<ClCompile Include="Tool\ETimerManager.cpp" /> <ClCompile Include="Tool\ETimerManager.cpp" />
<ClCompile Include="Win\winbase.cpp" /> <ClCompile Include="Win\winbase.cpp" />

View File

@ -48,9 +48,6 @@
<ClCompile Include="Msg\Listener\EMouseClickListener.cpp"> <ClCompile Include="Msg\Listener\EMouseClickListener.cpp">
<Filter>Msg\Listener</Filter> <Filter>Msg\Listener</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Msg\Listener\EMouseDraggedListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMouseListener.cpp"> <ClCompile Include="Msg\Listener\EMouseListener.cpp">
<Filter>Msg\Listener</Filter> <Filter>Msg\Listener</Filter>
</ClCompile> </ClCompile>
@ -66,6 +63,18 @@
<ClCompile Include="Node\ERectangle.cpp"> <ClCompile Include="Node\ERectangle.cpp">
<Filter>Node</Filter> <Filter>Node</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Node\ESprite.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMousePressListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMouseDoubleClickListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
<ClCompile Include="Msg\Listener\EMouseDragListener.cpp">
<Filter>Msg\Listener</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Win\winbase.h"> <ClInclude Include="Win\winbase.h">

View File

@ -2,31 +2,41 @@
e2d::EMouseClickListener::EMouseClickListener() e2d::EMouseClickListener::EMouseClickListener()
: EMouseListener() : EMouseListener()
, m_bPressed(false)
{ {
} }
e2d::EMouseClickListener::EMouseClickListener(EString name) e2d::EMouseClickListener::EMouseClickListener(EString name)
: EMouseListener(name) : EMouseListener(name)
, m_bPressed(false)
{ {
} }
e2d::EMouseClickListener::EMouseClickListener(const MOUSE_CLICK_LISTENER_CALLBACK & callback) e2d::EMouseClickListener::EMouseClickListener(const MOUSE_CLICK_LISTENER_CALLBACK & callback)
: EMouseListener() : EMouseListener()
, m_callback(callback) , m_callback(callback)
, m_bPressed(false)
{ {
} }
e2d::EMouseClickListener::EMouseClickListener(EString name, const MOUSE_CLICK_LISTENER_CALLBACK & callback) e2d::EMouseClickListener::EMouseClickListener(EString name, const MOUSE_CLICK_LISTENER_CALLBACK & callback)
: EMouseListener(name) : EMouseListener(name)
, m_callback(callback) , m_callback(callback)
, m_bPressed(false)
{ {
} }
void e2d::EMouseClickListener::runCallback() void e2d::EMouseClickListener::runCallback()
{ {
if (EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_UP) if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN ||
EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK)
{
m_bPressed = true;
}
else if (m_bPressed && EMouseMsg::getMsg() == EMouseMsg::LBUTTON_UP)
{ {
m_callback(EMouseMsg::getPos()); m_callback(EMouseMsg::getPos());
m_bPressed = false;
} }
} }

View File

@ -0,0 +1,45 @@
#include "..\..\emsg.h"
e2d::EMouseDoubleClickListener::EMouseDoubleClickListener()
: EMouseListener()
, m_bPressed(false)
{
}
e2d::EMouseDoubleClickListener::EMouseDoubleClickListener(EString name)
: EMouseListener(name)
, m_bPressed(false)
{
}
e2d::EMouseDoubleClickListener::EMouseDoubleClickListener(const MOUSE_DBLCLK_LISTENER_CALLBACK & callback)
: EMouseListener()
, m_callback(callback)
, m_bPressed(false)
{
}
e2d::EMouseDoubleClickListener::EMouseDoubleClickListener(EString name, const MOUSE_DBLCLK_LISTENER_CALLBACK & callback)
: EMouseListener(name)
, m_callback(callback)
, m_bPressed(false)
{
}
void e2d::EMouseDoubleClickListener::runCallback()
{
if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK)
{
m_bPressed = true;
}
else if (m_bPressed && EMouseMsg::getMsg() == EMouseMsg::LBUTTON_UP)
{
m_callback(EMouseMsg::getPos());
m_bPressed = false;
}
}
void e2d::EMouseDoubleClickListener::setCallback(const MOUSE_DBLCLK_LISTENER_CALLBACK & callback)
{
m_callback = callback;
}

View File

@ -0,0 +1,41 @@
#include "..\..\emsg.h"
e2d::EMouseDragListener::EMouseDragListener()
: EMouseListener()
{
}
e2d::EMouseDragListener::EMouseDragListener(EString name)
: EMouseListener(name)
{
}
e2d::EMouseDragListener::EMouseDragListener(const MOUSE_DRAG_LISTENER_CALLBACK & callback)
: EMouseListener()
, m_callback(callback)
{
}
e2d::EMouseDragListener::EMouseDragListener(EString name, const MOUSE_DRAG_LISTENER_CALLBACK & callback)
: EMouseListener(name)
, m_callback(callback)
{
}
void e2d::EMouseDragListener::runCallback()
{
if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN ||
EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK)
{
m_Begin = EMouseMsg::getPos();
}
else if (EMouseMsg::isLButtonDown() && EMouseMsg::getMsg() == EMouseMsg::MOVE)
{
m_callback(m_Begin, EMouseMsg::getPos());
}
}
void e2d::EMouseDragListener::setCallback(const MOUSE_DRAG_LISTENER_CALLBACK & callback)
{
m_callback = callback;
}

View File

@ -1,42 +0,0 @@
#include "..\..\emsg.h"
e2d::EMouseDraggedListener::EMouseDraggedListener()
: EMouseListener()
{
}
e2d::EMouseDraggedListener::EMouseDraggedListener(EString name)
: EMouseListener(name)
{
}
e2d::EMouseDraggedListener::EMouseDraggedListener(const MOUSE_DRAG_LISTENER_CALLBACK & callback)
: EMouseListener()
, m_callback(callback)
{
}
e2d::EMouseDraggedListener::EMouseDraggedListener(EString name, const MOUSE_DRAG_LISTENER_CALLBACK & callback)
: EMouseListener(name)
, m_callback(callback)
{
}
void e2d::EMouseDraggedListener::runCallback()
{
if (EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_DOWN ||
EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_DBLCLK)
{
m_Begin = EMouseMsg::getPos();
}
else if (EMouseMsg::getMsg() == EMouseMsg::MOUSE_MSG::LBUTTON_UP)
{
m_End = EMouseMsg::getPos();
m_callback(m_Begin, m_End);
}
}
void e2d::EMouseDraggedListener::setCallback(const MOUSE_DRAG_LISTENER_CALLBACK & callback)
{
m_callback = callback;
}

View File

@ -0,0 +1,37 @@
#include "..\..\emsg.h"
e2d::EMousePressListener::EMousePressListener()
: EMouseListener()
{
}
e2d::EMousePressListener::EMousePressListener(EString name)
: EMouseListener(name)
{
}
e2d::EMousePressListener::EMousePressListener(const MOUSE_PRESS_LISTENER_CALLBACK & callback)
: EMouseListener()
, m_callback(callback)
{
}
e2d::EMousePressListener::EMousePressListener(EString name, const MOUSE_PRESS_LISTENER_CALLBACK & callback)
: EMouseListener(name)
, m_callback(callback)
{
}
void e2d::EMousePressListener::runCallback()
{
if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN ||
EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK)
{
m_callback(EMouseMsg::getPos());
}
}
void e2d::EMousePressListener::setCallback(const MOUSE_PRESS_LISTENER_CALLBACK & callback)
{
m_callback = callback;
}

View File

@ -8,20 +8,22 @@ e2d::ENode::ENode()
, m_fPosY(0) , m_fPosY(0)
, m_fWidth(0) , m_fWidth(0)
, m_fHeight(0) , m_fHeight(0)
, m_fScaleX(1) , m_fScaleX(1.0f)
, m_fScaleY(1) , m_fScaleY(1.0f)
, m_fRotation(0) , m_fRotation(0)
, m_fSkewAngleX(0) , m_fSkewAngleX(0)
, m_fSkewAngleY(0) , m_fSkewAngleY(0)
, m_fDisplayOpacity(1) , m_fDisplayOpacity(1.0f)
, m_fRealOpacity(1) , m_fRealOpacity(1.0f)
, m_fAnchorX(0)
, m_fAnchorY(0)
, m_Matri(D2D1::Matrix3x2F::Identity()) , m_Matri(D2D1::Matrix3x2F::Identity())
, m_bVisiable(true) , m_bVisiable(true)
, m_pParent(nullptr) , m_pParent(nullptr)
, m_pParentScene(nullptr) , m_pParentScene(nullptr)
, m_nHashName(0) , m_nHashName(0)
, m_bSortNeeded(false) , m_bSortChildrenNeeded(false)
, m_bTransformNeeded(false) , m_bTransformChildrenNeeded(false)
{ {
} }
@ -35,14 +37,17 @@ e2d::ENode::~ENode()
{ {
} }
void e2d::ENode::callOn() void e2d::ENode::_callOn()
{ {
if (!m_bVisiable) if (!m_bVisiable)
{ {
return; return;
} }
this->_transfrom(); if (m_bTransformChildrenNeeded)
{
_updateTransform(this);
}
if (!m_vChildren.empty()) if (!m_vChildren.empty())
{ {
@ -56,7 +61,7 @@ void e2d::ENode::callOn()
// 访问 Order 小于零的节点 // 访问 Order 小于零的节点
if (child->getOrder() < 0) if (child->getOrder() < 0)
{ {
child->callOn(); child->_callOn();
} }
else else
{ {
@ -70,7 +75,7 @@ void e2d::ENode::callOn()
// 访问剩余节点 // 访问剩余节点
for (; i < size; i++) for (; i < size; i++)
m_vChildren[i]->callOn(); m_vChildren[i]->_callOn();
} }
else else
{ {
@ -86,7 +91,7 @@ void e2d::ENode::_onRender()
void e2d::ENode::_sortChildren() void e2d::ENode::_sortChildren()
{ {
if (m_bSortNeeded) if (m_bSortChildrenNeeded)
{ {
// 子节点排序 // 子节点排序
std::sort( std::sort(
@ -97,34 +102,75 @@ void e2d::ENode::_sortChildren()
} }
); );
m_bSortNeeded = false; m_bSortChildrenNeeded = false;
} }
} }
void e2d::ENode::_transfrom() void e2d::ENode::_updateTransformToReal()
{ {
if (m_bTransformNeeded) // 计算锚点坐标
{ D2D1_POINT_2F anchorPos = D2D1::Point2F(
m_fWidth * m_fAnchorX,
m_fHeight * m_fAnchorY
);
// 计算左上角坐标
D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(
m_fPosX - m_fWidth * m_fAnchorX,
m_fPosY - m_fHeight * m_fAnchorY
);
// 二维矩形变换 // 二维矩形变换
m_Matri = D2D1::Matrix3x2F::Identity(); m_Matri = D2D1::Matrix3x2F::Scale(
m_Matri = m_Matri.Translation(m_fPosX, m_fPosY); m_fScaleX,
m_Matri = m_Matri.Rotation(m_fRotation); m_fScaleY,
m_Matri = m_Matri.Scale(m_fScaleX, m_fScaleY); anchorPos
m_Matri = m_Matri.Skew(m_fSkewAngleX, m_fSkewAngleY); ) * D2D1::Matrix3x2F::Rotation(
m_fRotation,
anchorPos
) * D2D1::Matrix3x2F::Skew(
m_fSkewAngleX,
m_fSkewAngleY,
anchorPos
) * D2D1::Matrix3x2F::Translation(
upperLeftCorner.x,
upperLeftCorner.y
);
}
if (m_pParent) void e2d::ENode::_updateChildrenTransform()
{ {
//m_Matri.SetProduct()
}
// Ìáʾ×Ó½Úµã¸üÐÂÊôÐÔ
for (const auto &child : m_vChildren) for (const auto &child : m_vChildren)
{ {
child->m_bTransformNeeded = true; _updateTransform(child);
} }
}
m_bTransformNeeded = false; void e2d::ENode::_updateTransform(ENode * node)
{
node->_updateTransformToReal();
if (node->m_pParent)
{
node->m_Matri = node->m_Matri * node->m_pParent->m_Matri;
} }
// 遍历子节点下的所有节点
node->_updateChildrenTransform();
node->m_bTransformChildrenNeeded = false;
}
void e2d::ENode::_updateChildrenOpacity()
{
for (const auto &child : m_vChildren)
{
_updateOpacity(child);
}
}
void e2d::ENode::_updateOpacity(ENode * node)
{
if (node->m_pParent)
{
node->m_fDisplayOpacity = node->m_fRealOpacity * node->m_pParent->m_fDisplayOpacity;
}
node->_updateChildrenOpacity();
} }
bool e2d::ENode::isVisiable() const bool e2d::ENode::isVisiable() const
@ -179,7 +225,7 @@ float e2d::ENode::getRotation() const
float e2d::ENode::getOpacity() const float e2d::ENode::getOpacity() const
{ {
return m_fDisplayOpacity; return m_fRealOpacity;
} }
int e2d::ENode::getOrder() const int e2d::ENode::getOrder() const
@ -207,10 +253,9 @@ void e2d::ENode::setPos(float x, float y)
if (m_fPosX == x && m_fPosY == y) if (m_fPosX == x && m_fPosY == y)
return; return;
//m_Matri.Translation(x, y);
m_fPosX = x; m_fPosX = x;
m_fPosY = y; m_fPosY = y;
m_bTransformNeeded = true; m_bTransformChildrenNeeded = true;
} }
void e2d::ENode::move(float x, float y) void e2d::ENode::move(float x, float y)
@ -235,6 +280,7 @@ void e2d::ENode::setSize(float width, float height)
m_fWidth = width; m_fWidth = width;
m_fHeight = height; m_fHeight = height;
m_bTransformChildrenNeeded = true;
} }
void e2d::ENode::setScaleX(float scaleX) void e2d::ENode::setScaleX(float scaleX)
@ -257,10 +303,9 @@ void e2d::ENode::setScale(float scaleX, float scaleY)
if (m_fScaleX == scaleX && m_fScaleY == scaleY) if (m_fScaleX == scaleX && m_fScaleY == scaleY)
return; return;
//m_Matri.Scale(scaleX, scaleY);
m_fScaleX = scaleX; m_fScaleX = scaleX;
m_fScaleY = scaleY; m_fScaleY = scaleY;
m_bTransformNeeded = true; m_bTransformChildrenNeeded = true;
} }
void e2d::ENode::setSkewX(float angleX) void e2d::ENode::setSkewX(float angleX)
@ -278,10 +323,9 @@ void e2d::ENode::setSkew(float angleX, float angleY)
if (m_fSkewAngleX == angleX && m_fSkewAngleY == angleY) if (m_fSkewAngleX == angleX && m_fSkewAngleY == angleY)
return; return;
//m_Matri.Skew(angleX, angleY);
m_fSkewAngleX = angleX; m_fSkewAngleX = angleX;
m_fSkewAngleY = angleY; m_fSkewAngleY = angleY;
m_bTransformNeeded = true; m_bTransformChildrenNeeded = true;
} }
void e2d::ENode::setRotation(float angle) void e2d::ENode::setRotation(float angle)
@ -289,14 +333,38 @@ void e2d::ENode::setRotation(float angle)
if (m_fRotation == angle) if (m_fRotation == angle)
return; return;
//m_Matri.Rotation(angle);
m_fRotation = angle; m_fRotation = angle;
m_bTransformNeeded = true; m_bTransformChildrenNeeded = true;
} }
void e2d::ENode::setOpacity(float opacity) void e2d::ENode::setOpacity(float opacity)
{ {
m_fDisplayOpacity = m_fRealOpacity = opacity; if (m_fRealOpacity == opacity)
return;
m_fDisplayOpacity = m_fRealOpacity = min(max(opacity, 0), 1);
// 更新子节点透明度
_updateChildrenOpacity();
}
void e2d::ENode::setAnchorX(float anchorX)
{
this->setAnchor(anchorX, m_fAnchorY);
}
void e2d::ENode::setAnchorY(float anchorY)
{
this->setAnchor(m_fAnchorX, anchorY);
}
void e2d::ENode::setAnchor(float anchorX, float anchorY)
{
if (m_fAnchorX == anchorX && m_fAnchorY == anchorY)
return;
m_fAnchorX = min(max(anchorX, 0), 1);
m_fAnchorY = min(max(anchorY, 0), 1);
m_bTransformChildrenNeeded = true;
} }
void e2d::ENode::setParent(ENode * parent) void e2d::ENode::setParent(ENode * parent)
@ -325,13 +393,15 @@ void e2d::ENode::addChild(ENode * child, int order /* = 0 */)
m_vChildren.push_back(child); m_vChildren.push_back(child);
child->m_pParent = this;
child->setOrder(order); child->setOrder(order);
child->retain(); child->retain();
m_bSortNeeded = true; child->m_pParent = this;
_updateOpacity(child);
m_bSortChildrenNeeded = true;
} }
} }

289
Easy2D/Node/ESprite.cpp Normal file
View File

@ -0,0 +1,289 @@
#include "..\enodes.h"
#include <map>
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
//static std::map<size_t, size_t, ID2D1Bitmap*> s_mBitmapsFromResource;
static ID2D1Bitmap * GetBitmapFromFile(e2d::EString fileName);
static ID2D1Bitmap * GetBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType);
static bool _loadBitmapFromFile(e2d::EString fileName);
static bool _loadBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType);
e2d::ESprite::ESprite()
{
}
e2d::ESprite::ESprite(EString imageFileName)
: ESprite()
{
setImage(imageFileName);
}
e2d::ESprite::ESprite(EString resourceName, EString resourceType)
: ESprite()
{
setImage(resourceName, resourceType);
}
void e2d::ESprite::setImage(EString fileName)
{
WARN_IF(fileName.empty(), "ESprite cannot load bitmap from NULL file name.");
if (fileName.empty() || m_sFileName == fileName)
return;
m_sFileName = fileName;
SafeReleaseInterface(&pBitmap);
pBitmap = GetBitmapFromFile(m_sFileName);
ASSERT(pBitmap, "ESprite create device resources failed!");
this->setSize(pBitmap->GetSize().width, pBitmap->GetSize().height);
}
void e2d::ESprite::setImage(EString resourceName, EString resourceType)
{
WARN_IF(resourceName.empty() || resourceType.empty(), "ESprite cannot load bitmap from NULL resource.");
if (resourceName.empty() || resourceType.empty())
return;
if (m_sResourceName == resourceName && m_sResourceType == resourceType)
return;
if (!m_sFileName.empty())
m_sFileName.clear();
m_sResourceName = resourceName;
m_sResourceType = resourceType;
SafeReleaseInterface(&pBitmap);
pBitmap = GetBitmapFromResource(resourceName, resourceType);
ASSERT(pBitmap, "ESprite create device resources failed!");
this->setSize(pBitmap->GetSize().width, pBitmap->GetSize().height);
}
void e2d::ESprite::_onRender()
{
if (pBitmap)
{
// Draw bitmap
GetRenderTarget()->DrawBitmap(
pBitmap,
D2D1::RectF(0, 0, m_fWidth, m_fHeight),
m_fDisplayOpacity
);
}
}
bool _loadBitmapFromFile(e2d::EString fileName)
{
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
hr = GetImagingFactory()->CreateDecoderFromFilename(
fileName.c_str(),
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// Create a Direct2D bitmap from the WIC bitmap.
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
std::hash<e2d::EString> h;
size_t hash = h(fileName);
s_mBitmapsFromFile.insert(
std::map<size_t, ID2D1Bitmap*>::value_type(
hash,
pBitmap)
);
}
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
return SUCCEEDED(hr);
}
bool _loadBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType)
{
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
IWICBitmapScaler *pScaler = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
HRSRC imageResHandle = nullptr;
HGLOBAL imageResDataHandle = nullptr;
void *pImageFile = nullptr;
DWORD imageFileSize = 0;
// Locate the resource.
imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName.c_str(), resourceType.c_str());
hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// Load the resource.
imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageResDataHandle ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// Lock it to get a system memory pointer.
pImageFile = LockResource(imageResDataHandle);
hr = pImageFile ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// Calculate the size.
imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageFileSize ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// Create a WIC stream to map onto the memory.
hr = GetImagingFactory()->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
// Initialize the stream with the memory pointer and size.
hr = pStream->InitializeFromMemory(
reinterpret_cast<BYTE*>(pImageFile),
imageFileSize
);
}
if (SUCCEEDED(hr))
{
// Create a decoder for the stream.
hr = GetImagingFactory()->CreateDecoderFromStream(
pStream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
if (SUCCEEDED(hr))
{
// Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = GetImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
//create a Direct2D bitmap from the WIC bitmap.
hr = GetRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
SafeReleaseInterface(&pScaler);
return SUCCEEDED(hr);
}
ID2D1Bitmap * GetBitmapFromFile(e2d::EString fileName)
{
std::hash<e2d::EString> h;
size_t hash = h(fileName);
if (s_mBitmapsFromFile.find(hash) == s_mBitmapsFromFile.end())
{
if (!_loadBitmapFromFile(fileName))
{
return nullptr;
}
}
return s_mBitmapsFromFile.at(hash);
}
ID2D1Bitmap * GetBitmapFromResource(e2d::EString resourceName, e2d::EString resourceType)
{
return nullptr;
}

View File

@ -4,6 +4,7 @@ HWND hwnd = nullptr;
ID2D1Factory * pDirect2dFactory = nullptr; ID2D1Factory * pDirect2dFactory = nullptr;
ID2D1HwndRenderTarget * pRenderTarget = nullptr; ID2D1HwndRenderTarget * pRenderTarget = nullptr;
ID2D1SolidColorBrush * m_pSolidBrush = nullptr; ID2D1SolidColorBrush * m_pSolidBrush = nullptr;
IWICImagingFactory * pIWICFactory = nullptr;
HWND &GetHWnd() HWND &GetHWnd()
@ -16,12 +17,47 @@ ID2D1Factory * &GetFactory()
return pDirect2dFactory; return pDirect2dFactory;
} }
IWICImagingFactory * &GetImagingFactory()
{
if (!pIWICFactory)
{
CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
reinterpret_cast<void **>(&pIWICFactory)
);
}
return pIWICFactory;
}
ID2D1HwndRenderTarget * &GetRenderTarget() ID2D1HwndRenderTarget * &GetRenderTarget()
{ {
if (!pRenderTarget)
{
RECT rc;
GetClientRect(hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// Create a Direct2D render target.
HRESULT hr;
hr = pDirect2dFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hwnd, size),
&pRenderTarget
);
ASSERT(SUCCEEDED(hr), "Create Render Target Failed!");
}
return pRenderTarget; return pRenderTarget;
} }
ID2D1SolidColorBrush *& GetSolidColorBrush() ID2D1SolidColorBrush * &GetSolidColorBrush()
{ {
if (!m_pSolidBrush) if (!m_pSolidBrush)
{ {

View File

@ -6,7 +6,14 @@
#include <wincodec.h> #include <wincodec.h>
#pragma comment(lib, "d2d1.lib") #pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "dwrite.lib") #pragma comment(lib, "dwrite.lib")
//#pragma comment(lib, "wincodec.lib") #pragma comment(lib, "windowscodecs.lib")
#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif
HWND &GetHWnd(); HWND &GetHWnd();
@ -16,6 +23,7 @@ ID2D1HwndRenderTarget * &GetRenderTarget();
ID2D1SolidColorBrush * &GetSolidColorBrush(); ID2D1SolidColorBrush * &GetSolidColorBrush();
IWICImagingFactory * &GetImagingFactory();
template<class Interface> template<class Interface>
inline void SafeReleaseInterface( inline void SafeReleaseInterface(

View File

@ -212,6 +212,12 @@ protected:
// 子节点排序 // 子节点排序
void _sortChildren(); void _sortChildren();
// 进入场景时需调用该函数
virtual void _onEnter();
// 退出场景时需调用该函数
virtual void _onExit();
protected: protected:
bool m_bSortNeeded; bool m_bSortNeeded;
bool m_bWillSave; bool m_bWillSave;

View File

@ -26,6 +26,8 @@ typedef struct
typedef std::function<void()> KEY_LISTENER_CALLBACK; typedef std::function<void()> KEY_LISTENER_CALLBACK;
typedef std::function<void()> MOUSE_LISTENER_CALLBACK; typedef std::function<void()> MOUSE_LISTENER_CALLBACK;
typedef std::function<void(EPoint mousePos)> MOUSE_CLICK_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; typedef std::function<void(EPoint begin, EPoint end)> MOUSE_DRAG_LISTENER_CALLBACK;

View File

@ -22,6 +22,11 @@
#include <windows.h> #include <windows.h>
#include <assert.h> #include <assert.h>
// C RunTime Header Files
#include <wchar.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef ASSERT_IF #ifndef ASSERT_IF
#if defined( DEBUG ) || defined( _DEBUG ) #if defined( DEBUG ) || defined( _DEBUG )

View File

@ -244,6 +244,39 @@ protected:
}; };
// 鼠标按下消息监听器
class EMousePressListener :
public EMouseListener
{
public:
EMousePressListener();
EMousePressListener(
EString name
);
EMousePressListener(
const MOUSE_PRESS_LISTENER_CALLBACK &callback
);
EMousePressListener(
EString name,
const MOUSE_PRESS_LISTENER_CALLBACK &callback
);
// 执行监听器回调函数
virtual void runCallback() override;
// 设置监听器回调函数
void setCallback(
const MOUSE_PRESS_LISTENER_CALLBACK &callback
);
protected:
MOUSE_PRESS_LISTENER_CALLBACK m_callback;
};
// 鼠标点击消息监听器 // 鼠标点击消息监听器
class EMouseClickListener : class EMouseClickListener :
public EMouseListener public EMouseListener
@ -273,26 +306,61 @@ public:
); );
protected: protected:
bool m_bPressed;
MOUSE_CLICK_LISTENER_CALLBACK m_callback; MOUSE_CLICK_LISTENER_CALLBACK m_callback;
}; };
// 鼠标拖动消息监听器 // 鼠标点击消息监听器
class EMouseDraggedListener : class EMouseDoubleClickListener :
public EMouseListener public EMouseListener
{ {
public: public:
EMouseDraggedListener(); EMouseDoubleClickListener();
EMouseDraggedListener( EMouseDoubleClickListener(
EString name EString name
); );
EMouseDraggedListener( EMouseDoubleClickListener(
const MOUSE_DBLCLK_LISTENER_CALLBACK &callback
);
EMouseDoubleClickListener(
EString name,
const MOUSE_DBLCLK_LISTENER_CALLBACK &callback
);
// 执行监听器回调函数
virtual void runCallback() override;
// 设置监听器回调函数
void setCallback(
const MOUSE_DBLCLK_LISTENER_CALLBACK &callback
);
protected:
bool m_bPressed;
MOUSE_DBLCLK_LISTENER_CALLBACK m_callback;
};
// 鼠标拖动消息监听器
class EMouseDragListener :
public EMouseListener
{
public:
EMouseDragListener();
EMouseDragListener(
EString name
);
EMouseDragListener(
const MOUSE_DRAG_LISTENER_CALLBACK &callback const MOUSE_DRAG_LISTENER_CALLBACK &callback
); );
EMouseDraggedListener( EMouseDragListener(
EString name, EString name,
const MOUSE_DRAG_LISTENER_CALLBACK &callback const MOUSE_DRAG_LISTENER_CALLBACK &callback
); );
@ -307,7 +375,6 @@ public:
protected: protected:
EPoint m_Begin; EPoint m_Begin;
EPoint m_End;
MOUSE_DRAG_LISTENER_CALLBACK m_callback; MOUSE_DRAG_LISTENER_CALLBACK m_callback;
}; };

View File

@ -8,6 +8,8 @@ namespace e2d
class ENode : class ENode :
public EObject public EObject
{ {
friend EScene;
public: public:
ENode(); ENode();
@ -35,10 +37,10 @@ public:
// 获取节点高度 // 获取节点高度
virtual float getHeight() const; virtual float getHeight() const;
// 获取节点横向缩放倍数 // 获取节点横向缩放比例
virtual float getScaleX() const; virtual float getScaleX() const;
// 获取节点纵向缩放倍数 // 获取节点纵向缩放比例
virtual float getScaleY() const; virtual float getScaleY() const;
// 获取节点横向倾斜角度 // 获取节点横向倾斜角度
@ -125,57 +127,86 @@ public:
); );
// 设置节点绘图顺序 // 设置节点绘图顺序
// 默认为 0
virtual void setOrder( virtual void setOrder(
int order int order
); );
// 设置横向缩放 // 设置横向缩放比例
// 默认为 1.0f
virtual void setScaleX( virtual void setScaleX(
float scaleX float scaleX
); );
// 设置纵向缩放 // 设置纵向缩放比例
// 默认为 1.0f
virtual void setScaleY( virtual void setScaleY(
float scaleY float scaleY
); );
// 设置缩放 // 设置缩放比例
// 默认为 (1.0f, 1.0f)
virtual void setScale( virtual void setScale(
float scaleX, float scaleX,
float scaleY float scaleY
); );
// 设置缩放 // 设置缩放比例
// 默认为 1.0f
virtual void setScale( virtual void setScale(
float scale float scale
); );
// 设置横向倾斜角度 // 设置横向倾斜角度
// 默认为 0
virtual void setSkewX( virtual void setSkewX(
float angleX float angleX
); );
// 设置纵向倾斜角度 // 设置纵向倾斜角度
// 默认为 0
virtual void setSkewY( virtual void setSkewY(
float angleY float angleY
); );
// 设置倾斜角度 // 设置倾斜角度
// 默认为 (0, 0)
virtual void setSkew( virtual void setSkew(
float angleX, float angleX,
float angleY float angleY
); );
// 设置旋转角度 // 设置旋转角度
// 默认为 0
virtual void setRotation( virtual void setRotation(
float rotation float rotation
); );
// 设置透明度 // 设置透明度
// 默认为 1.0f, 范围 [0, 1]
virtual void setOpacity( virtual void setOpacity(
float opacity float opacity
); );
// 设置纵向锚点
// 默认为 0, 范围 [0, 1]
virtual void setAnchorX(
float anchorX
);
// 设置横向锚点
// 默认为 0, 范围 [0, 1]
virtual void setAnchorY(
float anchorY
);
// 设置锚点
// 默认为 (0, 0), 范围 [0, 1]
virtual void setAnchor(
float anchorX,
float anchorY
);
// 设置节点所在场景 // 设置节点所在场景
virtual void setParentScene( virtual void setParentScene(
EScene * scene EScene * scene
@ -209,18 +240,30 @@ public:
bool release = false bool release = false
); );
// 访问节点
virtual void callOn();
protected: protected:
// 访问节点
virtual void _callOn();
// 渲染节点 // 渲染节点
virtual void _onRender(); virtual void _onRender();
// 子节点排序 // 子节点排序
void _sortChildren(); void _sortChildren();
// 节点状态转换 // 只考虑自身进行二维矩阵变换
void _transfrom(); void _updateTransformToReal();
// 更新所有子节点矩阵
void _updateChildrenTransform();
// 更新所有子节点透明度
void _updateChildrenOpacity();
// 更新节点矩阵
static void _updateTransform(ENode * node);
// 更新节点透明度
static void _updateOpacity(ENode * node);
protected: protected:
EString m_sName; EString m_sName;
@ -236,11 +279,13 @@ protected:
float m_fSkewAngleY; float m_fSkewAngleY;
float m_fDisplayOpacity; float m_fDisplayOpacity;
float m_fRealOpacity; float m_fRealOpacity;
float m_fAnchorX;
float m_fAnchorY;
D2D1::Matrix3x2F m_Matri; D2D1::Matrix3x2F m_Matri;
int m_nOrder; int m_nOrder;
bool m_bVisiable; bool m_bVisiable;
bool m_bSortNeeded; bool m_bSortChildrenNeeded;
bool m_bTransformNeeded; bool m_bTransformChildrenNeeded;
EScene * m_pParentScene; EScene * m_pParentScene;
ENode * m_pParent; ENode * m_pParent;
std::vector<ENode*> m_vChildren; std::vector<ENode*> m_vChildren;
@ -264,4 +309,29 @@ protected:
EColor::Enum m_Color; EColor::Enum m_Color;
}; };
class ESprite :
public ENode
{
public:
ESprite();
ESprite(EString imageFileName);
ESprite(EString resourceName, EString resourceType);
void setImage(EString fileName);
void setImage(EString resourceName, EString resourceType);
protected:
virtual void _onRender() override;
protected:
EString m_sFileName;
EString m_sResourceName;
EString m_sResourceType;
ID2D1Bitmap * pBitmap;
};
} }