修复了若干BUG

This commit is contained in:
Nomango 2017-10-21 19:09:31 +08:00
parent 4e803de6a9
commit 9fa60891a4
46 changed files with 1313 additions and 484 deletions

View File

@ -10,20 +10,11 @@ int WINAPI WinMain(
{ {
EApp app; EApp app;
if (app.init(L"Easy2D Demo", 640, 480, app.NO_CLOSE | app.NO_MINI_SIZE | app.TOP_MOST)) if (app.init(L"Easy2D Demo", 640, 480, app.NO_MINI_SIZE))
{ {
auto scene = new EScene(); auto scene = new EScene();
auto scene2 = new EScene();
auto listener = new EKeyboardPressListener([=]() { auto text = new EText(L"中文测试中文测试中文测试中文测试中文测试中文测试中文测试", EColor::WHITE, L"楷体");
if (EKeyboardMsg::getVal() == EKeyboardMsg::KEY::SPACE)
{
EApp::enterScene(scene, new ETransitionFade(2, 2));
}
});
listener->bindWith(scene2);
auto text = new EText(L"中文测试中文测试中文测试中文测试中文测试中文测试中文测试", EColor::WHITE, L"Microsoft Yahei");
text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2);
//text->setWordWrapping(true); //text->setWordWrapping(true);
//text->setWordWrappingWidth(130); //text->setWordWrappingWidth(130);
@ -31,9 +22,18 @@ int WINAPI WinMain(
text->getFont()->setItalic(true); text->getFont()->setItalic(true);
text->setAnchor(0.5f, 0.5f); text->setAnchor(0.5f, 0.5f);
text->setColor(EColor::WHITE); text->setColor(EColor::WHITE);
//text->runAction(new EActionLoop(new EActionTwo(new EActionFadeOut(1), new EActionFadeIn(1))));
scene->add(text); scene->add(text);
text->runAction(new EActionLoop(new EActionTwo(new EActionFadeOut(1), new EActionFadeIn(1)))); auto listener = new EKeyboardPressListener([=]() {
if (EKeyboardMsg::getVal() == EKeyboardMsg::KEY::SPACE)
{
EApp::backScene(new ETransitionFade(0.5f, 0.5f));
}
});
listener->bindWith(scene);
auto scene2 = new EScene();
auto bird = new ESprite(); auto bird = new ESprite();
auto animation = new EAnimation(); auto animation = new EAnimation();
@ -45,15 +45,26 @@ int WINAPI WinMain(
bird->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); bird->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2);
scene2->add(bird); scene2->add(bird);
auto listener2 = new EKeyboardPressListener([=]() { auto btnStart = new ESprite(L"atlas.png", 702, 234, 116, 70);
if (EKeyboardMsg::getVal() == EKeyboardMsg::KEY::SPACE) btnStart->setAnchor(0.5f, 0.5f);
auto btnStartSelected = new ESprite(L"atlas.png", 702, 234, 116, 70);
btnStartSelected->setAnchor(0.5f, 0.5f);
btnStartSelected->setPosY(5);
auto button = new EButton(btnStart, btnStartSelected, [=] {
if (EApp::isPaused())
{ {
EApp::backScene(new ETransitionFade(0.5f, 0.5f)); EApp::resume();
} }
else
{
EApp::pause();
}
//EApp::enterScene(scene, new ETransitionScaleEmerge(1, ETransitionScaleEmerge::BACK));
}); });
listener2->bindWith(scene); button->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2 + 100);
scene2->add(button);
app.enterScene(scene2, new ETransitionFade(2, 4)); app.enterScene(scene2, new ETransitionFade(0, 1));
app.run(); app.run();
} }

View File

@ -75,10 +75,14 @@ e2d::ENode * e2d::EAction::getTarget()
void e2d::EAction::_init() void e2d::EAction::_init()
{ {
m_bInit = true; m_bInit = true;
// 记录当前时间
m_tLast = GetNow();
} }
void e2d::EAction::_reset() void e2d::EAction::_reset()
{ {
m_bInit = false; m_bInit = false;
m_bEnding = false; m_bEnding = false;
// 记录当前时间
m_tLast = GetNow();
} }

View File

@ -14,8 +14,6 @@ e2d::EActionDelay * e2d::EActionDelay::clone() const
void e2d::EActionDelay::_init() void e2d::EActionDelay::_init()
{ {
EAction::_init(); EAction::_init();
// 记录当前时间
m_tLast = GetNow();
} }
void e2d::EActionDelay::_callOn() void e2d::EActionDelay::_callOn()
@ -30,6 +28,4 @@ void e2d::EActionDelay::_callOn()
void e2d::EActionDelay::_reset() void e2d::EActionDelay::_reset()
{ {
EAction::_reset(); EAction::_reset();
// 记录当前时间
m_tLast = GetNow();
} }

View File

@ -2,21 +2,20 @@
#include "..\Win\winbase.h" #include "..\Win\winbase.h"
e2d::EActionGradual::EActionGradual(float duration) e2d::EActionGradual::EActionGradual(float duration)
: m_fRateOfProgress(0)
, m_fDuration(0)
, m_fTotalDuration(duration * 1000)
{ {
m_nDuration = 0;
m_nTotalDuration = UINT(duration * 1000);
} }
bool e2d::EActionGradual::_isEnd() const bool e2d::EActionGradual::_isEnd() const
{ {
return m_nDuration >= m_nTotalDuration; return m_fDuration >= m_fTotalDuration;
} }
void e2d::EActionGradual::_init() void e2d::EActionGradual::_init()
{ {
EAction::_init(); EAction::_init();
// 记录当前时间
m_tLast = GetNow();
} }
bool e2d::EActionGradual::_isDelayEnough() bool e2d::EActionGradual::_isDelayEnough()
@ -26,7 +25,9 @@ bool e2d::EActionGradual::_isDelayEnough()
{ {
// 重新记录时间 // 重新记录时间
m_tLast += milliseconds(m_nAnimationInterval); m_tLast += milliseconds(m_nAnimationInterval);
m_nDuration += m_nAnimationInterval; m_fDuration += static_cast<float>(m_nAnimationInterval);
// 计算动画进度
m_fRateOfProgress = m_fDuration / m_fTotalDuration;
return true; return true;
} }
return false; return false;
@ -35,7 +36,5 @@ bool e2d::EActionGradual::_isDelayEnough()
void e2d::EActionGradual::_reset() void e2d::EActionGradual::_reset()
{ {
EAction::_reset(); EAction::_reset();
m_nDuration = 0; m_fDuration = 0;
// 记录当前时间
m_tLast = GetNow();
} }

View File

@ -8,7 +8,7 @@ e2d::EActionLoop::EActionLoop(EAction * action) :
e2d::EActionLoop::~EActionLoop() e2d::EActionLoop::~EActionLoop()
{ {
SafeRelease(&m_Action); SafeReleaseAndClear(&m_Action);
} }
e2d::EActionLoop * e2d::EActionLoop::clone() const e2d::EActionLoop * e2d::EActionLoop::clone() const

View File

@ -25,12 +25,10 @@ void e2d::EActionMoveBy::_callOn()
} }
while (EActionGradual::_isDelayEnough()) while (EActionGradual::_isDelayEnough())
{ {
// 计算移动位置 // 移动节点
float scale = static_cast<float>(m_nDuration) / m_nTotalDuration;
// 移动 Sprite
m_pTarget->setPos( m_pTarget->setPos(
m_BeginPos.x + m_MoveVector.x * scale, m_BeginPos.x + m_MoveVector.x * m_fRateOfProgress,
m_BeginPos.y + m_MoveVector.y * scale m_BeginPos.y + m_MoveVector.y * m_fRateOfProgress
); );
// 判断动作是否结束 // 判断动作是否结束
if (_isEnd()) if (_isEnd())
@ -48,10 +46,10 @@ void e2d::EActionMoveBy::_reset()
e2d::EActionMoveBy * e2d::EActionMoveBy::clone() const e2d::EActionMoveBy * e2d::EActionMoveBy::clone() const
{ {
return new EActionMoveBy(m_nAnimationInterval / 1000.0f, m_MoveVector); return new EActionMoveBy(m_fTotalDuration / 1000, m_MoveVector);
} }
e2d::EActionMoveBy * e2d::EActionMoveBy::reverse() const e2d::EActionMoveBy * e2d::EActionMoveBy::reverse() const
{ {
return new EActionMoveBy(m_nTotalDuration / 1000.0f, EVec(-m_MoveVector.x, -m_MoveVector.y)); return new EActionMoveBy(m_fTotalDuration / 1000, EVec(-m_MoveVector.x, -m_MoveVector.y));
} }

View File

@ -8,7 +8,7 @@ e2d::EActionMoveTo::EActionMoveTo(float duration, EPoint pos) :
e2d::EActionMoveTo * e2d::EActionMoveTo::clone() const e2d::EActionMoveTo * e2d::EActionMoveTo::clone() const
{ {
return new EActionMoveTo(m_nAnimationInterval / 1000.0f, m_EndPos); return new EActionMoveTo(m_fTotalDuration / 1000, m_EndPos);
} }
void e2d::EActionMoveTo::_init() void e2d::EActionMoveTo::_init()

View File

@ -25,10 +25,8 @@ void e2d::EActionOpacityBy::_callOn()
} }
while (EActionGradual::_isDelayEnough()) while (EActionGradual::_isDelayEnough())
{ {
// 计算移动位置 // 设置节点透明度
float scale = static_cast<float>(m_nDuration) / m_nTotalDuration; m_pTarget->setOpacity(m_nBeginVal + m_nVariation * m_fRateOfProgress);
// 移动 Sprite
m_pTarget->setOpacity(m_nBeginVal + m_nVariation * scale);
// 判断动作是否结束 // 判断动作是否结束
if (_isEnd()) if (_isEnd())
{ {
@ -45,10 +43,10 @@ void e2d::EActionOpacityBy::_reset()
e2d::EActionOpacityBy * e2d::EActionOpacityBy::clone() const e2d::EActionOpacityBy * e2d::EActionOpacityBy::clone() const
{ {
return new EActionOpacityBy(m_nAnimationInterval / 1000.0f, m_nVariation); return new EActionOpacityBy(m_fTotalDuration / 1000, m_nVariation);
} }
e2d::EActionOpacityBy * e2d::EActionOpacityBy::reverse() const e2d::EActionOpacityBy * e2d::EActionOpacityBy::reverse() const
{ {
return new EActionOpacityBy(m_nTotalDuration / 1000.0f, -m_nVariation); return new EActionOpacityBy(m_fTotalDuration / 1000, -m_nVariation);
} }

View File

@ -9,7 +9,7 @@ e2d::EActionOpacityTo::EActionOpacityTo(float duration, float opacity) :
e2d::EActionOpacityTo * e2d::EActionOpacityTo::clone() const e2d::EActionOpacityTo * e2d::EActionOpacityTo::clone() const
{ {
return new EActionOpacityTo(m_nAnimationInterval / 1000.0f, m_nEndVal); return new EActionOpacityTo(m_fTotalDuration / 1000, m_nEndVal);
} }
void e2d::EActionOpacityTo::_init() void e2d::EActionOpacityTo::_init()

View File

@ -25,10 +25,8 @@ void e2d::EActionRotateBy::_callOn()
} }
while (EActionGradual::_isDelayEnough()) while (EActionGradual::_isDelayEnough())
{ {
// 计算移动位置 // 旋转节点
float scale = static_cast<float>(m_nDuration) / m_nTotalDuration; m_pTarget->setRotation(m_nBeginVal + m_nVariation * m_fRateOfProgress);
// 移动 Sprite
m_pTarget->setRotation(m_nBeginVal + m_nVariation * scale);
// 判断动作是否结束 // 判断动作是否结束
if (_isEnd()) if (_isEnd())
{ {
@ -45,10 +43,10 @@ void e2d::EActionRotateBy::_reset()
e2d::EActionRotateBy * e2d::EActionRotateBy::clone() const e2d::EActionRotateBy * e2d::EActionRotateBy::clone() const
{ {
return new EActionRotateBy(m_nAnimationInterval / 1000.0f, m_nVariation); return new EActionRotateBy(m_fTotalDuration / 1000, m_nVariation);
} }
e2d::EActionRotateBy * e2d::EActionRotateBy::reverse() const e2d::EActionRotateBy * e2d::EActionRotateBy::reverse() const
{ {
return new EActionRotateBy(m_nTotalDuration / 1000.0f, -m_nVariation); return new EActionRotateBy(m_fTotalDuration / 1000, -m_nVariation);
} }

View File

@ -1,15 +1,15 @@
#include "..\eactions.h" #include "..\eactions.h"
e2d::EActionRotateTo::EActionRotateTo(float duration, float opacity) : e2d::EActionRotateTo::EActionRotateTo(float duration, float rotation) :
EActionRotateBy(duration, 0) EActionRotateBy(duration, 0)
{ {
m_nEndVal = opacity; m_nEndVal = rotation;
} }
e2d::EActionRotateTo * e2d::EActionRotateTo::clone() const e2d::EActionRotateTo * e2d::EActionRotateTo::clone() const
{ {
return new EActionRotateTo(m_nAnimationInterval / 1000.0f, m_nEndVal); return new EActionRotateTo(m_fTotalDuration / 1000, m_nEndVal);
} }
void e2d::EActionRotateTo::_init() void e2d::EActionRotateTo::_init()

View File

@ -1,8 +1,15 @@
#include "..\eactions.h" #include "..\eactions.h"
e2d::EActionScaleBy::EActionScaleBy(float duration, float scaleX, float scaleY) : e2d::EActionScaleBy::EActionScaleBy(float duration, float scale)
EActionGradual(duration) : EActionGradual(duration)
{
m_nVariationX = scale;
m_nVariationY = scale;
}
e2d::EActionScaleBy::EActionScaleBy(float duration, float scaleX, float scaleY)
: EActionGradual(duration)
{ {
m_nVariationX = scaleX; m_nVariationX = scaleX;
m_nVariationY = scaleY; m_nVariationY = scaleY;
@ -27,10 +34,10 @@ void e2d::EActionScaleBy::_callOn()
} }
while (EActionGradual::_isDelayEnough()) while (EActionGradual::_isDelayEnough())
{ {
// 计算移动位置 // Ëõ·Å½Úµã
float scale = static_cast<float>(m_nDuration) / m_nTotalDuration; m_pTarget->setScale(
// 移动 Sprite m_nBeginScaleX + m_nVariationX * m_fRateOfProgress,
m_pTarget->setScale(m_nBeginScaleX + m_nVariationX * scale, m_nBeginScaleX + m_nVariationX * scale); m_nBeginScaleX + m_nVariationX * m_fRateOfProgress);
// 判断动作是否结束 // 判断动作是否结束
if (_isEnd()) if (_isEnd())
{ {
@ -47,10 +54,10 @@ void e2d::EActionScaleBy::_reset()
e2d::EActionScaleBy * e2d::EActionScaleBy::clone() const e2d::EActionScaleBy * e2d::EActionScaleBy::clone() const
{ {
return new EActionScaleBy(m_nAnimationInterval / 1000.0f, m_nVariationX, m_nVariationY); return new EActionScaleBy(m_fTotalDuration / 1000, m_nVariationX, m_nVariationY);
} }
e2d::EActionScaleBy * e2d::EActionScaleBy::reverse() const e2d::EActionScaleBy * e2d::EActionScaleBy::reverse() const
{ {
return new EActionScaleBy(m_nTotalDuration / 1000.0f, -m_nVariationX, -m_nVariationY); return new EActionScaleBy(m_fTotalDuration / 1000, -m_nVariationX, -m_nVariationY);
} }

View File

@ -1,7 +1,14 @@
#include "..\eactions.h" #include "..\eactions.h"
e2d::EActionScaleTo::EActionScaleTo(float duration, float scaleX, float scaleY) : e2d::EActionScaleTo::EActionScaleTo(float duration, float scale)
EActionScaleBy(duration, 0, 0) : EActionScaleBy(duration, 0, 0)
{
m_nEndScaleX = scale;
m_nEndScaleY = scale;
}
e2d::EActionScaleTo::EActionScaleTo(float duration, float scaleX, float scaleY)
: EActionScaleBy(duration, 0, 0)
{ {
m_nEndScaleX = scaleX; m_nEndScaleX = scaleX;
m_nEndScaleY = scaleY; m_nEndScaleY = scaleY;
@ -9,7 +16,7 @@ e2d::EActionScaleTo::EActionScaleTo(float duration, float scaleX, float scaleY)
e2d::EActionScaleTo * e2d::EActionScaleTo::clone() const e2d::EActionScaleTo * e2d::EActionScaleTo::clone() const
{ {
return new EActionScaleTo(m_nAnimationInterval / 1000.0f, m_nEndScaleX, m_nEndScaleY); return new EActionScaleTo(m_fTotalDuration / 1000, m_nEndScaleX, m_nEndScaleY);
} }
void e2d::EActionScaleTo::_init() void e2d::EActionScaleTo::_init()

View File

@ -25,7 +25,7 @@ e2d::EActionSequence::~EActionSequence()
{ {
for (auto action : m_vActions) for (auto action : m_vActions)
{ {
SafeRelease(&action); SafeReleaseAndClear(&action);
} }
} }
@ -49,9 +49,10 @@ void e2d::EActionSequence::_init()
void e2d::EActionSequence::_callOn() void e2d::EActionSequence::_callOn()
{ {
m_vActions[m_nActionIndex]->_callOn(); auto &action = m_vActions[m_nActionIndex];
action->_callOn();
if (m_vActions[m_nActionIndex]->_isEnding()) if (action->_isEnding())
{ {
m_nActionIndex++; m_nActionIndex++;
if (m_nActionIndex == m_vActions.size()) if (m_nActionIndex == m_vActions.size())

View File

@ -10,8 +10,8 @@ e2d::EActionTwo::EActionTwo(EAction * actionFirst, EAction * actionSecond) :
e2d::EActionTwo::~EActionTwo() e2d::EActionTwo::~EActionTwo()
{ {
SafeRelease(&m_pFirstAction); SafeReleaseAndClear(&m_pFirstAction);
SafeRelease(&m_pSecondAction); SafeReleaseAndClear(&m_pSecondAction);
} }
e2d::EActionTwo * e2d::EActionTwo::clone() const e2d::EActionTwo * e2d::EActionTwo::clone() const

View File

@ -10,8 +10,8 @@ e2d::EActionTwoAtSameTime::EActionTwoAtSameTime(EAction * actionFirst, EAction *
e2d::EActionTwoAtSameTime::~EActionTwoAtSameTime() e2d::EActionTwoAtSameTime::~EActionTwoAtSameTime()
{ {
SafeRelease(&m_pFirstAction); SafeReleaseAndClear(&m_pFirstAction);
SafeRelease(&m_pSecondAction); SafeReleaseAndClear(&m_pSecondAction);
} }
e2d::EActionTwoAtSameTime * e2d::EActionTwoAtSameTime::clone() const e2d::EActionTwoAtSameTime * e2d::EActionTwoAtSameTime::clone() const

View File

@ -19,20 +19,13 @@ e2d::EAnimation::~EAnimation()
{ {
for (auto frame : m_vFrames) for (auto frame : m_vFrames)
{ {
SafeRelease(&frame); SafeReleaseAndClear(&frame);
} }
} }
void e2d::EAnimation::_init() void e2d::EAnimation::_init()
{ {
// 判断执行帧动画的目标类型是否是 ESprite
ASSERT(
typeid(ESprite) == typeid(*m_pTarget),
"Only ESprite can use EAnimation!"
);
EAction::_init(); EAction::_init();
// 记录当前时间
m_tLast = GetNow();
} }
void e2d::EAnimation::_callOn() void e2d::EAnimation::_callOn()
@ -47,7 +40,8 @@ void e2d::EAnimation::_callOn()
{ {
// 重新记录时间 // 重新记录时间
m_tLast += milliseconds(m_nAnimationInterval); m_tLast += milliseconds(m_nAnimationInterval);
reinterpret_cast<ESprite*>(m_pTarget)->loadFromSpriteFrame(m_vFrames[m_nFrameIndex]); // ¼ÓÔØ¾«ÁéÖ¡
reinterpret_cast<ESprite*>(m_pTarget)->loadFrom(m_vFrames[m_nFrameIndex]);
m_nFrameIndex++; m_nFrameIndex++;
// 判断动作是否结束 // 判断动作是否结束
if (m_nFrameIndex == m_vFrames.size()) if (m_nFrameIndex == m_vFrames.size())
@ -62,8 +56,6 @@ void e2d::EAnimation::_reset()
{ {
EAction::_reset(); EAction::_reset();
m_nFrameIndex = 0; m_nFrameIndex = 0;
// 记录当前时间
m_tLast = steady_clock::now();
} }
void e2d::EAnimation::addFrame(ESpriteFrame * frame) void e2d::EAnimation::addFrame(ESpriteFrame * frame)

View File

@ -25,7 +25,6 @@ e2d::EApp::EApp()
, m_bPaused(false) , m_bPaused(false)
, m_bManualPaused(false) , m_bManualPaused(false)
, m_bTransitional(false) , m_bTransitional(false)
, m_bEnterNextScene(true)
, m_bTopMost(false) , m_bTopMost(false)
, nAnimationInterval(17LL) , nAnimationInterval(17LL)
, m_ClearColor(EColor::BLACK) , m_ClearColor(EColor::BLACK)
@ -58,10 +57,10 @@ e2d::EApp * e2d::EApp::get()
bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, bool showConsole /* = false */) bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, bool showConsole /* = false */)
{ {
return init(title, width, height, 0, showConsole); return init(title, width, height, EWindowStyle(), showConsole);
} }
bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int windowStyle, bool showConsole /* = false */) bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, EWindowStyle wStyle, bool showConsole /* = false */)
{ {
HRESULT hr; HRESULT hr;
@ -76,7 +75,7 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind
// 注册窗口类 // 注册窗口类
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) }; WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
UINT style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; UINT style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
if (windowStyle & EApp::NO_CLOSE) if (wStyle.NO_CLOSE)
{ {
style |= CS_NOCLOSE; style |= CS_NOCLOSE;
} }
@ -89,6 +88,10 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind
wcex.lpszMenuName = NULL; wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = L"Easy2DApp"; wcex.lpszClassName = L"Easy2DApp";
if (wStyle.ICON_ID)
{
wcex.hIcon = (HICON)::LoadImage(GetModuleHandle(NULL), wStyle.ICON_ID, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
}
RegisterClassEx(&wcex); RegisterClassEx(&wcex);
@ -119,14 +122,12 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind
rtWindow.bottom = rtWindow.top + height; rtWindow.bottom = rtWindow.top + height;
// 创建窗口样式 // 创建窗口样式
DWORD dwStyle = WS_OVERLAPPED | WS_SYSMENU; DWORD dwStyle = WS_OVERLAPPED | WS_SYSMENU;
if (windowStyle & EApp::NO_MINI_SIZE) if (!wStyle.NO_MINI_SIZE)
{ {
dwStyle &= ~WS_MINIMIZEBOX; dwStyle |= WS_MINIMIZEBOX;
}
if (windowStyle & EApp::TOP_MOST)
{
m_bTopMost = true;
} }
// 保存窗口是否置顶显示
m_bTopMost = wStyle.TOP_MOST;
// 计算客户区大小 // 计算客户区大小
AdjustWindowRectEx(&rtWindow, dwStyle, FALSE, 0L); AdjustWindowRectEx(&rtWindow, dwStyle, FALSE, 0L);
// 保存窗口名称 // 保存窗口名称
@ -178,6 +179,9 @@ void e2d::EApp::resume()
{ {
EApp::get()->m_bPaused = false; EApp::get()->m_bPaused = false;
EApp::get()->m_bManualPaused = false; EApp::get()->m_bManualPaused = false;
// 刷新当前时间
GetNow() = steady_clock::now();
// 重置动画和定时器
EActionManager::_resetAllActions(); EActionManager::_resetAllActions();
ETimerManager::_resetAllTimers(); ETimerManager::_resetAllTimers();
} }
@ -298,9 +302,10 @@ void e2d::EApp::_mainLoop()
static LONGLONG nInterval = 0LL; static LONGLONG nInterval = 0LL;
// 挂起时长 // 挂起时长
static LONGLONG nWaitMS = 0L; static LONGLONG nWaitMS = 0L;
// 刷新计时 // 上一帧画面绘制时间
static steady_clock::time_point tLast = steady_clock::now(); static steady_clock::time_point tLast = steady_clock::now();
// 刷新当前时间
GetNow() = steady_clock::now(); GetNow() = steady_clock::now();
// 计算时间间隔 // 计算时间间隔
nInterval = GetInterval(tLast); nInterval = GetInterval(tLast);
@ -308,7 +313,7 @@ void e2d::EApp::_mainLoop()
if (nInterval >= nAnimationInterval) if (nInterval >= nAnimationInterval)
{ {
// 记录当前时间 // 记录当前时间
tLast = GetNow(); tLast += microseconds(nAnimationInterval);
// 游戏控制流程 // 游戏控制流程
_onControl(); _onControl();
// 刷新游戏画面 // 刷新游戏画面
@ -328,19 +333,22 @@ void e2d::EApp::_mainLoop()
void e2d::EApp::_onControl() void e2d::EApp::_onControl()
{ {
// 下一场景指针不为空时,切换场景 // 正在切换场景时,执行场景切换动画
if (m_bEnterNextScene)
{
// 进入下一场景
_enterNextScene();
m_bEnterNextScene = false;
}
// 正在切换场景时,只执行动画
if (m_bTransitional) if (m_bTransitional)
{ {
EActionManager::ActionProc(); EActionManager::ActionProc();
return; // 若场景切换未结束,不执行后面的部分
if (m_bTransitional)
{
return;
}
}
// 下一场景指针不为空时,切换场景
if (m_pNextScene)
{
// 进入下一场景
_enterNextScene();
} }
// 断言当前场景非空 // 断言当前场景非空
@ -367,7 +375,15 @@ void e2d::EApp::_onRender()
// 使用背景色清空屏幕 // 使用背景色清空屏幕
GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor.value)); GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor.value));
// 绘制当前场景 // 绘制当前场景
m_pCurrentScene->_onRender(); if (m_pCurrentScene)
{
m_pCurrentScene->_onRender();
}
// 切换场景时,同时绘制两场景
if (m_bTransitional && m_pNextScene)
{
m_pNextScene->_onRender();
}
// 终止绘图 // 终止绘图
hr = GetRenderTarget()->EndDraw(); hr = GetRenderTarget()->EndDraw();
// 刷新界面 // 刷新界面
@ -418,14 +434,14 @@ e2d::EString e2d::EApp::getTitle()
return get()->m_sTitle; return get()->m_sTitle;
} }
UINT32 e2d::EApp::getWidth() float e2d::EApp::getWidth()
{ {
return GetRenderTarget()->GetPixelSize().width; return GetRenderTarget()->GetSize().width;
} }
UINT32 e2d::EApp::getHeight() float e2d::EApp::getHeight()
{ {
return GetRenderTarget()->GetPixelSize().height; return GetRenderTarget()->GetSize().height;
} }
void e2d::EApp::enterScene(EScene * scene, bool saveCurrentScene /* = true */) void e2d::EApp::enterScene(EScene * scene, bool saveCurrentScene /* = true */)
@ -450,7 +466,6 @@ void e2d::EApp::enterScene(EScene * scene, ETransition * transition, bool saveCu
transition->_setTarget( transition->_setTarget(
get()->m_pCurrentScene, get()->m_pCurrentScene,
get()->m_pNextScene, get()->m_pNextScene,
get()->m_bEnterNextScene,
get()->m_bTransitional get()->m_bTransitional
); );
} }
@ -483,7 +498,6 @@ void e2d::EApp::backScene(ETransition * transition)
transition->_setTarget( transition->_setTarget(
get()->m_pCurrentScene, get()->m_pCurrentScene,
get()->m_pNextScene, get()->m_pNextScene,
get()->m_bEnterNextScene,
get()->m_bTransitional get()->m_bTransitional
); );
} }
@ -499,7 +513,7 @@ void e2d::EApp::clearScene()
while (s_SceneStack.size()) while (s_SceneStack.size())
{ {
auto temp = s_SceneStack.top(); auto temp = s_SceneStack.top();
SafeRelease(&temp); SafeReleaseAndClear(&temp);
s_SceneStack.pop(); s_SceneStack.pop();
} }
} }
@ -569,19 +583,9 @@ void e2d::EApp::showWindow()
void e2d::EApp::_free() void e2d::EApp::_free()
{ {
// 清空场景栈
clearScene();
// 释放场景内存
SafeRelease(&m_pCurrentScene);
SafeRelease(&m_pNextScene);
// 删除图片缓存 // 删除图片缓存
ETexture::clearCache(); ETexture::clearCache();
// 停止所有定时器、监听器、动画 // 删除所有对象(包括所有场景、定时器、监听器、动画)
ETimerManager::_clearManager();
EMsgManager::_clearManager();
EActionManager::_clearManager();
// 删除所有对象
EObjectManager::clearAllObjects(); EObjectManager::clearAllObjects();
} }
@ -612,7 +616,7 @@ void e2d::EApp::_enterNextScene()
} }
else else
{ {
SafeRelease(&m_pCurrentScene); SafeReleaseAndClear(&m_pCurrentScene);
} }
} }
@ -721,7 +725,7 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:
{ {
// 执行场景切换时屏蔽按键和鼠标消息 // 执行场景切换时屏蔽按键和鼠标消息
if (!pEApp->m_bTransitional) if (!pEApp->m_bTransitional && !pEApp->m_pNextScene)
{ {
EMsgManager::MouseProc(message, wParam, lParam); EMsgManager::MouseProc(message, wParam, lParam);
} }
@ -735,7 +739,7 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
case WM_KEYUP: case WM_KEYUP:
{ {
// 执行场景切换时屏蔽按键和鼠标消息 // 执行场景切换时屏蔽按键和鼠标消息
if (!pEApp->m_bTransitional) if (!pEApp->m_bTransitional && !pEApp->m_pNextScene)
{ {
EMsgManager::KeyboardProc(message, wParam, lParam); EMsgManager::KeyboardProc(message, wParam, lParam);
} }
@ -780,7 +784,8 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
{ {
if (LOWORD(wParam) == WA_INACTIVE) if (LOWORD(wParam) == WA_INACTIVE)
{ {
if (pEApp->getCurrentScene()->onInactive() && if (pEApp->getCurrentScene() &&
pEApp->getCurrentScene()->onInactive() &&
pEApp->onInactive()) pEApp->onInactive())
{ {
pEApp->m_bPaused = true; pEApp->m_bPaused = true;
@ -788,7 +793,8 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
} }
else else
{ {
if (pEApp->getCurrentScene()->onActivate() && if (pEApp->getCurrentScene() &&
pEApp->getCurrentScene()->onActivate() &&
pEApp->onActivate()) pEApp->onActivate())
{ {
pEApp->m_bPaused = false; pEApp->m_bPaused = false;
@ -802,10 +808,20 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
// 窗口关闭消息 // 窗口关闭消息
case WM_CLOSE: case WM_CLOSE:
{ {
if (pEApp->getCurrentScene()->onCloseWindow() && if (!pEApp->getCurrentScene())
pEApp->onCloseWindow())
{ {
DestroyWindow(hWnd); if (pEApp->onCloseWindow())
{
DestroyWindow(hWnd);
}
}
else
{
if (pEApp->getCurrentScene()->onCloseWindow() &&
pEApp->onCloseWindow())
{
DestroyWindow(hWnd);
}
} }
} }
result = 1; result = 1;

View File

@ -23,11 +23,11 @@ void e2d::EObject::retain()
void e2d::EObject::release() void e2d::EObject::release()
{ {
m_nRefCount--; m_nRefCount--;
// 通知对象管理池刷新
EObjectManager::notifyFlush();
} }
void e2d::EObject::autoRelease() void e2d::EObject::autoRelease()
{ {
m_bAutoRelease = true; m_bAutoRelease = true;
// 通知对象管理池刷新
EObjectManager::notifyFlush();
} }

View File

@ -11,15 +11,16 @@ e2d::EScene::EScene()
{ {
m_pRoot->_onEnter(); m_pRoot->_onEnter();
m_pRoot->_setParentScene(this); m_pRoot->_setParentScene(this);
m_pRoot->_setSize(EApp::getWidth(), EApp::getHeight());
m_pRoot->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2);
} }
e2d::EScene::~EScene() e2d::EScene::~EScene()
{ {
ETimerManager::clearAllTimersBindedWith(this); ETimerManager::_clearAllTimersBindedWith(this);
EMsgManager::clearAllMouseListenersBindedWith(this); EMsgManager::_clearAllMouseListenersBindedWith(this);
EMsgManager::clearAllKeyboardListenersBindedWith(this); EMsgManager::_clearAllKeyboardListenersBindedWith(this);
EActionManager::clearAllActionsBindedWith(this); SafeReleaseAndClear(&m_pRoot);
SafeRelease(&m_pRoot);
} }
void e2d::EScene::onEnter() void e2d::EScene::onEnter()

View File

@ -146,7 +146,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>false</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
@ -212,7 +212,6 @@
<ClCompile Include="Base\EApp.cpp" /> <ClCompile Include="Base\EApp.cpp" />
<ClCompile Include="Base\EObject.cpp" /> <ClCompile Include="Base\EObject.cpp" />
<ClCompile Include="Base\EScene.cpp" /> <ClCompile Include="Base\EScene.cpp" />
<ClCompile Include="ETimer.cpp" />
<ClCompile Include="Listener\EKeyboardListener.cpp" /> <ClCompile Include="Listener\EKeyboardListener.cpp" />
<ClCompile Include="Listener\EKeyboardPressListener.cpp" /> <ClCompile Include="Listener\EKeyboardPressListener.cpp" />
<ClCompile Include="Listener\EListener.cpp" /> <ClCompile Include="Listener\EListener.cpp" />
@ -225,6 +224,7 @@
<ClCompile Include="Manager\EMsgManager.cpp" /> <ClCompile Include="Manager\EMsgManager.cpp" />
<ClCompile Include="Manager\EObjectManager.cpp" /> <ClCompile Include="Manager\EObjectManager.cpp" />
<ClCompile Include="Manager\ETimerManager.cpp" /> <ClCompile Include="Manager\ETimerManager.cpp" />
<ClCompile Include="Node\EButton.cpp" />
<ClCompile Include="Node\ENode.cpp" /> <ClCompile Include="Node\ENode.cpp" />
<ClCompile Include="Node\ESprite.cpp" /> <ClCompile Include="Node\ESprite.cpp" />
<ClCompile Include="Node\ESpriteFrame.cpp" /> <ClCompile Include="Node\ESpriteFrame.cpp" />
@ -232,9 +232,13 @@
<ClCompile Include="Node\EFont.cpp" /> <ClCompile Include="Node\EFont.cpp" />
<ClCompile Include="Node\ETexture.cpp" /> <ClCompile Include="Node\ETexture.cpp" />
<ClCompile Include="Tool\EFileUtils.cpp" /> <ClCompile Include="Tool\EFileUtils.cpp" />
<ClCompile Include="Tool\EMusicUtils.cpp" />
<ClCompile Include="Tool\ERandom.cpp" /> <ClCompile Include="Tool\ERandom.cpp" />
<ClCompile Include="Tool\ETimer.cpp" />
<ClCompile Include="Transition\ETransitionEmerge.cpp" />
<ClCompile Include="Transition\ETransitionFade.cpp" /> <ClCompile Include="Transition\ETransitionFade.cpp" />
<ClCompile Include="Transition\ETransitionMove.cpp" />
<ClCompile Include="Transition\ETransitionScale.cpp" />
<ClCompile Include="Transition\ETransitionScaleEmerge.cpp" />
<ClCompile Include="Win\winbase.cpp" /> <ClCompile Include="Win\winbase.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -45,9 +45,6 @@
<ClCompile Include="Node\ESprite.cpp"> <ClCompile Include="Node\ESprite.cpp">
<Filter>Node</Filter> <Filter>Node</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ETimer.cpp">
<Filter>Tool</Filter>
</ClCompile>
<ClCompile Include="Node\EText.cpp"> <ClCompile Include="Node\EText.cpp">
<Filter>Node</Filter> <Filter>Node</Filter>
</ClCompile> </ClCompile>
@ -105,9 +102,6 @@
<ClCompile Include="Action\EActionTwoAtSameTime.cpp"> <ClCompile Include="Action\EActionTwoAtSameTime.cpp">
<Filter>Action</Filter> <Filter>Action</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Tool\EMusicUtils.cpp">
<Filter>Tool</Filter>
</ClCompile>
<ClCompile Include="Node\ESpriteFrame.cpp"> <ClCompile Include="Node\ESpriteFrame.cpp">
<Filter>Node</Filter> <Filter>Node</Filter>
</ClCompile> </ClCompile>
@ -159,6 +153,24 @@
<ClCompile Include="Listener\EMousePressListener.cpp"> <ClCompile Include="Listener\EMousePressListener.cpp">
<Filter>Listener</Filter> <Filter>Listener</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Node\EButton.cpp">
<Filter>Node</Filter>
</ClCompile>
<ClCompile Include="Transition\ETransitionEmerge.cpp">
<Filter>Transition</Filter>
</ClCompile>
<ClCompile Include="Transition\ETransitionMove.cpp">
<Filter>Transition</Filter>
</ClCompile>
<ClCompile Include="Transition\ETransitionScale.cpp">
<Filter>Transition</Filter>
</ClCompile>
<ClCompile Include="Transition\ETransitionScaleEmerge.cpp">
<Filter>Transition</Filter>
</ClCompile>
<ClCompile Include="Tool\ETimer.cpp">
<Filter>Tool</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Win\winbase.h"> <ClInclude Include="Win\winbase.h">

View File

@ -2,6 +2,7 @@
e2d::EListener::EListener() e2d::EListener::EListener()
: m_bRunning(false) : m_bRunning(false)
, m_bAlways(false)
, m_pParentScene(nullptr) , m_pParentScene(nullptr)
, m_pParentNode(nullptr) , m_pParentNode(nullptr)
{ {

View File

@ -17,39 +17,6 @@ void e2d::EActionManager::addAction(EAction * action)
} }
} }
void e2d::EActionManager::startAllActionsBindedWith(EScene * pParentScene)
{
if (pParentScene)
{
for (const auto &child : pParentScene->getChildren())
{
EActionManager::startAllActionsBindedWith(child);
}
}
}
void e2d::EActionManager::stopAllActionsBindedWith(EScene * pParentScene)
{
if (pParentScene)
{
for (const auto &child : pParentScene->getChildren())
{
EActionManager::stopAllActionsBindedWith(child);
}
}
}
void e2d::EActionManager::clearAllActionsBindedWith(EScene * pParentScene)
{
if (pParentScene)
{
for (const auto & child : pParentScene->getChildren())
{
ETimerManager::clearAllTimersBindedWith(child);
}
}
}
void e2d::EActionManager::startAllActionsBindedWith(ENode * pTargetNode) void e2d::EActionManager::startAllActionsBindedWith(ENode * pTargetNode)
{ {
if (pTargetNode) if (pTargetNode)
@ -68,6 +35,24 @@ void e2d::EActionManager::startAllActionsBindedWith(ENode * pTargetNode)
} }
} }
void e2d::EActionManager::pauseAllActionsBindedWith(ENode * pTargetNode)
{
if (pTargetNode)
{
for (const auto &action : s_vActions)
{
if (action->getTarget() == pTargetNode)
{
action->pause();
}
}
for (const auto &child : pTargetNode->getChildren())
{
EActionManager::pauseAllActionsBindedWith(child);
}
}
}
void e2d::EActionManager::stopAllActionsBindedWith(ENode * pTargetNode) void e2d::EActionManager::stopAllActionsBindedWith(ENode * pTargetNode)
{ {
if (pTargetNode) if (pTargetNode)
@ -86,7 +71,7 @@ void e2d::EActionManager::stopAllActionsBindedWith(ENode * pTargetNode)
} }
} }
void e2d::EActionManager::clearAllActionsBindedWith(ENode * pTargetNode) void e2d::EActionManager::_clearAllActionsBindedWith(ENode * pTargetNode)
{ {
if (pTargetNode) if (pTargetNode)
{ {
@ -95,7 +80,7 @@ void e2d::EActionManager::clearAllActionsBindedWith(ENode * pTargetNode)
auto a = s_vActions[i]; auto a = s_vActions[i];
if (a->getTarget() == pTargetNode) if (a->getTarget() == pTargetNode)
{ {
SafeRelease(&a); SafeReleaseAndClear(&a);
s_vActions.erase(s_vActions.begin() + i); s_vActions.erase(s_vActions.begin() + i);
} }
else else
@ -103,26 +88,31 @@ void e2d::EActionManager::clearAllActionsBindedWith(ENode * pTargetNode)
i++; i++;
} }
} }
for (auto child : pTargetNode->getChildren())
{
ETimerManager::clearAllTimersBindedWith(child);
}
} }
} }
void e2d::EActionManager::startAllActions() void e2d::EActionManager::startAllActions()
{ {
EActionManager::startAllActionsBindedWith(EApp::getCurrentScene()); for (auto child : EApp::getCurrentScene()->getChildren())
{
EActionManager::startAllActionsBindedWith(child);
}
}
void e2d::EActionManager::pauseAllActions()
{
for (auto child : EApp::getCurrentScene()->getChildren())
{
EActionManager::pauseAllActionsBindedWith(child);
}
} }
void e2d::EActionManager::stopAllActions() void e2d::EActionManager::stopAllActions()
{ {
EActionManager::stopAllActionsBindedWith(EApp::getCurrentScene()); for (auto child : EApp::getCurrentScene()->getChildren())
} {
EActionManager::stopAllActionsBindedWith(child);
void e2d::EActionManager::clearAllActions() }
{
EActionManager::clearAllActionsBindedWith(EApp::getCurrentScene());
} }
void e2d::EActionManager::_clearManager() void e2d::EActionManager::_clearManager()
@ -143,11 +133,10 @@ void e2d::EActionManager::ActionProc()
if (EApp::isPaused() || s_vActions.empty()) if (EApp::isPaused() || s_vActions.empty())
return; return;
EAction * action;
// 循环遍历所有正在运行的动作 // 循环遍历所有正在运行的动作
for (size_t i = 0; i < s_vActions.size(); i++) for (size_t i = 0; i < s_vActions.size(); i++)
{ {
action = s_vActions[i]; auto &action = s_vActions[i];
// 获取动作运行状态 // 获取动作运行状态
if (action->isRunning() || if (action->isRunning() ||
(action->getTarget() && action->getTarget()->getParentScene() == EApp::getCurrentScene())) (action->getTarget() && action->getTarget()->getParentScene() == EApp::getCurrentScene()))
@ -155,7 +144,7 @@ void e2d::EActionManager::ActionProc()
if (action->_isEnding()) if (action->_isEnding())
{ {
// 动作已经结束 // 动作已经结束
SafeRelease(&action); SafeReleaseAndClear(&action);
s_vActions.erase(s_vActions.begin() + i); s_vActions.erase(s_vActions.begin() + i);
} }
else else

View File

@ -15,16 +15,18 @@ 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)
{ {
if (EApp::isPaused())
return;
// 保存鼠标消息 // 保存鼠标消息
s_MouseMsg.m_nMsg = message; s_MouseMsg.m_nMsg = message;
s_MouseMsg.m_wParam = wParam; s_MouseMsg.m_wParam = wParam;
s_MouseMsg.m_lParam = lParam; s_MouseMsg.m_lParam = lParam;
// 执行鼠标消息监听函数 // 执行鼠标消息监听函数
for (auto mlistener : s_vMouseListeners) for (size_t i = 0; i < s_vMouseListeners.size(); i++)
{ {
auto &mlistener = s_vMouseListeners[i];
if (EApp::isPaused() && !mlistener->m_bAlways)
continue;
if (mlistener->isRunning()) if (mlistener->isRunning())
{ {
if (mlistener->getParentScene() == EApp::getCurrentScene() || if (mlistener->getParentScene() == EApp::getCurrentScene() ||
@ -38,16 +40,18 @@ 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)
{ {
if (EApp::isPaused())
return;
// 保存按键消息 // 保存按键消息
s_KeyboardMsg.m_nMsg = message; s_KeyboardMsg.m_nMsg = message;
s_KeyboardMsg.m_wParam = wParam; s_KeyboardMsg.m_wParam = wParam;
s_KeyboardMsg.m_lParam = lParam; s_KeyboardMsg.m_lParam = lParam;
// 执行按键消息监听函数 // 执行按键消息监听函数
for (auto klistener : s_vKeyboardListeners) for (size_t i = 0; i < s_vKeyboardListeners.size(); i++)
{ {
auto &klistener = s_vKeyboardListeners[i];
if (EApp::isPaused() && !klistener->m_bAlways)
continue;
if (klistener->isRunning()) if (klistener->isRunning())
{ {
if (klistener->getParentScene() == EApp::getCurrentScene() || if (klistener->getParentScene() == EApp::getCurrentScene() ||
@ -163,7 +167,7 @@ bool e2d::EKeyboardMsg::isScrollLockOn()
return false; return false;
} }
void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pParentScene) void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pParentScene, bool always /* = false */)
{ {
ASSERT( ASSERT(
(!listener->m_pParentNode) && (!listener->m_pParentScene), (!listener->m_pParentNode) && (!listener->m_pParentScene),
@ -177,11 +181,12 @@ void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pPa
listener->start(); listener->start();
listener->retain(); listener->retain();
listener->m_pParentScene = pParentScene; listener->m_pParentScene = pParentScene;
listener->m_bAlways = always;
s_vMouseListeners.push_back(listener); s_vMouseListeners.push_back(listener);
} }
} }
void e2d::EMsgManager::bindListener(EKeyboardListener * listener, EScene * pParentScene) void e2d::EMsgManager::bindListener(EKeyboardListener * listener, EScene * pParentScene, bool always /* = false */)
{ {
ASSERT( ASSERT(
(!listener->m_pParentNode) && (!listener->m_pParentScene), (!listener->m_pParentNode) && (!listener->m_pParentScene),
@ -195,11 +200,12 @@ void e2d::EMsgManager::bindListener(EKeyboardListener * listener, EScene * pPare
listener->start(); listener->start();
listener->retain(); listener->retain();
listener->m_pParentScene = pParentScene; listener->m_pParentScene = pParentScene;
listener->m_bAlways = always;
s_vKeyboardListeners.push_back(listener); s_vKeyboardListeners.push_back(listener);
} }
} }
void e2d::EMsgManager::bindListener(EMouseListener * listener, ENode * pParentNode) void e2d::EMsgManager::bindListener(EMouseListener * listener, ENode * pParentNode, bool always /* = false */)
{ {
ASSERT( ASSERT(
(!listener->m_pParentNode) && (!listener->m_pParentScene), (!listener->m_pParentNode) && (!listener->m_pParentScene),
@ -212,12 +218,13 @@ void e2d::EMsgManager::bindListener(EMouseListener * listener, ENode * pParentNo
{ {
listener->start(); listener->start();
listener->retain(); listener->retain();
listener->m_bAlways = always;
listener->m_pParentNode = pParentNode; listener->m_pParentNode = pParentNode;
s_vMouseListeners.push_back(listener); s_vMouseListeners.push_back(listener);
} }
} }
void e2d::EMsgManager::bindListener(EKeyboardListener * listener, ENode * pParentNode) void e2d::EMsgManager::bindListener(EKeyboardListener * listener, ENode * pParentNode, bool always /* = false */)
{ {
ASSERT( ASSERT(
(!listener->m_pParentNode) && (!listener->m_pParentScene), (!listener->m_pParentNode) && (!listener->m_pParentScene),
@ -231,6 +238,7 @@ void e2d::EMsgManager::bindListener(EKeyboardListener * listener, ENode * pParen
listener->start(); listener->start();
listener->retain(); listener->retain();
listener->m_pParentNode = pParentNode; listener->m_pParentNode = pParentNode;
listener->m_bAlways = always;
s_vKeyboardListeners.push_back(listener); s_vKeyboardListeners.push_back(listener);
} }
} }
@ -265,7 +273,7 @@ void e2d::EMsgManager::delMouseListeners(const EString & name)
{ {
if ((*mIter)->getName() == name) if ((*mIter)->getName() == name)
{ {
SafeRelease(&(*mIter)); SafeReleaseAndClear(&(*mIter));
mIter = s_vMouseListeners.erase(mIter); mIter = s_vMouseListeners.erase(mIter);
} }
else else
@ -307,7 +315,7 @@ void e2d::EMsgManager::delKeyboardListeners(const EString & name)
{ {
if ((*kIter)->getName() == name) if ((*kIter)->getName() == name)
{ {
SafeRelease(&(*kIter)); SafeReleaseAndClear(&(*kIter));
kIter = s_vKeyboardListeners.erase(kIter); kIter = s_vKeyboardListeners.erase(kIter);
} }
else else
@ -437,14 +445,14 @@ void e2d::EMsgManager::stopAllKeyboardListenersBindedWith(ENode * pParentNode)
} }
} }
void e2d::EMsgManager::clearAllMouseListenersBindedWith(EScene * pParentScene) void e2d::EMsgManager::_clearAllMouseListenersBindedWith(EScene * pParentScene)
{ {
for (size_t i = 0; i < s_vMouseListeners.size();) for (size_t i = 0; i < s_vMouseListeners.size();)
{ {
auto t = s_vMouseListeners[i]; auto t = s_vMouseListeners[i];
if (t->getParentScene() == pParentScene) if (t->getParentScene() == pParentScene)
{ {
SafeRelease(&t); SafeReleaseAndClear(&t);
s_vMouseListeners.erase(s_vMouseListeners.begin() + i); s_vMouseListeners.erase(s_vMouseListeners.begin() + i);
} }
else else
@ -452,20 +460,16 @@ void e2d::EMsgManager::clearAllMouseListenersBindedWith(EScene * pParentScene)
i++; i++;
} }
} }
for (auto child : pParentScene->getChildren())
{
EMsgManager::clearAllMouseListenersBindedWith(child);
}
} }
void e2d::EMsgManager::clearAllKeyboardListenersBindedWith(EScene * pParentScene) void e2d::EMsgManager::_clearAllKeyboardListenersBindedWith(EScene * pParentScene)
{ {
for (size_t i = 0; i < s_vKeyboardListeners.size();) for (size_t i = 0; i < s_vKeyboardListeners.size();)
{ {
auto t = s_vKeyboardListeners[i]; auto t = s_vKeyboardListeners[i];
if (t->getParentScene() == pParentScene) if (t->getParentScene() == pParentScene)
{ {
SafeRelease(&t); SafeReleaseAndClear(&t);
s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i);
} }
else else
@ -473,20 +477,16 @@ void e2d::EMsgManager::clearAllKeyboardListenersBindedWith(EScene * pParentScene
i++; i++;
} }
} }
for (auto child : pParentScene->getChildren())
{
EMsgManager::clearAllKeyboardListenersBindedWith(child);
}
} }
void e2d::EMsgManager::clearAllMouseListenersBindedWith(ENode * pParentNode) void e2d::EMsgManager::_clearAllMouseListenersBindedWith(ENode * pParentNode)
{ {
for (size_t i = 0; i < s_vMouseListeners.size();) for (size_t i = 0; i < s_vMouseListeners.size();)
{ {
auto t = s_vMouseListeners[i]; auto t = s_vMouseListeners[i];
if (t->getParentNode() == pParentNode) if (t->getParentNode() == pParentNode)
{ {
SafeRelease(&t); SafeReleaseAndClear(&t);
s_vMouseListeners.erase(s_vMouseListeners.begin() + i); s_vMouseListeners.erase(s_vMouseListeners.begin() + i);
} }
else else
@ -494,20 +494,16 @@ void e2d::EMsgManager::clearAllMouseListenersBindedWith(ENode * pParentNode)
i++; i++;
} }
} }
for (auto child : pParentNode->getChildren())
{
EMsgManager::clearAllMouseListenersBindedWith(child);
}
} }
void e2d::EMsgManager::clearAllKeyboardListenersBindedWith(ENode * pParentNode) void e2d::EMsgManager::_clearAllKeyboardListenersBindedWith(ENode * pParentNode)
{ {
for (size_t i = 0; i < s_vKeyboardListeners.size();) for (size_t i = 0; i < s_vKeyboardListeners.size();)
{ {
auto t = s_vKeyboardListeners[i]; auto t = s_vKeyboardListeners[i];
if (t->getParentNode() == pParentNode) if (t->getParentNode() == pParentNode)
{ {
SafeRelease(&t); SafeReleaseAndClear(&t);
s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i);
} }
else else
@ -515,10 +511,6 @@ void e2d::EMsgManager::clearAllKeyboardListenersBindedWith(ENode * pParentNode)
i++; i++;
} }
} }
for (auto child : pParentNode->getChildren())
{
EMsgManager::clearAllKeyboardListenersBindedWith(child);
}
} }
void e2d::EMsgManager::_clearManager() void e2d::EMsgManager::_clearManager()
@ -537,11 +529,6 @@ void e2d::EMsgManager::stopAllMouseListeners()
EMsgManager::stopAllMouseListenersBindedWith(EApp::getCurrentScene()); EMsgManager::stopAllMouseListenersBindedWith(EApp::getCurrentScene());
} }
void e2d::EMsgManager::clearAllMouseListeners()
{
EMsgManager::clearAllMouseListenersBindedWith(EApp::getCurrentScene());
}
void e2d::EMsgManager::startAllKeyboardListeners() void e2d::EMsgManager::startAllKeyboardListeners()
{ {
EMsgManager::startAllKeyboardListenersBindedWith(EApp::getCurrentScene()); EMsgManager::startAllKeyboardListenersBindedWith(EApp::getCurrentScene());
@ -550,9 +537,4 @@ void e2d::EMsgManager::startAllKeyboardListeners()
void e2d::EMsgManager::stopAllKeyboardListeners() void e2d::EMsgManager::stopAllKeyboardListeners()
{ {
EMsgManager::stopAllKeyboardListenersBindedWith(EApp::getCurrentScene()); EMsgManager::stopAllKeyboardListenersBindedWith(EApp::getCurrentScene());
}
void e2d::EMsgManager::clearAllKeyboardListeners()
{
EMsgManager::clearAllKeyboardListenersBindedWith(EApp::getCurrentScene());
} }

View File

@ -4,6 +4,29 @@
static e2d::EVector<e2d::ETimer*> s_vTimers; static e2d::EVector<e2d::ETimer*> s_vTimers;
void e2d::ETimerManager::TimerProc()
{
if (EApp::isPaused())
return;
for (size_t i = 0; i < s_vTimers.size(); i++)
{
auto &t = s_vTimers[i];
if (t->isRunning())
{
if (t->getParentScene() == EApp::getCurrentScene() ||
(t->getParentNode() && (t->getParentNode()->getParentScene() == EApp::getCurrentScene())))
{
if (t->_isReady())
{
t->_callOn();
}
}
}
}
}
void e2d::ETimerManager::bindTimer(ETimer * timer, EScene * pParentScene) void e2d::ETimerManager::bindTimer(ETimer * timer, EScene * pParentScene)
{ {
ASSERT( ASSERT(
@ -69,7 +92,7 @@ void e2d::ETimerManager::delTimers(const EString & name)
{ {
if ((*mIter)->getName() == name) if ((*mIter)->getName() == name)
{ {
SafeRelease(&(*mIter)); SafeReleaseAndClear(&(*mIter));
mIter = s_vTimers.erase(mIter); mIter = s_vTimers.erase(mIter);
} }
else else
@ -109,14 +132,14 @@ void e2d::ETimerManager::stopAllTimersBindedWith(EScene * pParentScene)
} }
} }
void e2d::ETimerManager::clearAllTimersBindedWith(EScene * pParentScene) void e2d::ETimerManager::_clearAllTimersBindedWith(EScene * pParentScene)
{ {
for (size_t i = 0; i < s_vTimers.size();) for (size_t i = 0; i < s_vTimers.size();)
{ {
auto t = s_vTimers[i]; auto t = s_vTimers[i];
if (t->getParentScene() == pParentScene) if (t->getParentScene() == pParentScene)
{ {
SafeRelease(&t); SafeReleaseAndClear(&t);
s_vTimers.erase(s_vTimers.begin() + i); s_vTimers.erase(s_vTimers.begin() + i);
} }
else else
@ -124,10 +147,6 @@ void e2d::ETimerManager::clearAllTimersBindedWith(EScene * pParentScene)
i++; i++;
} }
} }
for (auto child : pParentScene->getChildren())
{
ETimerManager::clearAllTimersBindedWith(child);
}
} }
void e2d::ETimerManager::startAllTimersBindedWith(ENode * pParentNode) void e2d::ETimerManager::startAllTimersBindedWith(ENode * pParentNode)
@ -160,14 +179,14 @@ void e2d::ETimerManager::stopAllTimersBindedWith(ENode * pParentNode)
} }
} }
void e2d::ETimerManager::clearAllTimersBindedWith(ENode * pParentNode) void e2d::ETimerManager::_clearAllTimersBindedWith(ENode * pParentNode)
{ {
for (size_t i = 0; i < s_vTimers.size();) for (size_t i = 0; i < s_vTimers.size();)
{ {
auto t = s_vTimers[i]; auto t = s_vTimers[i];
if (t->getParentNode() == pParentNode) if (t->getParentNode() == pParentNode)
{ {
SafeRelease(&t); SafeReleaseAndClear(&t);
s_vTimers.erase(s_vTimers.begin() + i); s_vTimers.erase(s_vTimers.begin() + i);
} }
else else
@ -175,10 +194,6 @@ void e2d::ETimerManager::clearAllTimersBindedWith(ENode * pParentNode)
i++; i++;
} }
} }
for (auto child : pParentNode->getChildren())
{
ETimerManager::clearAllTimersBindedWith(child);
}
} }
void e2d::ETimerManager::_clearManager() void e2d::ETimerManager::_clearManager()
@ -202,31 +217,4 @@ void e2d::ETimerManager::startAllTimers()
void e2d::ETimerManager::stopAllTimers() void e2d::ETimerManager::stopAllTimers()
{ {
ETimerManager::stopAllTimersBindedWith(EApp::getCurrentScene()); ETimerManager::stopAllTimersBindedWith(EApp::getCurrentScene());
}
void e2d::ETimerManager::clearAllTimers()
{
ETimerManager::clearAllTimersBindedWith(EApp::getCurrentScene());
}
void e2d::ETimerManager::TimerProc()
{
if (EApp::isPaused())
return;
for (auto t : s_vTimers)
{
if (t->isRunning())
{
if (t->getParentScene() == EApp::getCurrentScene() ||
(t->getParentNode() && t->getParentNode()->getParentScene() == EApp::getCurrentScene()))
{
if (GetInterval(t->m_tLast) >= t->m_nInterval)
{
t->_callOn();
t->m_tLast = GetNow();
}
}
}
}
} }

212
Easy2D/Node/EButton.cpp Normal file
View File

@ -0,0 +1,212 @@
#include "..\enodes.h"
#include "..\emsg.h"
#include "..\Win\winbase.h"
e2d::EButton::EButton()
: m_Callback([] {})
, m_eStatus(STATUS::NORMAL)
, m_bIsDisable(false)
, m_bIsSelected(false)
, m_pNormal(nullptr)
, m_pMouseover(nullptr)
, m_pSelected(nullptr)
, m_pDisabled(nullptr)
, m_pDisplayed(nullptr)
{
}
e2d::EButton::EButton(ENode * normal, const BUTTON_CLICK_CALLBACK & callback)
: EButton()
{
this->setNormal(normal);
this->setCallback(callback);
}
e2d::EButton::EButton(ENode * normal, ENode * selected, const BUTTON_CLICK_CALLBACK & callback)
: EButton()
{
this->setNormal(normal);
this->setSelected(selected);
this->setCallback(callback);
}
e2d::EButton::EButton(ENode * normal, ENode * mouseover, ENode * selected, const BUTTON_CLICK_CALLBACK & callback)
: EButton()
{
this->setNormal(normal);
this->setMouseOver(mouseover);
this->setSelected(selected);
this->setCallback(callback);
}
e2d::EButton::EButton(ENode * normal, ENode * mouseover, ENode * selected, ENode * disabled, const BUTTON_CLICK_CALLBACK & callback)
: EButton()
{
this->setNormal(normal);
this->setMouseOver(mouseover);
this->setSelected(selected);
this->setDisabled(disabled);
this->setCallback(callback);
}
void e2d::EButton::setNormal(ENode * normal)
{
if (normal)
{
if (m_pNormal)
{
this->removeChild(m_pNormal);
}
m_pNormal = normal;
this->addChild(m_pNormal);
}
}
void e2d::EButton::setMouseOver(ENode * mouseover)
{
if (mouseover)
{
if (m_pMouseover)
{
this->removeChild(m_pMouseover);
}
m_pMouseover = mouseover;
this->addChild(m_pMouseover);
}
}
void e2d::EButton::setSelected(ENode * selected)
{
if (selected)
{
if (m_pSelected)
{
this->removeChild(m_pSelected);
}
m_pSelected = selected;
this->addChild(m_pSelected);
}
}
void e2d::EButton::setDisabled(ENode * disabled)
{
if (disabled)
{
if (m_pDisabled)
{
this->removeChild(m_pDisabled);
}
m_pDisabled = disabled;
this->addChild(m_pDisabled);
}
}
void e2d::EButton::setDisable(bool disable)
{
m_bIsDisable = disable;
}
void e2d::EButton::setCallback(const BUTTON_CLICK_CALLBACK & callback)
{
auto listener = new EMouseListener(std::bind(&EButton::_listenerCallback, this));
EMsgManager::bindListener(listener, this, true);
m_Callback = callback;
}
void e2d::EButton::_callOn()
{
if (!m_bVisiable)
{
return;
}
if (m_bTransformChildrenNeeded)
{
_updateTransform(this);
}
if (!m_vChildren.empty())
{
GetRenderTarget()->SetTransform(m_Matri);
if (m_eStatus == STATUS::DISABLED && m_pDisabled)
{
m_pDisabled->_callOn();
}
else if (m_eStatus == STATUS::SELECTED && m_pSelected)
{
m_pSelected->_callOn();
}
else if (m_eStatus == STATUS::MOUSEOVER && m_pMouseover)
{
m_pMouseover->_callOn();
}
else if (m_pNormal)
{
m_pNormal->_callOn();
}
}
}
void e2d::EButton::_listenerCallback()
{
if (!m_bIsDisable)
{
if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN &&
m_pDisplayed &&
m_pDisplayed->isPointIn(EMouseMsg::getPos()))
{
// 鼠标左键按下,且位于按钮内时,标记 m_bIsSelected 为 true
m_bIsSelected = true;
}
else if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_UP)
{
// 鼠标左键抬起时,判断鼠标坐标是否在按钮内部
if (m_bIsSelected &&
m_pDisplayed &&
m_pDisplayed->isPointIn(EMouseMsg::getPos()))
{
m_Callback();
m_eStatus = STATUS::NORMAL;
m_pDisplayed = m_pNormal;
}
// 标记 m_bIsSelected 为 false
m_bIsSelected = false;
}
if (EMouseMsg::isLButtonDown() &&
m_bIsSelected &&
m_pSelected &&
m_pSelected->isPointIn(EMouseMsg::getPos()))
{
// 鼠标左键按下,且按钮是被选中的状态,且鼠标
// 在按钮内时,按钮状态变为 SELECTED
m_eStatus = STATUS::SELECTED;
m_pDisplayed = m_pSelected;
}
else if (EMouseMsg::getMsg() == EMouseMsg::MOVE &&
m_pDisplayed &&
m_pDisplayed->isPointIn(EMouseMsg::getPos()) &&
m_pMouseover)
{
m_eStatus = STATUS::MOUSEOVER;
m_pDisplayed = m_pMouseover;
}
else
{
m_eStatus = STATUS::NORMAL;
m_pDisplayed = m_pNormal;
}
}
else
{
if (m_pDisplayed)
{
m_eStatus = STATUS::DISABLED;
}
else
{
m_eStatus = STATUS::NORMAL;
}
}
}

View File

@ -14,8 +14,8 @@ e2d::ENode::ENode()
, m_fSkewAngleY(0) , m_fSkewAngleY(0)
, m_fDisplayOpacity(1.0f) , m_fDisplayOpacity(1.0f)
, m_fRealOpacity(1.0f) , m_fRealOpacity(1.0f)
, m_fAnchorX(0) , m_fAnchorX(0.5f)
, m_fAnchorY(0) , m_fAnchorY(0.5f)
, m_Matri(D2D1::Matrix3x2F::Identity()) , m_Matri(D2D1::Matrix3x2F::Identity())
, m_bVisiable(true) , m_bVisiable(true)
, m_bDisplayedInScene(false) , m_bDisplayedInScene(false)
@ -35,10 +35,10 @@ e2d::ENode::ENode(const EString & name)
e2d::ENode::~ENode() e2d::ENode::~ENode()
{ {
ETimerManager::clearAllTimersBindedWith(this); ETimerManager::_clearAllTimersBindedWith(this);
EMsgManager::clearAllMouseListenersBindedWith(this); EMsgManager::_clearAllMouseListenersBindedWith(this);
EMsgManager::clearAllKeyboardListenersBindedWith(this); EMsgManager::_clearAllKeyboardListenersBindedWith(this);
EActionManager::clearAllActionsBindedWith(this); EActionManager::_clearAllActionsBindedWith(this);
} }
void e2d::ENode::onEnter() void e2d::ENode::onEnter()
@ -428,8 +428,8 @@ void e2d::ENode::setOpacity(float opacity)
return; return;
m_fDisplayOpacity = m_fRealOpacity = min(max(opacity, 0), 1); m_fDisplayOpacity = m_fRealOpacity = min(max(opacity, 0), 1);
// 更新节点透明度 // 更新节点透明度
_updateChildrenOpacity(); _updateOpacity(this);
} }
void e2d::ENode::setAnchorX(float anchorX) void e2d::ENode::setAnchorX(float anchorX)
@ -557,7 +557,9 @@ bool e2d::ENode::removeChild(ENode * child, bool release /* = true */)
child->_onExit(); child->_onExit();
child->release(); child->release();
if (release) if (release)
{
child->autoRelease(); child->autoRelease();
}
return true; return true;
} }
} }
@ -593,7 +595,9 @@ void e2d::ENode::removeChild(const EString & childName, bool release /* = true *
child->_onExit(); child->_onExit();
child->release(); child->release();
if (release) if (release)
{
child->autoRelease(); child->autoRelease();
}
return; return;
} }
} }
@ -604,12 +608,12 @@ void e2d::ENode::clearAllChildren(bool release /* = true */)
// 所有节点的引用计数减一 // 所有节点的引用计数减一
for (auto child : m_vChildren) for (auto child : m_vChildren)
{ {
child->_onExit();
child->release();
if (release) if (release)
{ {
child->autoRelease(); child->autoRelease();
} }
child->_onExit();
child->release();
} }
// 清空储存节点的容器 // 清空储存节点的容器
m_vChildren.clear(); m_vChildren.clear();
@ -619,7 +623,7 @@ void e2d::ENode::runAction(EAction * action)
{ {
ASSERT( ASSERT(
(!action->getTarget()), (!action->getTarget()),
"The action is already running, it cannot running again!" "The action is already running, it cannot run again!"
); );
action->setTarget(this); action->setTarget(this);
EActionManager::addAction(action); EActionManager::addAction(action);
@ -641,6 +645,41 @@ void e2d::ENode::pauseAction(EAction * action)
} }
} }
bool e2d::ENode::isPointIn(EPoint point)
{
if (m_bTransformChildrenNeeded)
{
_updateTransform(this);
}
// 保存节点所在矩形
D2D1_POINT_2F leftTop = m_Matri.TransformPoint(
D2D1::Point2F(0, 0)
);
D2D1_POINT_2F rightBottom = m_Matri.TransformPoint(
D2D1::Point2F(getRealWidth(), getRealHeight())
);
D2D1_RECT_F rt = D2D1::RectF(
leftTop.x,
leftTop.y,
rightBottom.x,
rightBottom.y
);
if (point.x >= rt.left &&
point.x <= rt.right &&
point.y >= rt.top &&
point.y <= rt.bottom)
{
return true;
}
else
{
for (const auto & child : m_vChildren)
if (child->isPointIn(point))
return true;
}
return false;
}
void e2d::ENode::stopAction(EAction * action) void e2d::ENode::stopAction(EAction * action)
{ {
if (action->getTarget() == this) if (action->getTarget() == this)
@ -649,6 +688,21 @@ void e2d::ENode::stopAction(EAction * action)
} }
} }
void e2d::ENode::startAllActions()
{
EActionManager::startAllActionsBindedWith(this);
}
void e2d::ENode::pauseAllActions()
{
EActionManager::pauseAllActionsBindedWith(this);
}
void e2d::ENode::stopAllActions()
{
EActionManager::stopAllActionsBindedWith(this);
}
void e2d::ENode::setVisiable(bool value) void e2d::ENode::setVisiable(bool value)
{ {
m_bVisiable = value; m_bVisiable = value;

View File

@ -9,64 +9,82 @@ e2d::ESprite::ESprite()
{ {
} }
e2d::ESprite::ESprite(ETexture * texture)
: ESprite()
{
loadFrom(texture);
}
e2d::ESprite::ESprite(ESpriteFrame * spriteFrame)
: ESprite()
{
loadFrom(spriteFrame);
}
e2d::ESprite::ESprite(const EString & imageFileName) e2d::ESprite::ESprite(const EString & imageFileName)
: ESprite() : ESprite()
{ {
setTexture(new ETexture(imageFileName)); loadFrom(new ETexture(imageFileName));
} }
e2d::ESprite::ESprite(const EString & imageFileName, float x, float y, float width, float height) e2d::ESprite::ESprite(const EString & imageFileName, float x, float y, float width, float height)
{ {
setTexture(new ETexture(imageFileName)); loadFrom(new ETexture(imageFileName));
clipTexture(x, y, width, height); clip(x, y, width, height);
} }
e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType) e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType)
: ESprite() : ESprite()
{ {
setTexture(new ETexture(resourceName, resourceType)); loadFrom(new ETexture(resourceName, resourceType));
} }
e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height) e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height)
{ {
setTexture(new ETexture(resourceName, resourceType)); loadFrom(new ETexture(resourceName, resourceType));
clipTexture(x, y, width, height); clip(x, y, width, height);
} }
e2d::ESprite::~ESprite() e2d::ESprite::~ESprite()
{ {
SafeRelease(&m_pTexture); SafeReleaseAndClear(&m_pTexture);
} }
void e2d::ESprite::setTexture(ETexture * texture) void e2d::ESprite::loadFrom(ETexture * texture)
{ {
SafeRelease(&m_pTexture); if (texture)
m_pTexture = texture; {
m_pTexture->retain(); SafeReleaseAndClear(&m_pTexture);
m_pTexture = texture;
m_pTexture->retain();
m_fSourceClipX = m_fSourceClipY = 0; m_fSourceClipX = m_fSourceClipY = 0;
ENode::_setWidth(m_pTexture->getSourceWidth()); ENode::_setWidth(m_pTexture->getSourceWidth());
ENode::_setHeight(m_pTexture->getSourceHeight()); ENode::_setHeight(m_pTexture->getSourceHeight());
}
} }
void e2d::ESprite::setTexture(ETexture * texture, float x, float y, float width, float height) void e2d::ESprite::loadFrom(ETexture * texture, float x, float y, float width, float height)
{ {
setTexture(texture); loadFrom(texture);
clipTexture(x, y, width, height); clip(x, y, width, height);
} }
void e2d::ESprite::loadFromSpriteFrame(ESpriteFrame * frame) void e2d::ESprite::loadFrom(ESpriteFrame * frame)
{ {
setTexture(frame->m_pTexture); if (frame)
clipTexture(frame->m_fSourceClipX, frame->m_fSourceClipY, frame->m_fSourceClipWidth, frame->m_fSourceClipHeight); {
loadFrom(frame->m_pTexture);
clip(frame->m_fSourceClipX, frame->m_fSourceClipY, frame->m_fSourceClipWidth, frame->m_fSourceClipHeight);
}
} }
void e2d::ESprite::clipTexture(float x, float y, float width, float height) void e2d::ESprite::clip(float x, float y, float width, float height)
{ {
m_fSourceClipX = min(max(x, 0), m_pTexture->getSourceWidth()); m_fSourceClipX = min(max(x, 0), m_pTexture->getSourceWidth());
m_fSourceClipY = min(max(y, 0), m_pTexture->getSourceHeight()); m_fSourceClipY = min(max(y, 0), m_pTexture->getSourceHeight());
ENode::_setWidth(min(max(width, 0), m_pTexture->getSourceWidth() - m_fSourceClipX)); ENode::_setWidth(min(max(width, 0), m_pTexture->getSourceWidth() - m_fSourceClipX));
ENode::_setHeight(min(max(height, 0), m_pTexture->getSourceHeight() - m_fSourceClipX)); ENode::_setHeight(min(max(height, 0), m_pTexture->getSourceHeight() - m_fSourceClipY));
} }
void e2d::ESprite::_onRender() void e2d::ESprite::_onRender()

