From 9fa60891a401186f4b492d19cbac9e633d61d897 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Sat, 21 Oct 2017 19:09:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E8=8B=A5=E5=B9=B2BU?= =?UTF-8?q?G?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/main.cpp | 45 ++-- Easy2D/Action/EAction.cpp | 4 + Easy2D/Action/EActionDelay.cpp | 4 - Easy2D/Action/EActionGradual.cpp | 17 +- Easy2D/Action/EActionLoop.cpp | 2 +- Easy2D/Action/EActionMoveBy.cpp | 12 +- Easy2D/Action/EActionMoveTo.cpp | 2 +- Easy2D/Action/EActionOpacityBy.cpp | 10 +- Easy2D/Action/EActionOpacityTo.cpp | 2 +- Easy2D/Action/EActionRotateBy.cpp | 10 +- Easy2D/Action/EActionRotateTo.cpp | 6 +- Easy2D/Action/EActionScaleBy.cpp | 23 +- Easy2D/Action/EActionScaleTo.cpp | 13 +- Easy2D/Action/EActionSequence.cpp | 7 +- Easy2D/Action/EActionTwo.cpp | 4 +- Easy2D/Action/EActionTwoAtSameTime.cpp | 4 +- Easy2D/Action/EAnimation.cpp | 14 +- Easy2D/Base/EApp.cpp | 114 +++++----- Easy2D/Base/EObject.cpp | 4 +- Easy2D/Base/EScene.cpp | 11 +- Easy2D/Easy2D.vcxproj | 10 +- Easy2D/Easy2D.vcxproj.filters | 24 ++- Easy2D/Listener/EListener.cpp | 1 + Easy2D/Manager/EActionManager.cpp | 87 ++++---- Easy2D/Manager/EMsgManager.cpp | 78 +++---- Easy2D/Manager/ETimerManager.cpp | 68 +++--- Easy2D/Node/EButton.cpp | 212 +++++++++++++++++++ Easy2D/Node/ENode.cpp | 76 ++++++- Easy2D/Node/ESprite.cpp | 62 ++++-- Easy2D/Node/ESpriteFrame.cpp | 25 ++- Easy2D/Node/EText.cpp | 8 +- Easy2D/Tool/EMusicUtils.cpp | 5 - Easy2D/{ => Tool}/ETimer.cpp | 62 ++++-- Easy2D/Transition/ETransitionEmerge.cpp | 39 ++++ Easy2D/Transition/ETransitionFade.cpp | 26 ++- Easy2D/Transition/ETransitionMove.cpp | 64 ++++++ Easy2D/Transition/ETransitionScale.cpp | 40 ++++ Easy2D/Transition/ETransitionScaleEmerge.cpp | 67 ++++++ Easy2D/eactions.h | 20 +- Easy2D/ebase.h | 14 +- Easy2D/ecommon.h | 61 +++++- Easy2D/emacros.h | 5 +- Easy2D/emsg.h | 59 +++--- Easy2D/enodes.h | 139 +++++++++++- Easy2D/etools.h | 125 +++++------ Easy2D/etransitions.h | 112 +++++++++- 46 files changed, 1313 insertions(+), 484 deletions(-) create mode 100644 Easy2D/Node/EButton.cpp rename Easy2D/{ => Tool}/ETimer.cpp (51%) create mode 100644 Easy2D/Transition/ETransitionEmerge.cpp create mode 100644 Easy2D/Transition/ETransitionMove.cpp create mode 100644 Easy2D/Transition/ETransitionScale.cpp create mode 100644 Easy2D/Transition/ETransitionScaleEmerge.cpp diff --git a/Demo/main.cpp b/Demo/main.cpp index 1e72f796..04a6cfc6 100644 --- a/Demo/main.cpp +++ b/Demo/main.cpp @@ -10,20 +10,11 @@ int WINAPI WinMain( { 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 scene2 = new EScene(); - auto listener = new EKeyboardPressListener([=]() { - 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"); + auto text = new EText(L"中文测试中文测试中文测试中文测试中文测试中文测试中文测试", EColor::WHITE, L"楷体"); text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); //text->setWordWrapping(true); //text->setWordWrappingWidth(130); @@ -31,9 +22,18 @@ int WINAPI WinMain( text->getFont()->setItalic(true); text->setAnchor(0.5f, 0.5f); text->setColor(EColor::WHITE); + //text->runAction(new EActionLoop(new EActionTwo(new EActionFadeOut(1), new EActionFadeIn(1)))); 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 animation = new EAnimation(); @@ -45,15 +45,26 @@ int WINAPI WinMain( bird->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); scene2->add(bird); - auto listener2 = new EKeyboardPressListener([=]() { - if (EKeyboardMsg::getVal() == EKeyboardMsg::KEY::SPACE) + auto btnStart = new ESprite(L"atlas.png", 702, 234, 116, 70); + 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(); } diff --git a/Easy2D/Action/EAction.cpp b/Easy2D/Action/EAction.cpp index 9eee2cb8..40899116 100644 --- a/Easy2D/Action/EAction.cpp +++ b/Easy2D/Action/EAction.cpp @@ -75,10 +75,14 @@ e2d::ENode * e2d::EAction::getTarget() void e2d::EAction::_init() { m_bInit = true; + // 记录当前时间 + m_tLast = GetNow(); } void e2d::EAction::_reset() { m_bInit = false; m_bEnding = false; + // 记录当前时间 + m_tLast = GetNow(); } diff --git a/Easy2D/Action/EActionDelay.cpp b/Easy2D/Action/EActionDelay.cpp index d51ef460..629ac683 100644 --- a/Easy2D/Action/EActionDelay.cpp +++ b/Easy2D/Action/EActionDelay.cpp @@ -14,8 +14,6 @@ e2d::EActionDelay * e2d::EActionDelay::clone() const void e2d::EActionDelay::_init() { EAction::_init(); - // 记录当前时间 - m_tLast = GetNow(); } void e2d::EActionDelay::_callOn() @@ -30,6 +28,4 @@ void e2d::EActionDelay::_callOn() void e2d::EActionDelay::_reset() { EAction::_reset(); - // 记录当前时间 - m_tLast = GetNow(); } diff --git a/Easy2D/Action/EActionGradual.cpp b/Easy2D/Action/EActionGradual.cpp index c9a67236..1d449179 100644 --- a/Easy2D/Action/EActionGradual.cpp +++ b/Easy2D/Action/EActionGradual.cpp @@ -2,21 +2,20 @@ #include "..\Win\winbase.h" 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 { - return m_nDuration >= m_nTotalDuration; + return m_fDuration >= m_fTotalDuration; } void e2d::EActionGradual::_init() { EAction::_init(); - // 记录当前时间 - m_tLast = GetNow(); } bool e2d::EActionGradual::_isDelayEnough() @@ -26,7 +25,9 @@ bool e2d::EActionGradual::_isDelayEnough() { // 重新记录时间 m_tLast += milliseconds(m_nAnimationInterval); - m_nDuration += m_nAnimationInterval; + m_fDuration += static_cast(m_nAnimationInterval); + // 计算动画进度 + m_fRateOfProgress = m_fDuration / m_fTotalDuration; return true; } return false; @@ -35,7 +36,5 @@ bool e2d::EActionGradual::_isDelayEnough() void e2d::EActionGradual::_reset() { EAction::_reset(); - m_nDuration = 0; - // 记录当前时间 - m_tLast = GetNow(); + m_fDuration = 0; } diff --git a/Easy2D/Action/EActionLoop.cpp b/Easy2D/Action/EActionLoop.cpp index eb2bfd11..a85db44f 100644 --- a/Easy2D/Action/EActionLoop.cpp +++ b/Easy2D/Action/EActionLoop.cpp @@ -8,7 +8,7 @@ e2d::EActionLoop::EActionLoop(EAction * action) : e2d::EActionLoop::~EActionLoop() { - SafeRelease(&m_Action); + SafeReleaseAndClear(&m_Action); } e2d::EActionLoop * e2d::EActionLoop::clone() const diff --git a/Easy2D/Action/EActionMoveBy.cpp b/Easy2D/Action/EActionMoveBy.cpp index 7a2fdace..5f6cd930 100644 --- a/Easy2D/Action/EActionMoveBy.cpp +++ b/Easy2D/Action/EActionMoveBy.cpp @@ -25,12 +25,10 @@ void e2d::EActionMoveBy::_callOn() } while (EActionGradual::_isDelayEnough()) { - // 计算移动位置 - float scale = static_cast(m_nDuration) / m_nTotalDuration; - // 移动 Sprite + // 移动节点 m_pTarget->setPos( - m_BeginPos.x + m_MoveVector.x * scale, - m_BeginPos.y + m_MoveVector.y * scale + m_BeginPos.x + m_MoveVector.x * m_fRateOfProgress, + m_BeginPos.y + m_MoveVector.y * m_fRateOfProgress ); // 判断动作是否结束 if (_isEnd()) @@ -48,10 +46,10 @@ void e2d::EActionMoveBy::_reset() 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 { - 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)); } \ No newline at end of file diff --git a/Easy2D/Action/EActionMoveTo.cpp b/Easy2D/Action/EActionMoveTo.cpp index 26980ea4..08a025e8 100644 --- a/Easy2D/Action/EActionMoveTo.cpp +++ b/Easy2D/Action/EActionMoveTo.cpp @@ -8,7 +8,7 @@ e2d::EActionMoveTo::EActionMoveTo(float duration, EPoint pos) : 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() diff --git a/Easy2D/Action/EActionOpacityBy.cpp b/Easy2D/Action/EActionOpacityBy.cpp index 6b66265e..6ac9e3de 100644 --- a/Easy2D/Action/EActionOpacityBy.cpp +++ b/Easy2D/Action/EActionOpacityBy.cpp @@ -25,10 +25,8 @@ void e2d::EActionOpacityBy::_callOn() } while (EActionGradual::_isDelayEnough()) { - // 计算移动位置 - float scale = static_cast(m_nDuration) / m_nTotalDuration; - // 移动 Sprite - m_pTarget->setOpacity(m_nBeginVal + m_nVariation * scale); + // 设置节点透明度 + m_pTarget->setOpacity(m_nBeginVal + m_nVariation * m_fRateOfProgress); // 判断动作是否结束 if (_isEnd()) { @@ -45,10 +43,10 @@ void e2d::EActionOpacityBy::_reset() 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 { - return new EActionOpacityBy(m_nTotalDuration / 1000.0f, -m_nVariation); + return new EActionOpacityBy(m_fTotalDuration / 1000, -m_nVariation); } \ No newline at end of file diff --git a/Easy2D/Action/EActionOpacityTo.cpp b/Easy2D/Action/EActionOpacityTo.cpp index 40ddc809..71ca0265 100644 --- a/Easy2D/Action/EActionOpacityTo.cpp +++ b/Easy2D/Action/EActionOpacityTo.cpp @@ -9,7 +9,7 @@ e2d::EActionOpacityTo::EActionOpacityTo(float duration, float opacity) : 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() diff --git a/Easy2D/Action/EActionRotateBy.cpp b/Easy2D/Action/EActionRotateBy.cpp index 9ac061a5..52828138 100644 --- a/Easy2D/Action/EActionRotateBy.cpp +++ b/Easy2D/Action/EActionRotateBy.cpp @@ -25,10 +25,8 @@ void e2d::EActionRotateBy::_callOn() } while (EActionGradual::_isDelayEnough()) { - // 计算移动位置 - float scale = static_cast(m_nDuration) / m_nTotalDuration; - // 移动 Sprite - m_pTarget->setRotation(m_nBeginVal + m_nVariation * scale); + // 旋转节点 + m_pTarget->setRotation(m_nBeginVal + m_nVariation * m_fRateOfProgress); // 判断动作是否结束 if (_isEnd()) { @@ -45,10 +43,10 @@ void e2d::EActionRotateBy::_reset() 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 { - return new EActionRotateBy(m_nTotalDuration / 1000.0f, -m_nVariation); + return new EActionRotateBy(m_fTotalDuration / 1000, -m_nVariation); } \ No newline at end of file diff --git a/Easy2D/Action/EActionRotateTo.cpp b/Easy2D/Action/EActionRotateTo.cpp index 93ef3f64..49da2153 100644 --- a/Easy2D/Action/EActionRotateTo.cpp +++ b/Easy2D/Action/EActionRotateTo.cpp @@ -1,15 +1,15 @@ #include "..\eactions.h" -e2d::EActionRotateTo::EActionRotateTo(float duration, float opacity) : +e2d::EActionRotateTo::EActionRotateTo(float duration, float rotation) : EActionRotateBy(duration, 0) { - m_nEndVal = opacity; + m_nEndVal = rotation; } 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() diff --git a/Easy2D/Action/EActionScaleBy.cpp b/Easy2D/Action/EActionScaleBy.cpp index 18110d14..0bf1178b 100644 --- a/Easy2D/Action/EActionScaleBy.cpp +++ b/Easy2D/Action/EActionScaleBy.cpp @@ -1,8 +1,15 @@ #include "..\eactions.h" -e2d::EActionScaleBy::EActionScaleBy(float duration, float scaleX, float scaleY) : - EActionGradual(duration) +e2d::EActionScaleBy::EActionScaleBy(float duration, float scale) + : EActionGradual(duration) +{ + m_nVariationX = scale; + m_nVariationY = scale; +} + +e2d::EActionScaleBy::EActionScaleBy(float duration, float scaleX, float scaleY) + : EActionGradual(duration) { m_nVariationX = scaleX; m_nVariationY = scaleY; @@ -27,10 +34,10 @@ void e2d::EActionScaleBy::_callOn() } while (EActionGradual::_isDelayEnough()) { - // 计算移动位置 - float scale = static_cast(m_nDuration) / m_nTotalDuration; - // 移动 Sprite - m_pTarget->setScale(m_nBeginScaleX + m_nVariationX * scale, m_nBeginScaleX + m_nVariationX * scale); + // 缩放节点 + m_pTarget->setScale( + m_nBeginScaleX + m_nVariationX * m_fRateOfProgress, + m_nBeginScaleX + m_nVariationX * m_fRateOfProgress); // 判断动作是否结束 if (_isEnd()) { @@ -47,10 +54,10 @@ void e2d::EActionScaleBy::_reset() 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 { - return new EActionScaleBy(m_nTotalDuration / 1000.0f, -m_nVariationX, -m_nVariationY); + return new EActionScaleBy(m_fTotalDuration / 1000, -m_nVariationX, -m_nVariationY); } \ No newline at end of file diff --git a/Easy2D/Action/EActionScaleTo.cpp b/Easy2D/Action/EActionScaleTo.cpp index ec2fd4a3..f117e65e 100644 --- a/Easy2D/Action/EActionScaleTo.cpp +++ b/Easy2D/Action/EActionScaleTo.cpp @@ -1,7 +1,14 @@ #include "..\eactions.h" -e2d::EActionScaleTo::EActionScaleTo(float duration, float scaleX, float scaleY) : - EActionScaleBy(duration, 0, 0) +e2d::EActionScaleTo::EActionScaleTo(float duration, float scale) + : 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_nEndScaleY = scaleY; @@ -9,7 +16,7 @@ e2d::EActionScaleTo::EActionScaleTo(float duration, float scaleX, float scaleY) 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() diff --git a/Easy2D/Action/EActionSequence.cpp b/Easy2D/Action/EActionSequence.cpp index 8fc2c5d6..0dd3b266 100644 --- a/Easy2D/Action/EActionSequence.cpp +++ b/Easy2D/Action/EActionSequence.cpp @@ -25,7 +25,7 @@ e2d::EActionSequence::~EActionSequence() { for (auto action : m_vActions) { - SafeRelease(&action); + SafeReleaseAndClear(&action); } } @@ -49,9 +49,10 @@ void e2d::EActionSequence::_init() 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++; if (m_nActionIndex == m_vActions.size()) diff --git a/Easy2D/Action/EActionTwo.cpp b/Easy2D/Action/EActionTwo.cpp index e2f29af4..ec566137 100644 --- a/Easy2D/Action/EActionTwo.cpp +++ b/Easy2D/Action/EActionTwo.cpp @@ -10,8 +10,8 @@ e2d::EActionTwo::EActionTwo(EAction * actionFirst, EAction * actionSecond) : e2d::EActionTwo::~EActionTwo() { - SafeRelease(&m_pFirstAction); - SafeRelease(&m_pSecondAction); + SafeReleaseAndClear(&m_pFirstAction); + SafeReleaseAndClear(&m_pSecondAction); } e2d::EActionTwo * e2d::EActionTwo::clone() const diff --git a/Easy2D/Action/EActionTwoAtSameTime.cpp b/Easy2D/Action/EActionTwoAtSameTime.cpp index c9a5ed08..81e42ec1 100644 --- a/Easy2D/Action/EActionTwoAtSameTime.cpp +++ b/Easy2D/Action/EActionTwoAtSameTime.cpp @@ -10,8 +10,8 @@ e2d::EActionTwoAtSameTime::EActionTwoAtSameTime(EAction * actionFirst, EAction * e2d::EActionTwoAtSameTime::~EActionTwoAtSameTime() { - SafeRelease(&m_pFirstAction); - SafeRelease(&m_pSecondAction); + SafeReleaseAndClear(&m_pFirstAction); + SafeReleaseAndClear(&m_pSecondAction); } e2d::EActionTwoAtSameTime * e2d::EActionTwoAtSameTime::clone() const diff --git a/Easy2D/Action/EAnimation.cpp b/Easy2D/Action/EAnimation.cpp index f6a3ff77..349d11fe 100644 --- a/Easy2D/Action/EAnimation.cpp +++ b/Easy2D/Action/EAnimation.cpp @@ -19,20 +19,13 @@ e2d::EAnimation::~EAnimation() { for (auto frame : m_vFrames) { - SafeRelease(&frame); + SafeReleaseAndClear(&frame); } } void e2d::EAnimation::_init() { - // 判断执行帧动画的目标类型是否是 ESprite - ASSERT( - typeid(ESprite) == typeid(*m_pTarget), - "Only ESprite can use EAnimation!" - ); EAction::_init(); - // 记录当前时间 - m_tLast = GetNow(); } void e2d::EAnimation::_callOn() @@ -47,7 +40,8 @@ void e2d::EAnimation::_callOn() { // 重新记录时间 m_tLast += milliseconds(m_nAnimationInterval); - reinterpret_cast(m_pTarget)->loadFromSpriteFrame(m_vFrames[m_nFrameIndex]); + // 加载精灵帧 + reinterpret_cast(m_pTarget)->loadFrom(m_vFrames[m_nFrameIndex]); m_nFrameIndex++; // 判断动作是否结束 if (m_nFrameIndex == m_vFrames.size()) @@ -62,8 +56,6 @@ void e2d::EAnimation::_reset() { EAction::_reset(); m_nFrameIndex = 0; - // 记录当前时间 - m_tLast = steady_clock::now(); } void e2d::EAnimation::addFrame(ESpriteFrame * frame) diff --git a/Easy2D/Base/EApp.cpp b/Easy2D/Base/EApp.cpp index 7552e6ab..8cb0da97 100644 --- a/Easy2D/Base/EApp.cpp +++ b/Easy2D/Base/EApp.cpp @@ -25,7 +25,6 @@ e2d::EApp::EApp() , m_bPaused(false) , m_bManualPaused(false) , m_bTransitional(false) - , m_bEnterNextScene(true) , m_bTopMost(false) , nAnimationInterval(17LL) , 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 */) { - 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; @@ -76,7 +75,7 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind // 注册窗口类 WNDCLASSEX wcex = { sizeof(WNDCLASSEX) }; UINT style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - if (windowStyle & EApp::NO_CLOSE) + if (wStyle.NO_CLOSE) { style |= CS_NOCLOSE; } @@ -89,6 +88,10 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind wcex.lpszMenuName = NULL; wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION); 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); @@ -119,14 +122,12 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind rtWindow.bottom = rtWindow.top + height; // 创建窗口样式 DWORD dwStyle = WS_OVERLAPPED | WS_SYSMENU; - if (windowStyle & EApp::NO_MINI_SIZE) + if (!wStyle.NO_MINI_SIZE) { - dwStyle &= ~WS_MINIMIZEBOX; - } - if (windowStyle & EApp::TOP_MOST) - { - m_bTopMost = true; + dwStyle |= WS_MINIMIZEBOX; } + // 保存窗口是否置顶显示 + m_bTopMost = wStyle.TOP_MOST; // 计算客户区大小 AdjustWindowRectEx(&rtWindow, dwStyle, FALSE, 0L); // 保存窗口名称 @@ -178,6 +179,9 @@ void e2d::EApp::resume() { EApp::get()->m_bPaused = false; EApp::get()->m_bManualPaused = false; + // 刷新当前时间 + GetNow() = steady_clock::now(); + // 重置动画和定时器 EActionManager::_resetAllActions(); ETimerManager::_resetAllTimers(); } @@ -298,9 +302,10 @@ void e2d::EApp::_mainLoop() static LONGLONG nInterval = 0LL; // 挂起时长 static LONGLONG nWaitMS = 0L; - // 刷新计时 + // 上一帧画面绘制时间 static steady_clock::time_point tLast = steady_clock::now(); + // 刷新当前时间 GetNow() = steady_clock::now(); // 计算时间间隔 nInterval = GetInterval(tLast); @@ -308,7 +313,7 @@ void e2d::EApp::_mainLoop() if (nInterval >= nAnimationInterval) { // 记录当前时间 - tLast = GetNow(); + tLast += microseconds(nAnimationInterval); // 游戏控制流程 _onControl(); // 刷新游戏画面 @@ -328,19 +333,22 @@ void e2d::EApp::_mainLoop() void e2d::EApp::_onControl() { - // 下一场景指针不为空时,切换场景 - if (m_bEnterNextScene) - { - // 进入下一场景 - _enterNextScene(); - m_bEnterNextScene = false; - } - - // 正在切换场景时,只执行动画 + // 正在切换场景时,执行场景切换动画 if (m_bTransitional) { 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)); // 绘制当前场景 - m_pCurrentScene->_onRender(); + if (m_pCurrentScene) + { + m_pCurrentScene->_onRender(); + } + // 切换场景时,同时绘制两场景 + if (m_bTransitional && m_pNextScene) + { + m_pNextScene->_onRender(); + } // 终止绘图 hr = GetRenderTarget()->EndDraw(); // 刷新界面 @@ -418,14 +434,14 @@ e2d::EString e2d::EApp::getTitle() 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 */) @@ -450,7 +466,6 @@ void e2d::EApp::enterScene(EScene * scene, ETransition * transition, bool saveCu transition->_setTarget( get()->m_pCurrentScene, get()->m_pNextScene, - get()->m_bEnterNextScene, get()->m_bTransitional ); } @@ -483,7 +498,6 @@ void e2d::EApp::backScene(ETransition * transition) transition->_setTarget( get()->m_pCurrentScene, get()->m_pNextScene, - get()->m_bEnterNextScene, get()->m_bTransitional ); } @@ -499,7 +513,7 @@ void e2d::EApp::clearScene() while (s_SceneStack.size()) { auto temp = s_SceneStack.top(); - SafeRelease(&temp); + SafeReleaseAndClear(&temp); s_SceneStack.pop(); } } @@ -569,19 +583,9 @@ void e2d::EApp::showWindow() void e2d::EApp::_free() { - // 清空场景栈 - clearScene(); - // 释放场景内存 - SafeRelease(&m_pCurrentScene); - SafeRelease(&m_pNextScene); - // 删除图片缓存 ETexture::clearCache(); - // 停止所有定时器、监听器、动画 - ETimerManager::_clearManager(); - EMsgManager::_clearManager(); - EActionManager::_clearManager(); - // 删除所有对象 + // 删除所有对象(包括所有场景、定时器、监听器、动画) EObjectManager::clearAllObjects(); } @@ -612,7 +616,7 @@ void e2d::EApp::_enterNextScene() } 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: { // 执行场景切换时屏蔽按键和鼠标消息 - if (!pEApp->m_bTransitional) + if (!pEApp->m_bTransitional && !pEApp->m_pNextScene) { EMsgManager::MouseProc(message, wParam, lParam); } @@ -735,7 +739,7 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam case WM_KEYUP: { // 执行场景切换时屏蔽按键和鼠标消息 - if (!pEApp->m_bTransitional) + if (!pEApp->m_bTransitional && !pEApp->m_pNextScene) { 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 (pEApp->getCurrentScene()->onInactive() && + if (pEApp->getCurrentScene() && + pEApp->getCurrentScene()->onInactive() && pEApp->onInactive()) { pEApp->m_bPaused = true; @@ -788,7 +793,8 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam } else { - if (pEApp->getCurrentScene()->onActivate() && + if (pEApp->getCurrentScene() && + pEApp->getCurrentScene()->onActivate() && pEApp->onActivate()) { pEApp->m_bPaused = false; @@ -802,10 +808,20 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam // 窗口关闭消息 case WM_CLOSE: { - if (pEApp->getCurrentScene()->onCloseWindow() && - pEApp->onCloseWindow()) + if (!pEApp->getCurrentScene()) { - DestroyWindow(hWnd); + if (pEApp->onCloseWindow()) + { + DestroyWindow(hWnd); + } + } + else + { + if (pEApp->getCurrentScene()->onCloseWindow() && + pEApp->onCloseWindow()) + { + DestroyWindow(hWnd); + } } } result = 1; diff --git a/Easy2D/Base/EObject.cpp b/Easy2D/Base/EObject.cpp index 98e9e087..bbe42644 100644 --- a/Easy2D/Base/EObject.cpp +++ b/Easy2D/Base/EObject.cpp @@ -23,11 +23,11 @@ void e2d::EObject::retain() void e2d::EObject::release() { m_nRefCount--; + // 通知对象管理池刷新 + EObjectManager::notifyFlush(); } void e2d::EObject::autoRelease() { m_bAutoRelease = true; - // 通知对象管理池刷新 - EObjectManager::notifyFlush(); } diff --git a/Easy2D/Base/EScene.cpp b/Easy2D/Base/EScene.cpp index d7647f67..c4b39a38 100644 --- a/Easy2D/Base/EScene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -11,15 +11,16 @@ e2d::EScene::EScene() { m_pRoot->_onEnter(); m_pRoot->_setParentScene(this); + m_pRoot->_setSize(EApp::getWidth(), EApp::getHeight()); + m_pRoot->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); } e2d::EScene::~EScene() { - ETimerManager::clearAllTimersBindedWith(this); - EMsgManager::clearAllMouseListenersBindedWith(this); - EMsgManager::clearAllKeyboardListenersBindedWith(this); - EActionManager::clearAllActionsBindedWith(this); - SafeRelease(&m_pRoot); + ETimerManager::_clearAllTimersBindedWith(this); + EMsgManager::_clearAllMouseListenersBindedWith(this); + EMsgManager::_clearAllKeyboardListenersBindedWith(this); + SafeReleaseAndClear(&m_pRoot); } void e2d::EScene::onEnter() diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index c40ae968..949eaf95 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -146,7 +146,7 @@ NotUsing Level3 MaxSpeed - true + false true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true @@ -212,7 +212,6 @@ - @@ -225,6 +224,7 @@ + @@ -232,9 +232,13 @@ - + + + + + diff --git a/Easy2D/Easy2D.vcxproj.filters b/Easy2D/Easy2D.vcxproj.filters index 2c30e2ae..7e5d3218 100644 --- a/Easy2D/Easy2D.vcxproj.filters +++ b/Easy2D/Easy2D.vcxproj.filters @@ -45,9 +45,6 @@ Node - - Tool - Node @@ -105,9 +102,6 @@ Action - - Tool - Node @@ -159,6 +153,24 @@ Listener + + Node + + + Transition + + + Transition + + + Transition + + + Transition + + + Tool + diff --git a/Easy2D/Listener/EListener.cpp b/Easy2D/Listener/EListener.cpp index 336056a7..aa6bb54a 100644 --- a/Easy2D/Listener/EListener.cpp +++ b/Easy2D/Listener/EListener.cpp @@ -2,6 +2,7 @@ e2d::EListener::EListener() : m_bRunning(false) + , m_bAlways(false) , m_pParentScene(nullptr) , m_pParentNode(nullptr) { diff --git a/Easy2D/Manager/EActionManager.cpp b/Easy2D/Manager/EActionManager.cpp index cecf5ab5..128452c8 100644 --- a/Easy2D/Manager/EActionManager.cpp +++ b/Easy2D/Manager/EActionManager.cpp @@ -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) { 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) { 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) { @@ -95,7 +80,7 @@ void e2d::EActionManager::clearAllActionsBindedWith(ENode * pTargetNode) auto a = s_vActions[i]; if (a->getTarget() == pTargetNode) { - SafeRelease(&a); + SafeReleaseAndClear(&a); s_vActions.erase(s_vActions.begin() + i); } else @@ -103,26 +88,31 @@ void e2d::EActionManager::clearAllActionsBindedWith(ENode * pTargetNode) i++; } } - for (auto child : pTargetNode->getChildren()) - { - ETimerManager::clearAllTimersBindedWith(child); - } } } 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() { - EActionManager::stopAllActionsBindedWith(EApp::getCurrentScene()); -} - -void e2d::EActionManager::clearAllActions() -{ - EActionManager::clearAllActionsBindedWith(EApp::getCurrentScene()); + for (auto child : EApp::getCurrentScene()->getChildren()) + { + EActionManager::stopAllActionsBindedWith(child); + } } void e2d::EActionManager::_clearManager() @@ -143,11 +133,10 @@ void e2d::EActionManager::ActionProc() if (EApp::isPaused() || s_vActions.empty()) return; - EAction * action; // 循环遍历所有正在运行的动作 for (size_t i = 0; i < s_vActions.size(); i++) { - action = s_vActions[i]; + auto &action = s_vActions[i]; // 获取动作运行状态 if (action->isRunning() || (action->getTarget() && action->getTarget()->getParentScene() == EApp::getCurrentScene())) @@ -155,7 +144,7 @@ void e2d::EActionManager::ActionProc() if (action->_isEnding()) { // 动作已经结束 - SafeRelease(&action); + SafeReleaseAndClear(&action); s_vActions.erase(s_vActions.begin() + i); } else diff --git a/Easy2D/Manager/EMsgManager.cpp b/Easy2D/Manager/EMsgManager.cpp index 612f6d65..b7635e56 100644 --- a/Easy2D/Manager/EMsgManager.cpp +++ b/Easy2D/Manager/EMsgManager.cpp @@ -15,16 +15,18 @@ e2d::EVector s_vKeyboardListeners; void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam) { - if (EApp::isPaused()) - return; - // 保存鼠标消息 s_MouseMsg.m_nMsg = message; s_MouseMsg.m_wParam = wParam; 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->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) { - if (EApp::isPaused()) - return; - // 保存按键消息 s_KeyboardMsg.m_nMsg = message; s_KeyboardMsg.m_wParam = wParam; 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->getParentScene() == EApp::getCurrentScene() || @@ -163,7 +167,7 @@ bool e2d::EKeyboardMsg::isScrollLockOn() return false; } -void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pParentScene) +void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pParentScene, bool always /* = false */) { ASSERT( (!listener->m_pParentNode) && (!listener->m_pParentScene), @@ -177,11 +181,12 @@ void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pPa listener->start(); listener->retain(); listener->m_pParentScene = pParentScene; + listener->m_bAlways = always; 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( (!listener->m_pParentNode) && (!listener->m_pParentScene), @@ -195,11 +200,12 @@ void e2d::EMsgManager::bindListener(EKeyboardListener * listener, EScene * pPare listener->start(); listener->retain(); listener->m_pParentScene = pParentScene; + listener->m_bAlways = always; 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( (!listener->m_pParentNode) && (!listener->m_pParentScene), @@ -212,12 +218,13 @@ void e2d::EMsgManager::bindListener(EMouseListener * listener, ENode * pParentNo { listener->start(); listener->retain(); + listener->m_bAlways = always; listener->m_pParentNode = pParentNode; 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( (!listener->m_pParentNode) && (!listener->m_pParentScene), @@ -231,6 +238,7 @@ void e2d::EMsgManager::bindListener(EKeyboardListener * listener, ENode * pParen listener->start(); listener->retain(); listener->m_pParentNode = pParentNode; + listener->m_bAlways = always; s_vKeyboardListeners.push_back(listener); } } @@ -265,7 +273,7 @@ void e2d::EMsgManager::delMouseListeners(const EString & name) { if ((*mIter)->getName() == name) { - SafeRelease(&(*mIter)); + SafeReleaseAndClear(&(*mIter)); mIter = s_vMouseListeners.erase(mIter); } else @@ -307,7 +315,7 @@ void e2d::EMsgManager::delKeyboardListeners(const EString & name) { if ((*kIter)->getName() == name) { - SafeRelease(&(*kIter)); + SafeReleaseAndClear(&(*kIter)); kIter = s_vKeyboardListeners.erase(kIter); } 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();) { auto t = s_vMouseListeners[i]; if (t->getParentScene() == pParentScene) { - SafeRelease(&t); + SafeReleaseAndClear(&t); s_vMouseListeners.erase(s_vMouseListeners.begin() + i); } else @@ -452,20 +460,16 @@ void e2d::EMsgManager::clearAllMouseListenersBindedWith(EScene * pParentScene) 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();) { auto t = s_vKeyboardListeners[i]; if (t->getParentScene() == pParentScene) { - SafeRelease(&t); + SafeReleaseAndClear(&t); s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); } else @@ -473,20 +477,16 @@ void e2d::EMsgManager::clearAllKeyboardListenersBindedWith(EScene * pParentScene 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();) { auto t = s_vMouseListeners[i]; if (t->getParentNode() == pParentNode) { - SafeRelease(&t); + SafeReleaseAndClear(&t); s_vMouseListeners.erase(s_vMouseListeners.begin() + i); } else @@ -494,20 +494,16 @@ void e2d::EMsgManager::clearAllMouseListenersBindedWith(ENode * pParentNode) 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();) { auto t = s_vKeyboardListeners[i]; if (t->getParentNode() == pParentNode) { - SafeRelease(&t); + SafeReleaseAndClear(&t); s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); } else @@ -515,10 +511,6 @@ void e2d::EMsgManager::clearAllKeyboardListenersBindedWith(ENode * pParentNode) i++; } } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::clearAllKeyboardListenersBindedWith(child); - } } void e2d::EMsgManager::_clearManager() @@ -537,11 +529,6 @@ void e2d::EMsgManager::stopAllMouseListeners() EMsgManager::stopAllMouseListenersBindedWith(EApp::getCurrentScene()); } -void e2d::EMsgManager::clearAllMouseListeners() -{ - EMsgManager::clearAllMouseListenersBindedWith(EApp::getCurrentScene()); -} - void e2d::EMsgManager::startAllKeyboardListeners() { EMsgManager::startAllKeyboardListenersBindedWith(EApp::getCurrentScene()); @@ -550,9 +537,4 @@ void e2d::EMsgManager::startAllKeyboardListeners() void e2d::EMsgManager::stopAllKeyboardListeners() { EMsgManager::stopAllKeyboardListenersBindedWith(EApp::getCurrentScene()); -} - -void e2d::EMsgManager::clearAllKeyboardListeners() -{ - EMsgManager::clearAllKeyboardListenersBindedWith(EApp::getCurrentScene()); } \ No newline at end of file diff --git a/Easy2D/Manager/ETimerManager.cpp b/Easy2D/Manager/ETimerManager.cpp index 109e8086..3a9e6c44 100644 --- a/Easy2D/Manager/ETimerManager.cpp +++ b/Easy2D/Manager/ETimerManager.cpp @@ -4,6 +4,29 @@ static e2d::EVector 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) { ASSERT( @@ -69,7 +92,7 @@ void e2d::ETimerManager::delTimers(const EString & name) { if ((*mIter)->getName() == name) { - SafeRelease(&(*mIter)); + SafeReleaseAndClear(&(*mIter)); mIter = s_vTimers.erase(mIter); } 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();) { auto t = s_vTimers[i]; if (t->getParentScene() == pParentScene) { - SafeRelease(&t); + SafeReleaseAndClear(&t); s_vTimers.erase(s_vTimers.begin() + i); } else @@ -124,10 +147,6 @@ void e2d::ETimerManager::clearAllTimersBindedWith(EScene * pParentScene) i++; } } - for (auto child : pParentScene->getChildren()) - { - ETimerManager::clearAllTimersBindedWith(child); - } } 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();) { auto t = s_vTimers[i]; if (t->getParentNode() == pParentNode) { - SafeRelease(&t); + SafeReleaseAndClear(&t); s_vTimers.erase(s_vTimers.begin() + i); } else @@ -175,10 +194,6 @@ void e2d::ETimerManager::clearAllTimersBindedWith(ENode * pParentNode) i++; } } - for (auto child : pParentNode->getChildren()) - { - ETimerManager::clearAllTimersBindedWith(child); - } } void e2d::ETimerManager::_clearManager() @@ -202,31 +217,4 @@ void e2d::ETimerManager::startAllTimers() void e2d::ETimerManager::stopAllTimers() { 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(); - } - } - } - } } \ No newline at end of file diff --git a/Easy2D/Node/EButton.cpp b/Easy2D/Node/EButton.cpp new file mode 100644 index 00000000..8392ed37 --- /dev/null +++ b/Easy2D/Node/EButton.cpp @@ -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; + } + } +} diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp index 50513be3..aad847b7 100644 --- a/Easy2D/Node/ENode.cpp +++ b/Easy2D/Node/ENode.cpp @@ -14,8 +14,8 @@ e2d::ENode::ENode() , m_fSkewAngleY(0) , m_fDisplayOpacity(1.0f) , m_fRealOpacity(1.0f) - , m_fAnchorX(0) - , m_fAnchorY(0) + , m_fAnchorX(0.5f) + , m_fAnchorY(0.5f) , m_Matri(D2D1::Matrix3x2F::Identity()) , m_bVisiable(true) , m_bDisplayedInScene(false) @@ -35,10 +35,10 @@ e2d::ENode::ENode(const EString & name) e2d::ENode::~ENode() { - ETimerManager::clearAllTimersBindedWith(this); - EMsgManager::clearAllMouseListenersBindedWith(this); - EMsgManager::clearAllKeyboardListenersBindedWith(this); - EActionManager::clearAllActionsBindedWith(this); + ETimerManager::_clearAllTimersBindedWith(this); + EMsgManager::_clearAllMouseListenersBindedWith(this); + EMsgManager::_clearAllKeyboardListenersBindedWith(this); + EActionManager::_clearAllActionsBindedWith(this); } void e2d::ENode::onEnter() @@ -428,8 +428,8 @@ void e2d::ENode::setOpacity(float opacity) return; m_fDisplayOpacity = m_fRealOpacity = min(max(opacity, 0), 1); - // 更新子节点透明度 - _updateChildrenOpacity(); + // 更新节点透明度 + _updateOpacity(this); } void e2d::ENode::setAnchorX(float anchorX) @@ -557,7 +557,9 @@ bool e2d::ENode::removeChild(ENode * child, bool release /* = true */) child->_onExit(); child->release(); if (release) + { child->autoRelease(); + } return true; } } @@ -593,7 +595,9 @@ void e2d::ENode::removeChild(const EString & childName, bool release /* = true * child->_onExit(); child->release(); if (release) + { child->autoRelease(); + } return; } } @@ -604,12 +608,12 @@ void e2d::ENode::clearAllChildren(bool release /* = true */) // 所有节点的引用计数减一 for (auto child : m_vChildren) { + child->_onExit(); + child->release(); if (release) { child->autoRelease(); } - child->_onExit(); - child->release(); } // 清空储存节点的容器 m_vChildren.clear(); @@ -619,7 +623,7 @@ void e2d::ENode::runAction(EAction * action) { ASSERT( (!action->getTarget()), - "The action is already running, it cannot running again!" + "The action is already running, it cannot run again!" ); action->setTarget(this); 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) { 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) { m_bVisiable = value; diff --git a/Easy2D/Node/ESprite.cpp b/Easy2D/Node/ESprite.cpp index aa877370..66cffd9a 100644 --- a/Easy2D/Node/ESprite.cpp +++ b/Easy2D/Node/ESprite.cpp @@ -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) : ESprite() { - setTexture(new ETexture(imageFileName)); + loadFrom(new ETexture(imageFileName)); } e2d::ESprite::ESprite(const EString & imageFileName, float x, float y, float width, float height) { - setTexture(new ETexture(imageFileName)); - clipTexture(x, y, width, height); + loadFrom(new ETexture(imageFileName)); + clip(x, y, width, height); } e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType) : 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) { - setTexture(new ETexture(resourceName, resourceType)); - clipTexture(x, y, width, height); + loadFrom(new ETexture(resourceName, resourceType)); + clip(x, y, width, height); } e2d::ESprite::~ESprite() { - SafeRelease(&m_pTexture); + SafeReleaseAndClear(&m_pTexture); } -void e2d::ESprite::setTexture(ETexture * texture) +void e2d::ESprite::loadFrom(ETexture * texture) { - SafeRelease(&m_pTexture); - m_pTexture = texture; - m_pTexture->retain(); + if (texture) + { + SafeReleaseAndClear(&m_pTexture); + m_pTexture = texture; + m_pTexture->retain(); - m_fSourceClipX = m_fSourceClipY = 0; - ENode::_setWidth(m_pTexture->getSourceWidth()); - ENode::_setHeight(m_pTexture->getSourceHeight()); + m_fSourceClipX = m_fSourceClipY = 0; + ENode::_setWidth(m_pTexture->getSourceWidth()); + 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); - clipTexture(x, y, width, height); + loadFrom(texture); + clip(x, y, width, height); } -void e2d::ESprite::loadFromSpriteFrame(ESpriteFrame * frame) +void e2d::ESprite::loadFrom(ESpriteFrame * frame) { - setTexture(frame->m_pTexture); - clipTexture(frame->m_fSourceClipX, frame->m_fSourceClipY, frame->m_fSourceClipWidth, frame->m_fSourceClipHeight); + if (frame) + { + 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_fSourceClipY = min(max(y, 0), m_pTexture->getSourceHeight()); 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() diff --git a/Easy2D/Node/ESpriteFrame.cpp b/Easy2D/Node/ESpriteFrame.cpp index 77bb45ee..522f7882 100644 --- a/Easy2D/Node/ESpriteFrame.cpp +++ b/Easy2D/Node/ESpriteFrame.cpp @@ -50,20 +50,29 @@ e2d::ESpriteFrame::ESpriteFrame(const EString & resourceName, const EString & re e2d::ESpriteFrame::~ESpriteFrame() { - if (m_pTexture) - { - m_pTexture->release(); - } + SafeRelease(&m_pTexture); +} + +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) { if (texture) { - if (m_pTexture) - { - m_pTexture->release(); - } + SafeRelease(&m_pTexture); m_pTexture = texture; m_pTexture->retain(); m_fSourceClipX = 0; diff --git a/Easy2D/Node/EText.cpp b/Easy2D/Node/EText.cpp index e2a522a1..77707766 100644 --- a/Easy2D/Node/EText.cpp +++ b/Easy2D/Node/EText.cpp @@ -40,7 +40,7 @@ e2d::EText::EText(const EString & text, EColor color, EString fontFamily, float e2d::EText::~EText() { - SafeRelease(&m_pFont); + SafeReleaseAndClear(&m_pFont); } e2d::EString e2d::EText::getText() const @@ -83,7 +83,7 @@ void e2d::EText::setFont(EFont * font) { if (font) { - SafeRelease(&m_pFont); + SafeReleaseAndClear(&m_pFont); m_pFont = font; font->retain(); @@ -108,7 +108,7 @@ void e2d::EText::_onRender() GetSolidColorBrush()->SetColor(D2D1::ColorF(m_Color.value, m_fDisplayOpacity)); GetRenderTarget()->DrawTextW( m_sText.c_str(), - m_sText.length(), + UINT32(m_sText.length()), m_pFont->_getTextFormat(), D2D1::RectF( 0, @@ -145,7 +145,7 @@ void e2d::EText::_initTextLayout() HRESULT hr = GetDirectWriteFactory()->CreateTextLayout( m_sText.c_str(), - m_sText.size(), + UINT32(m_sText.size()), m_pFont->_getTextFormat(), m_bWordWrapping ? m_fWordWrappingWidth : 0, 0, diff --git a/Easy2D/Tool/EMusicUtils.cpp b/Easy2D/Tool/EMusicUtils.cpp index 11746935..86aab8f7 100644 --- a/Easy2D/Tool/EMusicUtils.cpp +++ b/Easy2D/Tool/EMusicUtils.cpp @@ -1,6 +1 @@ #include "..\etools.h" - - -void e2d::EMusicUtils::play(LPCTSTR musicFileName, bool loop) -{ -} \ No newline at end of file diff --git a/Easy2D/ETimer.cpp b/Easy2D/Tool/ETimer.cpp similarity index 51% rename from Easy2D/ETimer.cpp rename to Easy2D/Tool/ETimer.cpp index 3272236a..2aa2f5b5 100644 --- a/Easy2D/ETimer.cpp +++ b/Easy2D/Tool/ETimer.cpp @@ -1,5 +1,5 @@ -#include "etools.h" -#include "Win\winbase.h" +#include "..\etools.h" +#include "..\Win\winbase.h" e2d::ETimer::ETimer() : m_bRunning(false) @@ -7,27 +7,29 @@ e2d::ETimer::ETimer() , m_pParentScene(nullptr) , m_pParentNode(nullptr) , 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() { - 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() { - m_Callback = callback; -} - -e2d::ETimer::ETimer(const EString & name, const TIMER_CALLBACK & callback, LONGLONG delay /* = 20LL */) - : ETimer() -{ - m_sName = name; - m_Callback = callback; + this->setName(name); + this->setCallback(callback); + this->setRepeatTimes(repeatTimes); + this->setInterval(interval); + m_bAtOnce = atOnce; } bool e2d::ETimer::isRunning() const @@ -71,6 +73,16 @@ void e2d::ETimer::setInterval(LONGLONG interval) 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) { ETimerManager::bindTimer(this, pParentScene); @@ -83,6 +95,28 @@ void e2d::ETimer::bindWith(ENode * pParentNode) void e2d::ETimer::_callOn() { + if (m_nRunTimes == m_nRepeatTimes) + { + this->stop(); + return; + } + m_Callback(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; +} diff --git a/Easy2D/Transition/ETransitionEmerge.cpp b/Easy2D/Transition/ETransitionEmerge.cpp new file mode 100644 index 00000000..5d27eb84 --- /dev/null +++ b/Easy2D/Transition/ETransitionEmerge.cpp @@ -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)); +} diff --git a/Easy2D/Transition/ETransitionFade.cpp b/Easy2D/Transition/ETransitionFade.cpp index ef210534..05ac9070 100644 --- a/Easy2D/Transition/ETransitionFade.cpp +++ b/Easy2D/Transition/ETransitionFade.cpp @@ -1,5 +1,6 @@ #include "..\etransitions.h" #include "..\eactions.h" +#include "..\etools.h" e2d::ETransitionFade::ETransitionFade(float fadeOutDuration, float fadeInDuration) : 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); if (prev) { action1->setTarget(prev->getRoot()); } - - // 切换至第二场景,并将第二场景透明度设为 0 - auto action2 = new EActionCallback([&, next] { - enterNextScene = true; - next->getRoot()->setOpacity(0); - }); // 第二个场景淡入 - auto action3 = new EActionFadeIn(m_fFadeInDuration); - action3->setTarget(next->getRoot()); + auto action2 = new EActionFadeIn(m_fFadeInDuration); + action2->setTarget(next->getRoot()); // 标志动画结束 - auto action4 = new EActionCallback([&] { + auto action3 = new EActionCallback([&, prev, next] { 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)); } \ No newline at end of file diff --git a/Easy2D/Transition/ETransitionMove.cpp b/Easy2D/Transition/ETransitionMove.cpp new file mode 100644 index 00000000..77bcbd4f --- /dev/null +++ b/Easy2D/Transition/ETransitionMove.cpp @@ -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)); +} diff --git a/Easy2D/Transition/ETransitionScale.cpp b/Easy2D/Transition/ETransitionScale.cpp new file mode 100644 index 00000000..ec547fc2 --- /dev/null +++ b/Easy2D/Transition/ETransitionScale.cpp @@ -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)); +} diff --git a/Easy2D/Transition/ETransitionScaleEmerge.cpp b/Easy2D/Transition/ETransitionScaleEmerge.cpp new file mode 100644 index 00000000..3d0b0b7e --- /dev/null +++ b/Easy2D/Transition/ETransitionScaleEmerge.cpp @@ -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)); +} diff --git a/Easy2D/eactions.h b/Easy2D/eactions.h index a8d96ff2..ed888cf7 100644 --- a/Easy2D/eactions.h +++ b/Easy2D/eactions.h @@ -1,10 +1,11 @@ #pragma once #include "enodes.h" -#include "etools.h" +#include namespace e2d { +class EActionManager; class EActionTwo; class EActionLoop; class EActionSequence; @@ -106,8 +107,9 @@ protected: virtual void _reset() override; protected: - LONGLONG m_nDuration; - LONGLONG m_nTotalDuration; + float m_fDuration; + float m_fTotalDuration; + float m_fRateOfProgress; }; @@ -172,6 +174,12 @@ class EActionScaleBy : public EActionGradual { public: + // 创建相对缩放动画 + EActionScaleBy( + float duration, /* 动画持续时长 */ + float scale /* 缩放比例变化 */ + ); + // 创建相对缩放动画 EActionScaleBy( float duration, /* 动画持续时长 */ @@ -207,6 +215,12 @@ class EActionScaleTo : public EActionScaleBy { public: + // 创建缩放动画 + EActionScaleTo( + float duration, /* 动画持续时长 */ + float scale /* 缩放至目标比例 */ + ); + // 创建缩放动画 EActionScaleTo( float duration, /* 动画持续时长 */ diff --git a/Easy2D/ebase.h b/Easy2D/ebase.h index 95e544dd..5f460356 100644 --- a/Easy2D/ebase.h +++ b/Easy2D/ebase.h @@ -22,13 +22,6 @@ public: virtual ~EApp(); - enum WINDOW_STYLE - { - NO_CLOSE = 1, /* 禁用关闭按钮 */ - NO_MINI_SIZE = 2, /* 禁用最小化按钮 */ - TOP_MOST = 4 /* 窗口置顶 */ - }; - // 初始化游戏界面 bool init( const EString &title, /* 窗口标题 */ @@ -42,7 +35,7 @@ public: const EString &title, /* 窗口标题 */ UINT32 width, /* 窗口宽度 */ UINT32 height, /* 窗口高度 */ - int windowStyle, /* 窗口样式 */ + EWindowStyle wStyle, /* 窗口样式 */ bool showConsole = false/* 是否显示控制台 */ ); @@ -115,10 +108,10 @@ public: static EString getTitle(); // 获取窗口宽度 - static UINT32 getWidth(); + static float getWidth(); // 获取窗口高度 - static UINT32 getHeight(); + static float getHeight(); // 获取当前场景 static EScene * getCurrentScene(); @@ -207,7 +200,6 @@ protected: bool m_bPaused; bool m_bManualPaused; bool m_bTransitional; - bool m_bEnterNextScene; bool m_bTopMost; EString m_sTitle; EString m_sAppName; diff --git a/Easy2D/ecommon.h b/Easy2D/ecommon.h index 6b8ba5ab..723b8968 100644 --- a/Easy2D/ecommon.h +++ b/Easy2D/ecommon.h @@ -12,6 +12,45 @@ typedef std::wstring EString; template using EVector = std::vector; +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 { EPoint() @@ -71,14 +110,22 @@ struct ESize }; -typedef std::function KEY_LISTENER_CALLBACK; -typedef std::function MOUSE_LISTENER_CALLBACK; -typedef std::function 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 MOUSE_DRAG_LISTENER_CALLBACK; - +// 定时器回调函数(参数为该定时器被调用的次数,从 0 开始) typedef std::function TIMER_CALLBACK; +// 按钮点击回调函数 +typedef std::function BUTTON_CLICK_CALLBACK; +// 按键消息监听回调函数 +typedef std::function KEY_LISTENER_CALLBACK; +// 鼠标消息监听回调函数 +typedef std::function MOUSE_LISTENER_CALLBACK; +// 鼠标点击消息监听回调函数(参数为点击位置) +typedef std::function 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 MOUSE_DRAG_LISTENER_CALLBACK; diff --git a/Easy2D/emacros.h b/Easy2D/emacros.h index 66a53f3d..0c6a54ef 100644 --- a/Easy2D/emacros.h +++ b/Easy2D/emacros.h @@ -65,4 +65,7 @@ template inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } } template -inline void SafeRelease(T** p) { if (*p) { (*p)->autoRelease(); (*p)->release(); *p = nullptr; } } \ No newline at end of file +inline void SafeReleaseAndClear(T** p) { if (*p) { (*p)->autoRelease(); (*p)->release(); *p = nullptr; } } + +template +inline void SafeRelease(T** p) { if (*p) { (*p)->release(); *p = nullptr; } } \ No newline at end of file diff --git a/Easy2D/emsg.h b/Easy2D/emsg.h index edd47dff..96d7a6f3 100644 --- a/Easy2D/emsg.h +++ b/Easy2D/emsg.h @@ -190,6 +190,7 @@ protected: protected: EString m_sName; bool m_bRunning; + bool m_bAlways; EScene * m_pParentScene; ENode * m_pParentNode; }; @@ -465,13 +466,15 @@ public: // 绑定鼠标消息监听器到场景 static void bindListener( EMouseListener * listener, - EScene * pParentScene + EScene * pParentScene, + bool always = false /* 是否在游戏暂停时仍然监听 */ ); // 绑定鼠标消息监听器到节点 static void bindListener( EMouseListener * listener, - ENode * pParentNode + ENode * pParentNode, + bool always = false /* 是否在游戏暂停时仍然监听 */ ); // 启动具有相同名称的鼠标消息监听器 @@ -499,11 +502,6 @@ public: EScene * pParentScene ); - // 清除绑定在场景及其子节点上的所有鼠标消息监听器 - static void clearAllMouseListenersBindedWith( - EScene * pParentScene - ); - // 启动绑定在节点上的所有鼠标消息监听器 static void startAllMouseListenersBindedWith( ENode * pParentNode @@ -514,30 +512,24 @@ public: ENode * pParentNode ); - // 清除绑定在节点上的所有鼠标消息监听器 - static void clearAllMouseListenersBindedWith( - ENode * pParentNode - ); - // 启动所有鼠标消息监听器 static void startAllMouseListeners(); // 停止所有鼠标消息监听器 static void stopAllMouseListeners(); - // 清除所有鼠标消息监听器 - static void clearAllMouseListeners(); - // 绑定按键消息监听器到场景 static void bindListener( EKeyboardListener * listener, - EScene * pParentScene + EScene * pParentScene, + bool always = false /* 是否在游戏暂停时仍然监听 */ ); // 绑定按键消息监听器到节点 static void bindListener( EKeyboardListener * listener, - ENode * pParentNode + ENode * pParentNode, + bool always = false /* 是否在游戏暂停时仍然监听 */ ); // 启动名称相同的按键消息监听器 @@ -565,11 +557,6 @@ public: EScene * pParentScene ); - // 清除绑定在场景及其子节点上的所有按键消息监听器 - static void clearAllKeyboardListenersBindedWith( - EScene * pParentScene - ); - // 启动绑定在节点上的所有按键消息监听器 static void startAllKeyboardListenersBindedWith( ENode * pParentNode @@ -580,24 +567,36 @@ public: ENode * pParentNode ); - // 清除绑定在节点上的所有按键消息监听器 - static void clearAllKeyboardListenersBindedWith( - ENode * pParentNode - ); - // 启动所有按键消息监听器 static void startAllKeyboardListeners(); // 停止所有按键消息监听器 static void stopAllKeyboardListeners(); - // 清除所有按键消息监听器 - static void clearAllKeyboardListeners(); - private: // 清除所有监听器 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( UINT message, diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h index 2b82173d..4026997e 100644 --- a/Easy2D/enodes.h +++ b/Easy2D/enodes.h @@ -7,11 +7,13 @@ namespace e2d class EText; class ESprite; class EAction; +class EButton; class ENode : public EObject { friend EScene; + friend EButton; public: ENode(); @@ -204,19 +206,19 @@ public: ); // 设置纵向锚点 - // 默认为 0, 范围 [0, 1] + // 默认为 0.5f, 范围 [0, 1] virtual void setAnchorX( float anchorX ); // 设置横向锚点 - // 默认为 0, 范围 [0, 1] + // 默认为 0.5f, 范围 [0, 1] virtual void setAnchorY( float anchorY ); // 设置锚点 - // 默认为 (0, 0), 范围 [0, 1] + // 默认为 (0.5f, 0.5f), 范围 [0, 1] virtual void setAnchor( float anchorX, float anchorY @@ -270,6 +272,20 @@ public: EAction * action ); + // 继续所有暂停动画 + virtual void startAllActions(); + + // 暂停所有动画 + virtual void pauseAllActions(); + + // 停止所有动画 + virtual void stopAllActions(); + + // 判断点是否在节点内 + virtual bool isPointIn( + EPoint point + ); + protected: // 访问节点 virtual void _callOn(); @@ -472,6 +488,15 @@ public: virtual ~ESpriteFrame(); + // 获取宽度 + float getWidth() const; + + // 获取高度 + float getHeight() const; + + // 获取纹理 + ETexture * getTexture() const; + protected: // 获取纹理 void _setTexture( @@ -502,6 +527,16 @@ public: // 创建一个空精灵 ESprite(); + // 从文理资源创建精灵 + ESprite( + ETexture * texture + ); + + // 从精灵帧创建精灵 + ESprite( + ESpriteFrame * spriteFrame + ); + // 从文件图片创建精灵 ESprite( const EString & imageFileName @@ -535,12 +570,12 @@ public: virtual ~ESprite(); // 设置精灵纹理 - void setTexture( + void loadFrom( ETexture * texture ); // 设置精灵纹理并裁剪 - void setTexture( + void loadFrom( ETexture * texture, float x, float y, @@ -548,13 +583,13 @@ public: float height ); - // 从 ESpriteFrame 加载资源 - void loadFromSpriteFrame( + // 从精灵帧加载资源 + void loadFrom( ESpriteFrame * frame ); // 裁剪纹理 - void clipTexture( + void clip( float x, float y, float width, @@ -721,4 +756,92 @@ protected: 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; +}; + } \ No newline at end of file diff --git a/Easy2D/etools.h b/Easy2D/etools.h index 51eea928..5b6cc869 100644 --- a/Easy2D/etools.h +++ b/Easy2D/etools.h @@ -41,28 +41,28 @@ class ETimer : public: ETimer(); - ETimer( - const EString &name /* 定时器名称 */ - ); - ETimer( const TIMER_CALLBACK &callback, /* 定时器回调函数 */ - LONGLONG delay = 20LL /* 时间间隔 */ + int repeatTimes = -1, /* 定时器执行次数 */ + LONGLONG interval = 0LL, /* 时间间隔(毫秒) */ + bool atOnce = false /* 是否立即执行 */ ); ETimer( const EString &name, /* 定时器名称 */ const TIMER_CALLBACK &callback, /* 定时器回调函数 */ - LONGLONG delay = 20LL /* 时间间隔 */ + int repeatTimes = -1, /* 定时器执行次数 */ + LONGLONG interval = 0LL, /* 时间间隔(毫秒) */ + bool atOnce = false /* 是否立即执行 */ ); // 获取定时器状态 bool isRunning() const; - // 启动监听 + // 启动定时器 void start(); - // 停止监听 + // 停止定时器 void stop(); // 获取定时器名称 @@ -84,6 +84,16 @@ public: LONGLONG interval ); + // 设置定时器回调函数 + void setCallback( + const TIMER_CALLBACK & callback + ); + + // 设置定时器重复执行次数 + void setRepeatTimes( + int repeatTimes + ); + // 绑定定时器到场景 virtual void bindWith( EScene * pParentScene @@ -98,10 +108,15 @@ protected: // 执行回调函数 virtual void _callOn(); + // 判断是否达到执行状态 + bool _isReady(); + protected: EString m_sName; bool m_bRunning; + bool m_bAtOnce; int m_nRunTimes; + int m_nRepeatTimes; EScene * m_pParentScene; ENode * m_pParentNode; TIMER_CALLBACK m_Callback; @@ -155,11 +170,6 @@ public: EScene * pParentScene ); - // 清空绑定在场景及其子节点上的所有定时器 - static void clearAllTimersBindedWith( - EScene * pParentScene - ); - // 启动绑定在节点上的所有定时器 static void startAllTimersBindedWith( ENode * pParentNode @@ -170,24 +180,26 @@ public: ENode * pParentNode ); - // 清空绑定在节点上的所有定时器 - static void clearAllTimersBindedWith( - ENode * pParentNode - ); - // 启动所有定时器 static void startAllTimers(); // 停止所有定时器 static void stopAllTimers(); - // 清除所有定时器 - static void clearAllTimers(); - private: // 清空定时器管理器 static void _clearManager(); + // 清空绑定在场景及其子节点上的所有定时器 + static void _clearAllTimersBindedWith( + EScene * pParentScene + ); + + // 清空绑定在节点上的所有定时器 + static void _clearAllTimersBindedWith( + ENode * pParentNode + ); + // 重置定时器状态 static void _resetAllTimers(); @@ -209,23 +221,13 @@ public: EAction * action ); - // 启动绑定在场景子节点上的所有动作 + // 继续绑定在节点上的所有动作 static void startAllActionsBindedWith( - EScene * pParentScene + ENode * pTargetNode ); - // 停止绑定在场景子节点上的所有动作 - static void stopAllActionsBindedWith( - EScene * pParentScene - ); - - // 清空绑定在场景子节点上的所有动作 - static void clearAllActionsBindedWith( - EScene * pParentScene - ); - - // 启动绑定在节点上的所有动作 - static void startAllActionsBindedWith( + // 暂停绑定在节点上的所有动作 + static void pauseAllActionsBindedWith( ENode * pTargetNode ); @@ -234,24 +236,24 @@ public: ENode * pTargetNode ); - // 清空绑定在节点上的所有动作 - static void clearAllActionsBindedWith( - ENode * pTargetNode - ); - - // 启动所有动作 + // 继续所有动作 static void startAllActions(); + // 暂停所有动作 + static void pauseAllActions(); + // 停止所有动作 static void stopAllActions(); - // 清除所有动作 - static void clearAllActions(); - private: // 清空动画管理器 static void _clearManager(); + // 清空绑定在节点上的所有动作 + static void _clearAllActionsBindedWith( + ENode * pTargetNode + ); + // 重置所有动作状态 static void _resetAllActions(); @@ -260,14 +262,6 @@ private: }; -class EMusicUtils -{ -public: - // 播放音效 - static void play(LPCTSTR musicFileName, bool loop = false); -}; - - class EFileUtils { public: @@ -311,7 +305,22 @@ class ERandom public: // 取得整型范围内的一个随机数 template - 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 + static T randomInt( + T min, + T max) { std::uniform_int_distribution dist(min, max); return dist(getEngine()); @@ -319,7 +328,9 @@ public: // 取得浮点数类型范围内的一个随机数 template - static T randomReal(T min, T max) + static T randomReal( + T min, + T max) { std::uniform_real_distribution dist(min, max); return dist(getEngine()); @@ -329,10 +340,4 @@ public: static std::default_random_engine &getEngine(); }; -template -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); } - } \ No newline at end of file diff --git a/Easy2D/etransitions.h b/Easy2D/etransitions.h index 5f6066cd..97c3e1bb 100644 --- a/Easy2D/etransitions.h +++ b/Easy2D/etransitions.h @@ -9,14 +9,13 @@ class ETransition : { friend EApp; public: - ETransition() {} + ETransition() { this->autoRelease(); } protected: // 保存当前场景和下一场景的指针,和控制场景切换的变量 virtual void _setTarget( EScene * prev, EScene * next, - bool &enterNextScene, bool &transitional ) = 0; }; @@ -37,7 +36,6 @@ protected: virtual void _setTarget( EScene * prev, EScene * next, - bool &enterNextScene, bool &transitional ) override; @@ -46,4 +44,112 @@ protected: 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; +}; + } \ No newline at end of file