View File

@ -50,20 +50,29 @@ e2d::ESpriteFrame::ESpriteFrame(const EString & resourceName, const EString & re
e2d::ESpriteFrame::~ESpriteFrame() e2d::ESpriteFrame::~ESpriteFrame()
{ {
if (m_pTexture) SafeRelease(&m_pTexture);
{ }
m_pTexture->release();
} float e2d::ESpriteFrame::getWidth() const
{
return m_fSourceClipWidth;
}
float e2d::ESpriteFrame::getHeight() const
{
return m_fSourceClipHeight;
}
e2d::ETexture * e2d::ESpriteFrame::getTexture() const
{
return m_pTexture;
} }
void e2d::ESpriteFrame::_setTexture(ETexture * texture) void e2d::ESpriteFrame::_setTexture(ETexture * texture)
{ {
if (texture) if (texture)
{ {
if (m_pTexture) SafeRelease(&m_pTexture);
{
m_pTexture->release();
}
m_pTexture = texture; m_pTexture = texture;
m_pTexture->retain(); m_pTexture->retain();
m_fSourceClipX = 0; m_fSourceClipX = 0;

View File

@ -40,7 +40,7 @@ e2d::EText::EText(const EString & text, EColor color, EString fontFamily, float
e2d::EText::~EText() e2d::EText::~EText()
{ {
SafeRelease(&m_pFont); SafeReleaseAndClear(&m_pFont);
} }
e2d::EString e2d::EText::getText() const e2d::EString e2d::EText::getText() const
@ -83,7 +83,7 @@ void e2d::EText::setFont(EFont * font)
{ {
if (font) if (font)
{ {
SafeRelease(&m_pFont); SafeReleaseAndClear(&m_pFont);
m_pFont = font; m_pFont = font;
font->retain(); font->retain();
@ -108,7 +108,7 @@ void e2d::EText::_onRender()
GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color.value, m_fDisplayOpacity)); GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color.value, m_fDisplayOpacity));
GetRenderTarget()->DrawTextW( GetRenderTarget()->DrawTextW(
m_sText.c_str(), m_sText.c_str(),
m_sText.length(), UINT32(m_sText.length()),
m_pFont->_getTextFormat(), m_pFont->_getTextFormat(),
D2D1::RectF( D2D1::RectF(
0, 0,
@ -145,7 +145,7 @@ void e2d::EText::_initTextLayout()
HRESULT hr = GetDirectWriteFactory()->CreateTextLayout( HRESULT hr = GetDirectWriteFactory()->CreateTextLayout(
m_sText.c_str(), m_sText.c_str(),
m_sText.size(), UINT32(m_sText.size()),
m_pFont->_getTextFormat(), m_pFont->_getTextFormat(),
m_bWordWrapping ? m_fWordWrappingWidth : 0, m_bWordWrapping ? m_fWordWrappingWidth : 0,
0, 0,

View File

@ -1,6 +1 @@
#include "..\etools.h" #include "..\etools.h"
void e2d::EMusicUtils::play(LPCTSTR musicFileName, bool loop)
{
}

View File

@ -1,5 +1,5 @@
#include "etools.h" #include "..\etools.h"
#include "Win\winbase.h" #include "..\Win\winbase.h"
e2d::ETimer::ETimer() e2d::ETimer::ETimer()
: m_bRunning(false) : m_bRunning(false)
@ -7,27 +7,29 @@ e2d::ETimer::ETimer()
, m_pParentScene(nullptr) , m_pParentScene(nullptr)
, m_pParentNode(nullptr) , m_pParentNode(nullptr)
, m_Callback([](int) {}) , m_Callback([](int) {})
, m_nInterval(20LL) , m_nInterval(0)
, m_nRepeatTimes(0)
, m_bAtOnce(false)
{ {
} }
e2d::ETimer::ETimer(const EString & name) e2d::ETimer::ETimer(const TIMER_CALLBACK & callback, int repeatTimes /* = -1 */, LONGLONG interval /* = 0 */, bool atOnce /* = false */)
: ETimer() : ETimer()
{ {
m_sName = name; this->setCallback(callback);
this->setRepeatTimes(repeatTimes);
this->setInterval(interval);
m_bAtOnce = atOnce;
} }
e2d::ETimer::ETimer(const TIMER_CALLBACK & callback, LONGLONG delay /* = 20LL */) e2d::ETimer::ETimer(const EString & name, const TIMER_CALLBACK & callback, int repeatTimes /* = -1 */, LONGLONG interval /* = 0 */, bool atOnce /* = false */)
: ETimer() : ETimer()
{ {
m_Callback = callback; this->setName(name);
} this->setCallback(callback);
this->setRepeatTimes(repeatTimes);
e2d::ETimer::ETimer(const EString & name, const TIMER_CALLBACK & callback, LONGLONG delay /* = 20LL */) this->setInterval(interval);
: ETimer() m_bAtOnce = atOnce;
{
m_sName = name;
m_Callback = callback;
} }
bool e2d::ETimer::isRunning() const bool e2d::ETimer::isRunning() const
@ -71,6 +73,16 @@ void e2d::ETimer::setInterval(LONGLONG interval)
m_nInterval = max(interval, 0); m_nInterval = max(interval, 0);
} }
void e2d::ETimer::setCallback(const TIMER_CALLBACK & callback)
{
m_Callback = callback;
}
void e2d::ETimer::setRepeatTimes(int repeatTimes)
{
m_nRepeatTimes = repeatTimes;
}
void e2d::ETimer::bindWith(EScene * pParentScene) void e2d::ETimer::bindWith(EScene * pParentScene)
{ {
ETimerManager::bindTimer(this, pParentScene); ETimerManager::bindTimer(this, pParentScene);
@ -83,6 +95,28 @@ void e2d::ETimer::bindWith(ENode * pParentNode)
void e2d::ETimer::_callOn() void e2d::ETimer::_callOn()
{ {
if (m_nRunTimes == m_nRepeatTimes)
{
this->stop();
return;
}
m_Callback(m_nRunTimes); m_Callback(m_nRunTimes);
m_nRunTimes++; m_nRunTimes++;
} }
bool e2d::ETimer::_isReady()
{
if (m_bAtOnce && m_nRunTimes == 0)
return true;
if (m_nInterval == 0)
return true;
if (GetInterval(m_tLast) >= m_nInterval)
{
m_tLast += milliseconds(m_nInterval);
return true;
}
return false;
}

View File

@ -0,0 +1,39 @@
#include "..\etransitions.h"
#include "..\eactions.h"
#include "..\etools.h"
e2d::ETransitionEmerge::ETransitionEmerge(float emergeDuration)
: m_fEmergeDuration(emergeDuration)
{
}
void e2d::ETransitionEmerge::_setTarget(EScene * prev, EScene * next, bool & transitional)
{
// 初始化场景属性
next->getRoot()->setOpacity(0);
// 第一个场景淡出
auto action1 = new EActionFadeOut(m_fEmergeDuration);
if (prev)
{
action1->setTarget(prev->getRoot());
}
// 第二个场景淡入
auto action2 = new EActionFadeIn(m_fEmergeDuration);
action2->setTarget(next->getRoot());
// 标志动画结束
auto action3 = new EActionCallback([&, prev, next] {
transitional = false;
// 还原场景状态
if (prev)
{
prev->getRoot()->setOpacity(1);
}
next->getRoot()->setOpacity(1);
});
// 添加顺序动作
EActionManager::addAction(new EActionSequence(2, new EActionTwoAtSameTime(action1, action2), action3));
}

View File

@ -1,5 +1,6 @@
#include "..\etransitions.h" #include "..\etransitions.h"
#include "..\eactions.h" #include "..\eactions.h"
#include "..\etools.h"
e2d::ETransitionFade::ETransitionFade(float fadeOutDuration, float fadeInDuration) e2d::ETransitionFade::ETransitionFade(float fadeOutDuration, float fadeInDuration)
: m_fFadeOutDuration(fadeOutDuration) : m_fFadeOutDuration(fadeOutDuration)
@ -7,30 +8,33 @@ e2d::ETransitionFade::ETransitionFade(float fadeOutDuration, float fadeInDuratio
{ {
} }
void e2d::ETransitionFade::_setTarget(EScene * prev, EScene * next, bool & enterNextScene, bool & transitional) void e2d::ETransitionFade::_setTarget(EScene * prev, EScene * next, bool & transitional)
{ {
// 初始化场景属性
next->getRoot()->setOpacity(0);
// 第一个场景淡出 // 第一个场景淡出
auto action1 = new EActionFadeOut(m_fFadeOutDuration); auto action1 = new EActionFadeOut(m_fFadeOutDuration);
if (prev) if (prev)
{ {
action1->setTarget(prev->getRoot()); action1->setTarget(prev->getRoot());
} }
// 切换至第二场景,并将第二场景透明度设为 0
auto action2 = new EActionCallback([&, next] {
enterNextScene = true;
next->getRoot()->setOpacity(0);
});
// 第二个场景淡入 // 第二个场景淡入
auto action3 = new EActionFadeIn(m_fFadeInDuration); auto action2 = new EActionFadeIn(m_fFadeInDuration);
action3->setTarget(next->getRoot()); action2->setTarget(next->getRoot());
// 标志动画结束 // 标志动画结束
auto action4 = new EActionCallback([&] { auto action3 = new EActionCallback([&, prev, next] {
transitional = false; transitional = false;
// 还原场景状态
if (prev)
{
prev->getRoot()->setOpacity(1);
}
next->getRoot()->setOpacity(1);
}); });
// 添加顺序动作 // 添加顺序动作
EActionManager::addAction(new EActionSequence(4, action1, action2, action3, action4)); EActionManager::addAction(new EActionSequence(3, action1, action2, action3));
} }

View File

@ -0,0 +1,64 @@
#include "..\etransitions.h"
#include "..\eactions.h"
#include "..\etools.h"
e2d::ETransitionMove::ETransitionMove(float moveDuration, MOVE_DIRECT direct)
: m_fMoveDuration(moveDuration)
, m_Direct(direct)
{
}
void e2d::ETransitionMove::_setTarget(EScene * prev, EScene * next, bool & transitional)
{
// 初始化动作属性
float distPosX;
float distPosY;
if (m_Direct == MOVE_DIRECT::UP)
{
distPosX = 0;
distPosY = -EApp::getHeight();
}
else if (m_Direct == MOVE_DIRECT::DOWN)
{
distPosX = 0;
distPosY = EApp::getHeight();
}
else if (m_Direct == MOVE_DIRECT::LEFT)
{
distPosX = -EApp::getWidth();
distPosY = 0;
}
else if (m_Direct == MOVE_DIRECT::RIGHT)
{
distPosX = EApp::getWidth();
distPosY = 0;
}
// 初始化场景属性
next->getRoot()->move(-distPosX, -distPosY);
// 第一个场景移出
auto action1 = new EActionMoveBy(m_fMoveDuration, EVec(distPosX, distPosY));
if (prev)
{
action1->setTarget(prev->getRoot());
}
// 第二个场景移入
auto action2 = new EActionMoveBy(m_fMoveDuration, EVec(distPosX, distPosY));
action2->setTarget(next->getRoot());
// 标志动画结束
auto action3 = new EActionCallback([&, prev, next] {
transitional = false;
// 还原场景状态
if (prev)
{
prev->getRoot()->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2);
}
next->getRoot()->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2);
});
// 添加顺序动作
EActionManager::addAction(new EActionSequence(2, new EActionTwoAtSameTime(action1, action2), action3));
}

View File

@ -0,0 +1,40 @@
#include "..\etransitions.h"
#include "..\eactions.h"
#include "..\etools.h"
e2d::ETransitionScale::ETransitionScale(float scaleOutDuration, float scaleInDuration)
: m_fScaleOutDuration(scaleOutDuration)
, m_fScaleInDuration(scaleInDuration)
{
}
void e2d::ETransitionScale::_setTarget(EScene * prev, EScene * next, bool & transitional)
{
// 初始化场景属性
next->getRoot()->setScale(0);
// 第一个场景缩放至消失
auto action1 = new EActionScaleTo(m_fScaleOutDuration, 0);
if (prev)
{
action1->setTarget(prev->getRoot());
}
// 第二个场景淡入
auto action2 = new EActionScaleTo(m_fScaleInDuration, 1);
action2->setTarget(next->getRoot());
// 标志动画结束
auto action3 = new EActionCallback([&, prev, next] {
transitional = false;
// 还原场景状态
if (prev)
{
prev->getRoot()->setScale(1);
}
next->getRoot()->setScale(1);
});
// 添加顺序动作
EActionManager::addAction(new EActionSequence(3, action1, action2, action3));
}

View File

@ -0,0 +1,67 @@
#include "..\etransitions.h"
#include "..\eactions.h"
#include "..\etools.h"
e2d::ETransitionScaleEmerge::ETransitionScaleEmerge(float duration, SCALE_EMERGE_MODE mode)
: m_fDuration(duration)
, m_Mode(mode)
{
}
void e2d::ETransitionScaleEmerge::_setTarget(EScene * prev, EScene * next, bool & transitional)
{
float prevScaleTo;
float nextScaleStart;
if (m_Mode == SCALE_EMERGE_MODE::ENTER)
{
prevScaleTo = 1.2f;
nextScaleStart = 0.8f;
}
else
{
prevScaleTo = 0.8f;
nextScaleStart = 1.2f;
}
// 初始化场景属性
next->getRoot()->setScale(nextScaleStart);
next->getRoot()->setOpacity(0);
// 第一个场景淡出
auto prevActionFadeOut = new EActionFadeOut(m_fDuration);
auto prevActionScaleTo = new EActionScaleTo(m_fDuration, prevScaleTo);
auto action1 = new EActionTwoAtSameTime(
prevActionFadeOut,
prevActionScaleTo);
if (prev)
{
prevActionFadeOut->setTarget(prev->getRoot());
prevActionScaleTo->setTarget(prev->getRoot());
}
// 第二个场景淡入
auto nextActionFadeOut = new EActionFadeIn(m_fDuration);
auto nextActionScaleTo = new EActionScaleTo(m_fDuration, 1);
auto action2 = new EActionTwoAtSameTime(
nextActionFadeOut,
nextActionScaleTo);
nextActionFadeOut->setTarget(next->getRoot());
nextActionScaleTo->setTarget(next->getRoot());
// 标志动画结束
auto action3 = new EActionCallback([&, prev, next] {
transitional = false;
// 还原场景状态
if (prev)
{
prev->getRoot()->setScale(1);
prev->getRoot()->setOpacity(1);
}
next->getRoot()->setScale(1);
next->getRoot()->setOpacity(1);
});
// 添加顺序动作
EActionManager::addAction(new EActionSequence(2, new EActionTwoAtSameTime(action1, action2), action3));
}

View File

@ -1,10 +1,11 @@
#pragma once #pragma once
#include "enodes.h" #include "enodes.h"
#include "etools.h" #include <chrono>
namespace e2d namespace e2d
{ {
class EActionManager;
class EActionTwo; class EActionTwo;
class EActionLoop; class EActionLoop;
class EActionSequence; class EActionSequence;
@ -106,8 +107,9 @@ protected:
virtual void _reset() override; virtual void _reset() override;
protected: protected:
LONGLONG m_nDuration; float m_fDuration;
LONGLONG m_nTotalDuration; float m_fTotalDuration;
float m_fRateOfProgress;
}; };
@ -172,6 +174,12 @@ class EActionScaleBy :
public EActionGradual public EActionGradual
{ {
public: public:
// 创建相对缩放动画
EActionScaleBy(
float duration, /* 动画持续时长 */
float scale /* 缩放比例变化 */
);
// 创建相对缩放动画 // 创建相对缩放动画
EActionScaleBy( EActionScaleBy(
float duration, /* 动画持续时长 */ float duration, /* 动画持续时长 */
@ -207,6 +215,12 @@ class EActionScaleTo :
public EActionScaleBy public EActionScaleBy
{ {
public: public:
// 创建缩放动画
EActionScaleTo(
float duration, /* 动画持续时长 */
float scale /* 缩放至目标比例 */
);
// 创建缩放动画 // 创建缩放动画
EActionScaleTo( EActionScaleTo(
float duration, /* 动画持续时长 */ float duration, /* 动画持续时长 */

View File

@ -22,13 +22,6 @@ public:
virtual ~EApp(); virtual ~EApp();
enum WINDOW_STYLE
{
NO_CLOSE = 1, /* 禁用关闭按钮 */
NO_MINI_SIZE = 2, /* 禁用最小化按钮 */
TOP_MOST = 4 /* 窗口置顶 */
};
// 初始化游戏界面 // 初始化游戏界面
bool init( bool init(
const EString &title, /* 窗口标题 */ const EString &title, /* 窗口标题 */
@ -42,7 +35,7 @@ public:
const EString &title, /* 窗口标题 */ const EString &title, /* 窗口标题 */
UINT32 width, /* 窗口宽度 */ UINT32 width, /* 窗口宽度 */
UINT32 height, /* 窗口高度 */ UINT32 height, /* 窗口高度 */
int windowStyle, /* 窗口样式 */ EWindowStyle wStyle, /* ´°¿ÚÑùʽ */
bool showConsole = false/* 是否显示控制台 */ bool showConsole = false/* 是否显示控制台 */
); );
@ -115,10 +108,10 @@ public:
static EString getTitle(); static EString getTitle();
// 获取窗口宽度 // 获取窗口宽度
static UINT32 getWidth(); static float getWidth();
// 获取窗口高度 // 获取窗口高度
static UINT32 getHeight(); static float getHeight();
// 获取当前场景 // 获取当前场景
static EScene * getCurrentScene(); static EScene * getCurrentScene();
@ -207,7 +200,6 @@ protected:
bool m_bPaused; bool m_bPaused;
bool m_bManualPaused; bool m_bManualPaused;
bool m_bTransitional; bool m_bTransitional;
bool m_bEnterNextScene;
bool m_bTopMost; bool m_bTopMost;
EString m_sTitle; EString m_sTitle;
EString m_sAppName; EString m_sAppName;

View File

@ -12,6 +12,45 @@ typedef std::wstring EString;
template<typename T> template<typename T>
using EVector = std::vector<T>; using EVector = std::vector<T>;
struct EWindowStyle
{
EWindowStyle()
{
ICON_ID = 0;
NO_CLOSE = false;
NO_MINI_SIZE = false;
TOP_MOST = false;
}
EWindowStyle(
LPCTSTR ICON_ID
)
{
this->ICON_ID = ICON_ID;
NO_CLOSE = false;
NO_MINI_SIZE = false;
TOP_MOST = false;
}
EWindowStyle(
LPCTSTR ICON_ID,
bool NO_CLOSE,
bool NO_MINI_SIZE,
bool TOP_MOST
)
{
this->ICON_ID = ICON_ID;
this->NO_CLOSE = NO_CLOSE;
this->NO_MINI_SIZE = NO_MINI_SIZE;
this->TOP_MOST = TOP_MOST;
}
LPCTSTR ICON_ID; /* 程序图标 ID */
bool NO_CLOSE; /* 禁用关闭按钮 */
bool NO_MINI_SIZE; /* 禁用最小化按钮 */
bool TOP_MOST; /* 窗口置顶 */
};
struct EPoint struct EPoint
{ {
EPoint() EPoint()
@ -71,14 +110,22 @@ struct ESize
}; };
typedef std::function<void()> KEY_LISTENER_CALLBACK; // 定时器回调函数(参数为该定时器被调用的次数,从 0 开始)
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;
typedef std::function<void(int)> TIMER_CALLBACK; 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

@ -65,4 +65,7 @@ template<typename T>
inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } } inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } }
template<typename T> template<typename T>
inline void SafeRelease(T** p) { if (*p) { (*p)->autoRelease(); (*p)->release(); *p = nullptr; } } inline void SafeReleaseAndClear(T** p) { if (*p) { (*p)->autoRelease(); (*p)->release(); *p = nullptr; } }
template<typename T>
inline void SafeRelease(T** p) { if (*p) { (*p)->release(); *p = nullptr; } }

View File

@ -190,6 +190,7 @@ protected:
protected: protected:
EString m_sName; EString m_sName;
bool m_bRunning; bool m_bRunning;
bool m_bAlways;
EScene * m_pParentScene; EScene * m_pParentScene;
ENode * m_pParentNode; ENode * m_pParentNode;
}; };
@ -465,13 +466,15 @@ public:
// 绑定鼠标消息监听器到场景 // 绑定鼠标消息监听器到场景
static void bindListener( static void bindListener(
EMouseListener * listener, EMouseListener * listener,
EScene * pParentScene EScene * pParentScene,
bool always = false /* 是否在游戏暂停时仍然监听 */
); );
// 绑定鼠标消息监听器到节点 // 绑定鼠标消息监听器到节点
static void bindListener( static void bindListener(
EMouseListener * listener, EMouseListener * listener,
ENode * pParentNode ENode * pParentNode,
bool always = false /* 是否在游戏暂停时仍然监听 */
); );
// 启动具有相同名称的鼠标消息监听器 // 启动具有相同名称的鼠标消息监听器
@ -499,11 +502,6 @@ public:
EScene * pParentScene EScene * pParentScene
); );
// 清除绑定在场景及其子节点上的所有鼠标消息监听器
static void clearAllMouseListenersBindedWith(
EScene * pParentScene
);
// 启动绑定在节点上的所有鼠标消息监听器 // 启动绑定在节点上的所有鼠标消息监听器
static void startAllMouseListenersBindedWith( static void startAllMouseListenersBindedWith(
ENode * pParentNode ENode * pParentNode
@ -514,30 +512,24 @@ public:
ENode * pParentNode ENode * pParentNode
); );
// 清除绑定在节点上的所有鼠标消息监听器
static void clearAllMouseListenersBindedWith(
ENode * pParentNode
);
// 启动所有鼠标消息监听器 // 启动所有鼠标消息监听器
static void startAllMouseListeners(); static void startAllMouseListeners();
// 停止所有鼠标消息监听器 // 停止所有鼠标消息监听器
static void stopAllMouseListeners(); static void stopAllMouseListeners();
// 清除所有鼠标消息监听器
static void clearAllMouseListeners();
// 绑定按键消息监听器到场景 // 绑定按键消息监听器到场景
static void bindListener( static void bindListener(
EKeyboardListener * listener, EKeyboardListener * listener,
EScene * pParentScene EScene * pParentScene,
bool always = false /* 是否在游戏暂停时仍然监听 */
); );
// 绑定按键消息监听器到节点 // 绑定按键消息监听器到节点
static void bindListener( static void bindListener(
EKeyboardListener * listener, EKeyboardListener * listener,
ENode * pParentNode ENode * pParentNode,
bool always = false /* 是否在游戏暂停时仍然监听 */
); );
// 启动名称相同的按键消息监听器 // 启动名称相同的按键消息监听器
@ -565,11 +557,6 @@ public:
EScene * pParentScene EScene * pParentScene
); );
// 清除绑定在场景及其子节点上的所有按键消息监听器
static void clearAllKeyboardListenersBindedWith(
EScene * pParentScene
);
// 启动绑定在节点上的所有按键消息监听器 // 启动绑定在节点上的所有按键消息监听器
static void startAllKeyboardListenersBindedWith( static void startAllKeyboardListenersBindedWith(
ENode * pParentNode ENode * pParentNode
@ -580,24 +567,36 @@ public:
ENode * pParentNode ENode * pParentNode
); );
// 清除绑定在节点上的所有按键消息监听器
static void clearAllKeyboardListenersBindedWith(
ENode * pParentNode
);
// 启动所有按键消息监听器 // 启动所有按键消息监听器
static void startAllKeyboardListeners(); static void startAllKeyboardListeners();
// 停止所有按键消息监听器 // 停止所有按键消息监听器
static void stopAllKeyboardListeners(); static void stopAllKeyboardListeners();
// 清除所有按键消息监听器
static void clearAllKeyboardListeners();
private: private:
// 清除所有监听器 // 清除所有监听器
static void _clearManager(); static void _clearManager();
// 清除绑定在节点上的所有鼠标消息监听器
static void _clearAllMouseListenersBindedWith(
ENode * pParentNode
);
// 清除绑定在场景及其子节点上的所有按键消息监听器
static void _clearAllKeyboardListenersBindedWith(
EScene * pParentScene
);
// 清除绑定在场景及其子节点上的所有鼠标消息监听器
static void _clearAllMouseListenersBindedWith(
EScene * pParentScene
);
// 清除绑定在节点上的所有按键消息监听器
static void _clearAllKeyboardListenersBindedWith(
ENode * pParentNode
);
// 鼠标消息程序 // 鼠标消息程序
static void MouseProc( static void MouseProc(
UINT message, UINT message,

View File

@ -7,11 +7,13 @@ namespace e2d
class EText; class EText;
class ESprite; class ESprite;
class EAction; class EAction;
class EButton;
class ENode : class ENode :
public EObject public EObject
{ {
friend EScene; friend EScene;
friend EButton;
public: public:
ENode(); ENode();
@ -204,19 +206,19 @@ public:
); );
// 设置纵向锚点 // 设置纵向锚点
// 默认为 0, 范围 [0, 1] // 默认为 0.5f, 范围 [0, 1]
virtual void setAnchorX( virtual void setAnchorX(
float anchorX float anchorX
); );
// 设置横向锚点 // 设置横向锚点
// 默认为 0, 范围 [0, 1] // 默认为 0.5f, 范围 [0, 1]
virtual void setAnchorY( virtual void setAnchorY(
float anchorY float anchorY
); );
// 设置锚点 // 设置锚点
// 默认为 (0, 0), 范围 [0, 1] // 默认为 (0.5f, 0.5f), 范围 [0, 1]
virtual void setAnchor( virtual void setAnchor(
float anchorX, float anchorX,
float anchorY float anchorY
@ -270,6 +272,20 @@ public:
EAction * action EAction * action
); );
// 继续所有暂停动画
virtual void startAllActions();
// 暂停所有动画
virtual void pauseAllActions();
// 停止所有动画
virtual void stopAllActions();
// 判断点是否在节点内
virtual bool isPointIn(
EPoint point
);
protected: protected:
// 访问节点 // 访问节点
virtual void _callOn(); virtual void _callOn();
@ -472,6 +488,15 @@ public:
virtual ~ESpriteFrame(); virtual ~ESpriteFrame();
// 获取宽度
float getWidth() const;
// 获取高度
float getHeight() const;
// 获取纹理
ETexture * getTexture() const;
protected: protected:
// 获取纹理 // 获取纹理
void _setTexture( void _setTexture(
@ -502,6 +527,16 @@ public:
// 创建一个空精灵 // 创建一个空精灵
ESprite(); ESprite();
// 从文理资源创建精灵
ESprite(
ETexture * texture
);
// 从精灵帧创建精灵
ESprite(
ESpriteFrame * spriteFrame
);
// 从文件图片创建精灵 // 从文件图片创建精灵
ESprite( ESprite(
const EString & imageFileName const EString & imageFileName
@ -535,12 +570,12 @@ public:
virtual ~ESprite(); virtual ~ESprite();
// 设置精灵纹理 // 设置精灵纹理
void setTexture( void loadFrom(
ETexture * texture ETexture * texture
); );
// 设置精灵纹理并裁剪 // 设置精灵纹理并裁剪
void setTexture( void loadFrom(
ETexture * texture, ETexture * texture,
float x, float x,
float y, float y,
@ -548,13 +583,13 @@ public:
float height float height
); );
// 从 ESpriteFrame 加载资源 // 从精灵帧加载资源
void loadFromSpriteFrame( void loadFrom(
ESpriteFrame * frame ESpriteFrame * frame
); );
// 裁剪纹理 // 裁剪纹理
void clipTexture( void clip(
float x, float x,
float y, float y,
float width, float width,
@ -721,4 +756,92 @@ protected:
EFont * m_pFont; EFont * m_pFont;
}; };
class EButton :
public ENode
{
public:
// 创建一个空按钮
EButton();
// 创建按钮
EButton(
ENode * normal,
const BUTTON_CLICK_CALLBACK & callback
);
// 创建按钮
EButton(
ENode * normal,
ENode * selected,
const BUTTON_CLICK_CALLBACK & callback
);
// 创建按钮
EButton(
ENode * normal,
ENode * mouseover,
ENode * selected,
const BUTTON_CLICK_CALLBACK & callback
);
// 创建按钮
EButton(
ENode * normal,
ENode * mouseover,
ENode * selected,
ENode * disabled,
const BUTTON_CLICK_CALLBACK & callback
);
// 设置一般情况下显示的按钮
void setNormal(
ENode * normal
);
// 设置鼠标移入按钮时显示的按钮
void setMouseOver(
ENode * mouseover
);
// 设置鼠标选中按钮时显示的按钮
void setSelected(
ENode * selected
);
// 设置按钮被禁用时显示的按钮
void setDisabled(
ENode * disabled
);
// 设置按钮禁用
void setDisable(
bool disable
);
// 设置回调函数
void setCallback(
const BUTTON_CLICK_CALLBACK & callback
);
protected:
// 渲染按钮
virtual void _callOn() override;
// 鼠标消息监听
void _listenerCallback();
protected:
enum STATUS { NORMAL, MOUSEOVER, SELECTED, DISABLED };
STATUS m_eStatus;
ENode * m_pNormal;
ENode * m_pMouseover;
ENode * m_pSelected;
ENode * m_pDisabled;
ENode * m_pDisplayed;
bool m_bIsDisable;
bool m_bIsSelected;
BUTTON_CLICK_CALLBACK m_Callback;
};
} }

View File

@ -41,28 +41,28 @@ class ETimer :
public: public:
ETimer(); ETimer();
ETimer(
const EString &name /* 定时器名称 */
);
ETimer( ETimer(
const TIMER_CALLBACK &callback, /* 定时器回调函数 */ const TIMER_CALLBACK &callback, /* 定时器回调函数 */
LONGLONG delay = 20LL /* 时间间隔 */ int repeatTimes = -1, /* 定时器执行次数 */
LONGLONG interval = 0LL, /* 时间间隔(毫秒) */
bool atOnce = false /* 是否立即执行 */
); );
ETimer( ETimer(
const EString &name, /* 定时器名称 */ const EString &name, /* 定时器名称 */
const TIMER_CALLBACK &callback, /* 定时器回调函数 */ const TIMER_CALLBACK &callback, /* 定时器回调函数 */
LONGLONG delay = 20LL /* 时间间隔 */ int repeatTimes = -1, /* 定时器执行次数 */
LONGLONG interval = 0LL, /* 时间间隔(毫秒) */
bool atOnce = false /* 是否立即执行 */
); );
// 获取定时器状态 // 获取定时器状态
bool isRunning() const; bool isRunning() const;
// 启动监听 // 启动定时器
void start(); void start();
// 停止监听 // 停止定时器
void stop(); void stop();
// 获取定时器名称 // 获取定时器名称
@ -84,6 +84,16 @@ public:
LONGLONG interval LONGLONG interval
); );
// 设置定时器回调函数
void setCallback(
const TIMER_CALLBACK & callback
);
// 设置定时器重复执行次数
void setRepeatTimes(
int repeatTimes
);
// 绑定定时器到场景 // 绑定定时器到场景
virtual void bindWith( virtual void bindWith(
EScene * pParentScene EScene * pParentScene
@ -98,10 +108,15 @@ protected:
// 执行回调函数 // 执行回调函数
virtual void _callOn(); virtual void _callOn();
// 判断是否达到执行状态
bool _isReady();
protected: protected:
EString m_sName; EString m_sName;
bool m_bRunning; bool m_bRunning;
bool m_bAtOnce;
int m_nRunTimes; int m_nRunTimes;
int m_nRepeatTimes;
EScene * m_pParentScene; EScene * m_pParentScene;
ENode * m_pParentNode; ENode * m_pParentNode;
TIMER_CALLBACK m_Callback; TIMER_CALLBACK m_Callback;
@ -155,11 +170,6 @@ public:
EScene * pParentScene EScene * pParentScene
); );
// 清空绑定在场景及其子节点上的所有定时器
static void clearAllTimersBindedWith(
EScene * pParentScene
);
// 启动绑定在节点上的所有定时器 // 启动绑定在节点上的所有定时器
static void startAllTimersBindedWith( static void startAllTimersBindedWith(
ENode * pParentNode ENode * pParentNode
@ -170,24 +180,26 @@ public:
ENode * pParentNode ENode * pParentNode
); );
// 清空绑定在节点上的所有定时器
static void clearAllTimersBindedWith(
ENode * pParentNode
);
// 启动所有定时器 // 启动所有定时器
static void startAllTimers(); static void startAllTimers();
// 停止所有定时器 // 停止所有定时器
static void stopAllTimers(); static void stopAllTimers();
// 清除所有定时器
static void clearAllTimers();
private: private:
// 清空定时器管理器 // 清空定时器管理器
static void _clearManager(); static void _clearManager();
// 清空绑定在场景及其子节点上的所有定时器
static void _clearAllTimersBindedWith(
EScene * pParentScene
);
// 清空绑定在节点上的所有定时器
static void _clearAllTimersBindedWith(
ENode * pParentNode
);
// 重置定时器状态 // 重置定时器状态
static void _resetAllTimers(); static void _resetAllTimers();
@ -209,23 +221,13 @@ public:
EAction * action EAction * action
); );
// 启动绑定在场景子节点上的所有动作 // 继续绑定在节点上的所有动作
static void startAllActionsBindedWith( static void startAllActionsBindedWith(
EScene * pParentScene ENode * pTargetNode
); );
// 停止绑定在场景子节点上的所有动作 // 暂停绑定在节点上的所有动作
static void stopAllActionsBindedWith( static void pauseAllActionsBindedWith(
EScene * pParentScene
);
// 清空绑定在场景子节点上的所有动作
static void clearAllActionsBindedWith(
EScene * pParentScene
);
// 启动绑定在节点上的所有动作
static void startAllActionsBindedWith(
ENode * pTargetNode ENode * pTargetNode
); );
@ -234,24 +236,24 @@ public:
ENode * pTargetNode ENode * pTargetNode
); );
// 清空绑定在节点上的所有动作 // 继续所有动作
static void clearAllActionsBindedWith(
ENode * pTargetNode
);
// 启动所有动作
static void startAllActions(); static void startAllActions();
// 暂停所有动作
static void pauseAllActions();
// 停止所有动作 // 停止所有动作
static void stopAllActions(); static void stopAllActions();
// 清除所有动作
static void clearAllActions();
private: private:
// 清空动画管理器 // 清空动画管理器
static void _clearManager(); static void _clearManager();
// 清空绑定在节点上的所有动作
static void _clearAllActionsBindedWith(
ENode * pTargetNode
);
// 重置所有动作状态 // 重置所有动作状态
static void _resetAllActions(); static void _resetAllActions();
@ -260,14 +262,6 @@ private:
}; };
class EMusicUtils
{
public:
// 播放音效
static void play(LPCTSTR musicFileName, bool loop = false);
};
class EFileUtils class EFileUtils
{ {
public: public:
@ -311,7 +305,22 @@ class ERandom
public: public:
// 取得整型范围内的一个随机数 // 取得整型范围内的一个随机数
template<typename T> template<typename T>
static T randomInt(T min, T max) static inline T between(T min, T max) { return e2d::ERandom::randomInt(min, max); }
// 取得浮点数范围内的一个随机数
static inline float between(float min, float max) { return e2d::ERandom::randomReal(min, max); }
// 取得浮点数范围内的一个随机数
static inline double between(double min, double max) { return e2d::ERandom::randomReal(min, max); }
// 取得浮点数范围内的一个随机数
static inline long double between(long double min, long double max) { return e2d::ERandom::randomReal(min, max); }
// 取得整型范围内的一个随机数
template<typename T>
static T randomInt(
T min,
T max)
{ {
std::uniform_int_distribution<T> dist(min, max); std::uniform_int_distribution<T> dist(min, max);
return dist(getEngine()); return dist(getEngine());
@ -319,7 +328,9 @@ public:
// 取得浮点数类型范围内的一个随机数 // 取得浮点数类型范围内的一个随机数
template<typename T> template<typename T>
static T randomReal(T min, T max) static T randomReal(
T min,
T max)
{ {
std::uniform_real_distribution<T> dist(min, max); std::uniform_real_distribution<T> dist(min, max);
return dist(getEngine()); return dist(getEngine());
@ -329,10 +340,4 @@ public:
static std::default_random_engine &getEngine(); static std::default_random_engine &getEngine();
}; };
template<typename T>
inline T random(T min, T max) { return e2d::ERandom::randomInt(min, max); }
inline float random(float min, float max) { return e2d::ERandom::randomReal(min, max); }
inline double random(double min, double max) { return e2d::ERandom::randomReal(min, max); }
inline long double random(long double min, long double max) { return e2d::ERandom::randomReal(min, max); }
} }

View File

@ -9,14 +9,13 @@ class ETransition :
{ {
friend EApp; friend EApp;
public: public:
ETransition() {} ETransition() { this->autoRelease(); }
protected: protected:
// 保存当前场景和下一场景的指针,和控制场景切换的变量 // 保存当前场景和下一场景的指针,和控制场景切换的变量
virtual void _setTarget( virtual void _setTarget(
EScene * prev, EScene * prev,
EScene * next, EScene * next,
bool &enterNextScene,
bool &transitional bool &transitional
) = 0; ) = 0;
}; };
@ -37,7 +36,6 @@ protected:
virtual void _setTarget( virtual void _setTarget(
EScene * prev, EScene * prev,
EScene * next, EScene * next,
bool &enterNextScene,
bool &transitional bool &transitional
) override; ) override;
@ -46,4 +44,112 @@ protected:
float m_fFadeInDuration; float m_fFadeInDuration;
}; };
class ETransitionEmerge :
public ETransition
{
public:
// 创建浮现式的场景切换动画
ETransitionEmerge(
float emergeDuration /* 浮现动画持续时长 */
);
protected:
// 保存当前场景和下一场景的指针,和控制场景切换的变量
virtual void _setTarget(
EScene * prev,
EScene * next,
bool &transitional
) override;
protected:
float m_fEmergeDuration;
};
class ETransitionMove :
public ETransition
{
public:
enum MOVE_DIRECT
{
UP,
DOWN,
LEFT,
RIGHT
};
// 创建移动式的场景切换动画
ETransitionMove(
float moveDuration, /* 场景移动动画持续时长 */
MOVE_DIRECT direct /* 场景移动方向 */
);
protected:
// 保存当前场景和下一场景的指针,和控制场景切换的变量
virtual void _setTarget(
EScene * prev,
EScene * next,
bool &transitional
) override;
protected:
float m_fMoveDuration;
MOVE_DIRECT m_Direct;
};
class ETransitionScale :
public ETransition
{
public:
// 创建缩放式的场景切换动画
ETransitionScale(
float scaleOutDuration, /* 第一个场景缩放动画持续时长 */
float scaleInDuration /* 第二个场景缩放动画持续时长 */
);
protected:
// 保存当前场景和下一场景的指针,和控制场景切换的变量
virtual void _setTarget(
EScene * prev,
EScene * next,
bool &transitional
) override;
protected:
float m_fScaleOutDuration;
float m_fScaleInDuration;
};
class ETransitionScaleEmerge :
public ETransition
{
public:
enum SCALE_EMERGE_MODE
{
ENTER,
BACK
};
// 创建缩放浮现式的场景切换动画
ETransitionScaleEmerge(
float duration, /* 场景动画持续时长 */
SCALE_EMERGE_MODE mode /* 场景移动方向 */
);
protected:
// 保存当前场景和下一场景的指针,和控制场景切换的变量
virtual void _setTarget(
EScene * prev,
EScene * next,
bool &transitional
) override;
protected:
float m_fDuration;
SCALE_EMERGE_MODE m_Mode;
};
} }