diff --git a/Demo/atlas.png b/Demo/atlas.png new file mode 100644 index 00000000..05e5ce16 Binary files /dev/null and b/Demo/atlas.png differ diff --git a/Demo/main.cpp b/Demo/main.cpp index ba277fda..1e72f796 100644 --- a/Demo/main.cpp +++ b/Demo/main.cpp @@ -10,9 +10,18 @@ int WINAPI WinMain( { EApp app; - if (app.init(L"Easy2D Demo", 640, 480)) + if (app.init(L"Easy2D Demo", 640, 480, app.NO_CLOSE | app.NO_MINI_SIZE | app.TOP_MOST)) { 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"); text->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); @@ -26,7 +35,25 @@ int WINAPI WinMain( text->runAction(new EActionLoop(new EActionTwo(new EActionFadeOut(1), new EActionFadeIn(1)))); - app.enterScene(scene); + auto bird = new ESprite(); + auto animation = new EAnimation(); + animation->addFrame(new ESpriteFrame(L"atlas.png", 5, 982, 34, 24)); + animation->addFrame(new ESpriteFrame(L"atlas.png", 61, 982, 34, 24)); + animation->addFrame(new ESpriteFrame(L"atlas.png", 117, 982, 34, 24)); + bird->runAction(new EActionLoop(animation)); + bird->setAnchor(0.5f, 0.5f); + bird->setPos(EApp::getWidth() / 2, EApp::getHeight() / 2); + scene2->add(bird); + + auto listener2 = new EKeyboardPressListener([=]() { + if (EKeyboardMsg::getVal() == EKeyboardMsg::KEY::SPACE) + { + EApp::backScene(new ETransitionFade(0.5f, 0.5f)); + } + }); + listener2->bindWith(scene); + + app.enterScene(scene2, new ETransitionFade(2, 4)); app.run(); } diff --git a/Easy2D/Action/EAction.cpp b/Easy2D/Action/EAction.cpp index 659ba67d..9eee2cb8 100644 --- a/Easy2D/Action/EAction.cpp +++ b/Easy2D/Action/EAction.cpp @@ -1,8 +1,8 @@ #include "..\eactions.h" +#include "..\Win\winbase.h" e2d::EAction::EAction() : m_bRunning(false), - m_bWaiting(false), m_bEnding(false), m_bInit(false), m_pTarget(nullptr), @@ -18,7 +18,7 @@ e2d::EAction::~EAction() bool e2d::EAction::isRunning() { - return m_bRunning && !m_bWaiting; + return m_bRunning; } bool e2d::EAction::_isEnding() @@ -28,12 +28,13 @@ bool e2d::EAction::_isEnding() void e2d::EAction::start() { - m_bRunning = true; + this->resume(); } void e2d::EAction::resume() { m_bRunning = true; + m_tLast = GetNow(); } void e2d::EAction::pause() @@ -45,15 +46,6 @@ void e2d::EAction::stop() { m_bEnding = true; } -void e2d::EAction::_wait() -{ - m_bWaiting = true; -} - -void e2d::EAction::_notify() -{ - m_bWaiting = false; -} void e2d::EAction::setInterval(LONGLONG milliSeconds) { @@ -61,6 +53,14 @@ void e2d::EAction::setInterval(LONGLONG milliSeconds) m_nAnimationInterval = milliSeconds; } +void e2d::EAction::setTarget(ENode * node) +{ + if (node) + { + m_pTarget = node; + } +} + e2d::EAction * e2d::EAction::reverse() const { assert(0); diff --git a/Easy2D/Action/EActionDelay.cpp b/Easy2D/Action/EActionDelay.cpp index 409ba3ba..d51ef460 100644 --- a/Easy2D/Action/EActionDelay.cpp +++ b/Easy2D/Action/EActionDelay.cpp @@ -15,13 +15,13 @@ void e2d::EActionDelay::_init() { EAction::_init(); // 记录当前时间 - m_nLast = GetNow(); + m_tLast = GetNow(); } void e2d::EActionDelay::_callOn() { // 判断时间间隔是否足够 - if (GetInterval(m_nLast) > m_nAnimationInterval) + if (GetInterval(m_tLast) > m_nAnimationInterval) { this->stop(); } @@ -31,5 +31,5 @@ void e2d::EActionDelay::_reset() { EAction::_reset(); // 记录当前时间 - m_nLast = GetNow(); + m_tLast = GetNow(); } diff --git a/Easy2D/Action/EActionFrames.cpp b/Easy2D/Action/EActionFrames.cpp deleted file mode 100644 index 751ffab2..00000000 --- a/Easy2D/Action/EActionFrames.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "..\eactions.h" -#include "..\Win\winbase.h" - -e2d::EActionFrames::EActionFrames() : - m_nFrameIndex(0) -{ - // 帧动画默认 .5s 刷新一次 - setInterval(500); -} - -e2d::EActionFrames::EActionFrames(LONGLONG frameDelay) : - m_nFrameIndex(0) -{ - setInterval(frameDelay); -} - -e2d::EActionFrames::~EActionFrames() -{ - for (auto frame : m_vFrames) - { - SafeRelease(&frame); - } -} - -void e2d::EActionFrames::_init() -{ - EAction::_init(); - // 记录当前时间 - m_nLast = GetNow(); -} - -void e2d::EActionFrames::_callOn() -{ - // 判断时间间隔是否足够 - while (GetInterval(m_nLast) > m_nAnimationInterval) - { - // 重新记录时间 - m_nLast += milliseconds(m_nAnimationInterval); - //m_pTarget->setImage(m_vFrames[m_nFrameIndex]); - m_nFrameIndex++; - // 判断动作是否结束 - if (m_nFrameIndex == m_vFrames.size()) - { - this->stop(); - break; - } - } -} - -void e2d::EActionFrames::_reset() -{ - EAction::_reset(); - m_nFrameIndex = 0; - // 记录当前时间 - m_nLast = steady_clock::now(); -} - -void e2d::EActionFrames::addFrame(ESpriteFrame * frame) -{ - if (frame) - { - m_vFrames.push_back(frame); - frame->retain(); - } -} - -e2d::EActionFrames * e2d::EActionFrames::clone() const -{ - auto a = new EActionFrames(this->m_nAnimationInterval); - for (auto f : m_vFrames) - { - a->addFrame(f); - } - return a; -} - -e2d::EActionFrames * e2d::EActionFrames::reverse() const -{ - auto a = this->clone(); - a->m_vFrames.reserve(m_vFrames.size()); - return a; -} diff --git a/Easy2D/Action/EActionGradual.cpp b/Easy2D/Action/EActionGradual.cpp new file mode 100644 index 00000000..c9a67236 --- /dev/null +++ b/Easy2D/Action/EActionGradual.cpp @@ -0,0 +1,41 @@ +#include "..\eactions.h" +#include "..\Win\winbase.h" + +e2d::EActionGradual::EActionGradual(float duration) +{ + m_nDuration = 0; + m_nTotalDuration = UINT(duration * 1000); +} + +bool e2d::EActionGradual::_isEnd() const +{ + return m_nDuration >= m_nTotalDuration; +} + +void e2d::EActionGradual::_init() +{ + EAction::_init(); + // 记录当前时间 + m_tLast = GetNow(); +} + +bool e2d::EActionGradual::_isDelayEnough() +{ + // 判断时间间隔是否足够 + if (GetInterval(m_tLast) > m_nAnimationInterval) + { + // 重新记录时间 + m_tLast += milliseconds(m_nAnimationInterval); + m_nDuration += m_nAnimationInterval; + return true; + } + return false; +} + +void e2d::EActionGradual::_reset() +{ + EAction::_reset(); + m_nDuration = 0; + // 记录当前时间 + m_tLast = GetNow(); +} diff --git a/Easy2D/Action/EActionNeverStop.cpp b/Easy2D/Action/EActionLoop.cpp similarity index 86% rename from Easy2D/Action/EActionNeverStop.cpp rename to Easy2D/Action/EActionLoop.cpp index 0b94f570..eb2bfd11 100644 --- a/Easy2D/Action/EActionNeverStop.cpp +++ b/Easy2D/Action/EActionLoop.cpp @@ -19,7 +19,10 @@ e2d::EActionLoop * e2d::EActionLoop::clone() const void e2d::EActionLoop::_init() { EAction::_init(); - m_Action->m_pTarget = m_pTarget; + if (!m_Action->getTarget() && m_pTarget) + { + m_Action->setTarget(m_pTarget); + } m_Action->_init(); } diff --git a/Easy2D/Action/EActionMoveBy.cpp b/Easy2D/Action/EActionMoveBy.cpp index 3dbe2867..7a2fdace 100644 --- a/Easy2D/Action/EActionMoveBy.cpp +++ b/Easy2D/Action/EActionMoveBy.cpp @@ -2,20 +2,28 @@ e2d::EActionMoveBy::EActionMoveBy(float duration, EVec vector) : - EAnimation(duration) + EActionGradual(duration) { m_MoveVector = vector; } void e2d::EActionMoveBy::_init() { - EAnimation::_init(); - m_BeginPos = m_pTarget->getPos(); + EActionGradual::_init(); + if (m_pTarget) + { + m_BeginPos = m_pTarget->getPos(); + } } void e2d::EActionMoveBy::_callOn() { - while (EAnimation::_isDelayEnough()) + if (m_pTarget == nullptr) + { + this->stop(); + return; + } + while (EActionGradual::_isDelayEnough()) { // 计算移动位置 float scale = static_cast(m_nDuration) / m_nTotalDuration; @@ -35,7 +43,7 @@ void e2d::EActionMoveBy::_callOn() void e2d::EActionMoveBy::_reset() { - EAnimation::_reset(); + EActionGradual::_reset(); } e2d::EActionMoveBy * e2d::EActionMoveBy::clone() const diff --git a/Easy2D/Action/EActionOpacityBy.cpp b/Easy2D/Action/EActionOpacityBy.cpp index b9d2b6b0..6b66265e 100644 --- a/Easy2D/Action/EActionOpacityBy.cpp +++ b/Easy2D/Action/EActionOpacityBy.cpp @@ -2,20 +2,28 @@ e2d::EActionOpacityBy::EActionOpacityBy(float duration, float opacity) : - EAnimation(duration) + EActionGradual(duration) { m_nVariation = opacity; } void e2d::EActionOpacityBy::_init() { - EAnimation::_init(); - m_nBeginVal = m_pTarget->getOpacity(); + EActionGradual::_init(); + if (m_pTarget) + { + m_nBeginVal = m_pTarget->getOpacity(); + } } void e2d::EActionOpacityBy::_callOn() { - while (EAnimation::_isDelayEnough()) + if (m_pTarget == nullptr) + { + this->stop(); + return; + } + while (EActionGradual::_isDelayEnough()) { // 计算移动位置 float scale = static_cast(m_nDuration) / m_nTotalDuration; @@ -32,7 +40,7 @@ void e2d::EActionOpacityBy::_callOn() void e2d::EActionOpacityBy::_reset() { - EAnimation::_reset(); + EActionGradual::_reset(); } e2d::EActionOpacityBy * e2d::EActionOpacityBy::clone() const diff --git a/Easy2D/Action/EActionRotateBy.cpp b/Easy2D/Action/EActionRotateBy.cpp index c4e6515a..9ac061a5 100644 --- a/Easy2D/Action/EActionRotateBy.cpp +++ b/Easy2D/Action/EActionRotateBy.cpp @@ -2,20 +2,28 @@ e2d::EActionRotateBy::EActionRotateBy(float duration, float rotation) : - EAnimation(duration) + EActionGradual(duration) { m_nVariation = rotation; } void e2d::EActionRotateBy::_init() { - EAnimation::_init(); - m_nBeginVal = m_pTarget->getOpacity(); + EActionGradual::_init(); + if (m_pTarget) + { + m_nBeginVal = m_pTarget->getOpacity(); + } } void e2d::EActionRotateBy::_callOn() { - while (EAnimation::_isDelayEnough()) + if (m_pTarget == nullptr) + { + this->stop(); + return; + } + while (EActionGradual::_isDelayEnough()) { // 计算移动位置 float scale = static_cast(m_nDuration) / m_nTotalDuration; @@ -32,7 +40,7 @@ void e2d::EActionRotateBy::_callOn() void e2d::EActionRotateBy::_reset() { - EAnimation::_reset(); + EActionGradual::_reset(); } e2d::EActionRotateBy * e2d::EActionRotateBy::clone() const diff --git a/Easy2D/Action/EActionScaleBy.cpp b/Easy2D/Action/EActionScaleBy.cpp index 460cfec6..18110d14 100644 --- a/Easy2D/Action/EActionScaleBy.cpp +++ b/Easy2D/Action/EActionScaleBy.cpp @@ -2,7 +2,7 @@ e2d::EActionScaleBy::EActionScaleBy(float duration, float scaleX, float scaleY) : - EAnimation(duration) + EActionGradual(duration) { m_nVariationX = scaleX; m_nVariationY = scaleY; @@ -10,14 +10,22 @@ e2d::EActionScaleBy::EActionScaleBy(float duration, float scaleX, float scaleY) void e2d::EActionScaleBy::_init() { - EAnimation::_init(); - m_nBeginScaleX = m_pTarget->getScaleX(); - m_nBeginScaleY = m_pTarget->getScaleY(); + EActionGradual::_init(); + if (m_pTarget) + { + m_nBeginScaleX = m_pTarget->getScaleX(); + m_nBeginScaleY = m_pTarget->getScaleY(); + } } void e2d::EActionScaleBy::_callOn() { - while (EAnimation::_isDelayEnough()) + if (m_pTarget == nullptr) + { + this->stop(); + return; + } + while (EActionGradual::_isDelayEnough()) { // 计算移动位置 float scale = static_cast(m_nDuration) / m_nTotalDuration; @@ -34,7 +42,7 @@ void e2d::EActionScaleBy::_callOn() void e2d::EActionScaleBy::_reset() { - EAnimation::_reset(); + EActionGradual::_reset(); } e2d::EActionScaleBy * e2d::EActionScaleBy::clone() const diff --git a/Easy2D/Action/EActionSequence.cpp b/Easy2D/Action/EActionSequence.cpp index 0f36f1ac..8fc2c5d6 100644 --- a/Easy2D/Action/EActionSequence.cpp +++ b/Easy2D/Action/EActionSequence.cpp @@ -33,9 +33,15 @@ void e2d::EActionSequence::_init() { EAction::_init(); // 将所有动作与目标绑定 - for (auto action : m_vActions) + if (m_pTarget) { - action->m_pTarget = m_pTarget; + for (auto action : m_vActions) + { + if (!action->getTarget()) + { + action->setTarget(m_pTarget); + } + } } // 初始化第一个动作 m_vActions[0]->_init(); diff --git a/Easy2D/Action/EActionTwo.cpp b/Easy2D/Action/EActionTwo.cpp index 006b4eef..e2f29af4 100644 --- a/Easy2D/Action/EActionTwo.cpp +++ b/Easy2D/Action/EActionTwo.cpp @@ -34,8 +34,14 @@ e2d::EActionTwo * e2d::EActionTwo::reverse(bool actionReverse) const void e2d::EActionTwo::_init() { EAction::_init(); - m_pFirstAction->m_pTarget = m_pTarget; - m_pSecondAction->m_pTarget = m_pTarget; + if (!m_pFirstAction->getTarget() && m_pTarget) + { + m_pFirstAction->setTarget(m_pTarget); + } + if (!m_pSecondAction->getTarget() && m_pTarget) + { + m_pSecondAction->setTarget(m_pTarget); + } m_pFirstAction->_init(); } diff --git a/Easy2D/Action/EActionTwoAtSameTime.cpp b/Easy2D/Action/EActionTwoAtSameTime.cpp index f3bdefdd..c9a5ed08 100644 --- a/Easy2D/Action/EActionTwoAtSameTime.cpp +++ b/Easy2D/Action/EActionTwoAtSameTime.cpp @@ -34,8 +34,14 @@ e2d::EActionTwoAtSameTime * e2d::EActionTwoAtSameTime::reverse(bool actionRevers void e2d::EActionTwoAtSameTime::_init() { EAction::_init(); - m_pFirstAction->m_pTarget = m_pTarget; - m_pSecondAction->m_pTarget = m_pTarget; + if (!m_pFirstAction->getTarget() && m_pTarget) + { + m_pFirstAction->setTarget(m_pTarget); + } + if (!m_pSecondAction->getTarget() && m_pTarget) + { + m_pSecondAction->setTarget(m_pTarget); + } m_pFirstAction->_init(); m_pSecondAction->_init(); diff --git a/Easy2D/Action/EAnimation.cpp b/Easy2D/Action/EAnimation.cpp index 526a228a..f6a3ff77 100644 --- a/Easy2D/Action/EAnimation.cpp +++ b/Easy2D/Action/EAnimation.cpp @@ -1,41 +1,93 @@ #include "..\eactions.h" #include "..\Win\winbase.h" +#include -e2d::EAnimation::EAnimation(float duration) +e2d::EAnimation::EAnimation() : + m_nFrameIndex(0) { - m_nDuration = 0; - m_nTotalDuration = UINT(duration * 1000); + // 帧动画默认 0.1s 刷新一次 + setInterval(100); } -bool e2d::EAnimation::_isEnd() const +e2d::EAnimation::EAnimation(LONGLONG frameDelay) : + m_nFrameIndex(0) { - return m_nDuration >= m_nTotalDuration; + setInterval(frameDelay); +} + +e2d::EAnimation::~EAnimation() +{ + for (auto frame : m_vFrames) + { + SafeRelease(&frame); + } } void e2d::EAnimation::_init() { + // 判断执行帧动画的目标类型是否是 ESprite + ASSERT( + typeid(ESprite) == typeid(*m_pTarget), + "Only ESprite can use EAnimation!" + ); EAction::_init(); // 记录当前时间 - m_nLast = GetNow(); + m_tLast = GetNow(); } -bool e2d::EAnimation::_isDelayEnough() +void e2d::EAnimation::_callOn() { + if (m_pTarget == nullptr) + { + this->stop(); + return; + } // 判断时间间隔是否足够 - if (GetInterval(m_nLast) > m_nAnimationInterval) + while (GetInterval(m_tLast) > m_nAnimationInterval) { // 重新记录时间 - m_nLast += milliseconds(m_nAnimationInterval); - m_nDuration += m_nAnimationInterval; - return true; + m_tLast += milliseconds(m_nAnimationInterval); + reinterpret_cast(m_pTarget)->loadFromSpriteFrame(m_vFrames[m_nFrameIndex]); + m_nFrameIndex++; + // 判断动作是否结束 + if (m_nFrameIndex == m_vFrames.size()) + { + this->stop(); + break; + } } - return false; } void e2d::EAnimation::_reset() { EAction::_reset(); - m_nDuration = 0; + m_nFrameIndex = 0; // 记录当前时间 - m_nLast = GetNow(); + m_tLast = steady_clock::now(); +} + +void e2d::EAnimation::addFrame(ESpriteFrame * frame) +{ + if (frame) + { + m_vFrames.push_back(frame); + frame->retain(); + } +} + +e2d::EAnimation * e2d::EAnimation::clone() const +{ + auto a = new EAnimation(this->m_nAnimationInterval); + for (auto f : m_vFrames) + { + a->addFrame(f); + } + return a; +} + +e2d::EAnimation * e2d::EAnimation::reverse() const +{ + auto a = this->clone(); + a->m_vFrames.reserve(m_vFrames.size()); + return a; } diff --git a/Easy2D/Base/EApp.cpp b/Easy2D/Base/EApp.cpp index d144ad3d..7552e6ab 100644 --- a/Easy2D/Base/EApp.cpp +++ b/Easy2D/Base/EApp.cpp @@ -3,6 +3,7 @@ #include "..\emsg.h" #include "..\etools.h" #include "..\enodes.h" +#include "..\etransitions.h" #include #include #include @@ -20,7 +21,12 @@ static std::stack s_SceneStack; static steady_clock::time_point s_tStart; e2d::EApp::EApp() - : m_bRunning(false) + : m_bEnd(false) + , m_bPaused(false) + , m_bManualPaused(false) + , m_bTransitional(false) + , m_bEnterNextScene(true) + , m_bTopMost(false) , nAnimationInterval(17LL) , m_ClearColor(EColor::BLACK) , m_pCurrentScene(nullptr) @@ -29,17 +35,17 @@ e2d::EApp::EApp() ASSERT(s_pInstance == nullptr, "EApp instance already exists!"); s_pInstance = this; // 保存实例对象 - CoInitialize(NULL); + CoInitializeEx(NULL, COINIT_MULTITHREADED); } e2d::EApp::~EApp() { // 释放资源 + SafeReleaseInterface(&GetSolidColorBrush()); SafeReleaseInterface(&GetRenderTarget()); SafeReleaseInterface(&GetFactory()); SafeReleaseInterface(&GetImagingFactory()); SafeReleaseInterface(&GetDirectWriteFactory()); - SafeReleaseInterface(&GetSolidColorBrush()); CoUninitialize(); } @@ -52,7 +58,7 @@ e2d::EApp * e2d::EApp::get() bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, bool showConsole /* = false */) { - return init(title, width, height, WS_OVERLAPPEDWINDOW, showConsole); + return init(title, width, height, 0, showConsole); } bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int windowStyle, bool showConsole /* = false */) @@ -69,7 +75,12 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind { // 注册窗口类 WNDCLASSEX wcex = { sizeof(WNDCLASSEX) }; - wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + UINT style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + if (windowStyle & EApp::NO_CLOSE) + { + style |= CS_NOCLOSE; + } + wcex.style = style; wcex.lpfnWndProc = EApp::WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = sizeof(LONG_PTR); @@ -106,15 +117,25 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind rtWindow.top = (screenHeight - height) / 2; rtWindow.right = rtWindow.left + width; rtWindow.bottom = rtWindow.top + height; + // 创建窗口样式 + DWORD dwStyle = WS_OVERLAPPED | WS_SYSMENU; + if (windowStyle & EApp::NO_MINI_SIZE) + { + dwStyle &= ~WS_MINIMIZEBOX; + } + if (windowStyle & EApp::TOP_MOST) + { + m_bTopMost = true; + } // 计算客户区大小 - AdjustWindowRectEx(&rtWindow, windowStyle, FALSE, 0L); + AdjustWindowRectEx(&rtWindow, dwStyle, FALSE, 0L); // 保存窗口名称 m_sTitle = title; // 创建窗口 GetHWnd() = CreateWindow( L"Easy2DApp", m_sTitle.c_str(), - windowStyle, + dwStyle, rtWindow.left, rtWindow.top, rtWindow.right - rtWindow.left, @@ -146,6 +167,27 @@ bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, int wind return SUCCEEDED(hr); } +void e2d::EApp::pause() +{ + EApp::get()->m_bManualPaused = true; +} + +void e2d::EApp::resume() +{ + if (isPaused()) + { + EApp::get()->m_bPaused = false; + EApp::get()->m_bManualPaused = false; + EActionManager::_resetAllActions(); + ETimerManager::_resetAllTimers(); + } +} + +bool e2d::EApp::isPaused() +{ + return s_pInstance->m_bPaused || s_pInstance->m_bManualPaused; +} + void e2d::EApp::showConsole(bool show) { // 查找已存在的控制台句柄 @@ -198,18 +240,20 @@ void e2d::EApp::run() ASSERT(GetHWnd() != nullptr, "Cannot find Game Window."); // 进入第一个场景 _enterNextScene(); - ASSERT(m_pCurrentScene != nullptr, "Current scene NULL pointer exception."); // 显示窗口 ShowWindow(GetHWnd(), SW_SHOWNORMAL); UpdateWindow(GetHWnd()); - // 运行游戏 - m_bRunning = true; + // 设置窗口置顶 + if (m_bTopMost) + { + SetWindowPos(GetHWnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } // 记录开始时间 s_tStart = steady_clock::now(); MSG msg; - while (m_bRunning) + while (!m_bEnd) { // 处理窗口消息 while (PeekMessage(&msg, GetHWnd(), 0, 0, PM_REMOVE)) @@ -224,17 +268,18 @@ void e2d::EApp::run() // 关闭控制台 EApp::showConsole(false); // 释放所有内存资源 - this->free(); + this->_free(); } void e2d::EApp::setFPS(UINT32 fps) { fps = min(max(fps, 30), 120); - nAnimationInterval = 1000 / fps; + s_pInstance->nAnimationInterval = 1000 / fps; } -void e2d::EApp::onActivate() +bool e2d::EApp::onActivate() { + return true; } bool e2d::EApp::onInactive() @@ -264,18 +309,10 @@ void e2d::EApp::_mainLoop() { // 记录当前时间 tLast = GetNow(); - - if (!m_bPaused) - { - // 游戏控制流程 - _onControl(); - // 刷新游戏画面 - if (!_onRender()) - { - MessageBox(GetHWnd(), L"Game Render Failed!", L"Error", MB_OK); - this->quit(); - } - } + // 游戏控制流程 + _onControl(); + // 刷新游戏画面 + _onRender(); } else { @@ -292,11 +329,20 @@ void e2d::EApp::_mainLoop() void e2d::EApp::_onControl() { // 下一场景指针不为空时,切换场景 - if (m_pNextScene) + if (m_bEnterNextScene) { // 进入下一场景 _enterNextScene(); + m_bEnterNextScene = false; } + + // 正在切换场景时,只执行动画 + if (m_bTransitional) + { + EActionManager::ActionProc(); + return; + } + // 断言当前场景非空 ASSERT(m_pCurrentScene != nullptr, "Current scene NULL pointer exception."); @@ -308,7 +354,7 @@ void e2d::EApp::_onControl() // This method discards device-specific // resources if the Direct3D device dissapears during execution and // recreates the resources the next time it's invoked. -bool e2d::EApp::_onRender() +void e2d::EApp::_onRender() { HRESULT hr = S_OK; @@ -316,12 +362,13 @@ bool e2d::EApp::_onRender() if (SUCCEEDED(hr)) { + // 开始绘图 GetRenderTarget()->BeginDraw(); // 使用背景色清空屏幕 GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor.value)); // 绘制当前场景 m_pCurrentScene->_onRender(); - + // 终止绘图 hr = GetRenderTarget()->EndDraw(); // 刷新界面 UpdateWindow(GetHWnd()); @@ -333,7 +380,11 @@ bool e2d::EApp::_onRender() _discardDeviceResources(); } - return SUCCEEDED(hr); + if (FAILED(hr)) + { + MessageBox(GetHWnd(), L"Game Render Failed!", L"Error", MB_OK); + this->quit(); + } } void e2d::EApp::setWindowSize(UINT32 width, UINT32 height) @@ -377,18 +428,44 @@ UINT32 e2d::EApp::getHeight() return GetRenderTarget()->GetPixelSize().height; } -void e2d::EApp::enterScene(EScene * scene, bool save /* = true */) +void e2d::EApp::enterScene(EScene * scene, bool saveCurrentScene /* = true */) { + enterScene(scene, nullptr, saveCurrentScene); +} + +void e2d::EApp::enterScene(EScene * scene, ETransition * transition, bool saveCurrentScene /* = true */) +{ + scene->retain(); // 保存下一场景的指针 get()->m_pNextScene = scene; // 切换场景时,是否保存当前场景 if (get()->m_pCurrentScene) { - get()->m_pCurrentScene->m_bWillSave = save; + get()->m_pCurrentScene->m_bWillSave = saveCurrentScene; + } + // 设置切换场景动画 + if (transition) + { + get()->m_bTransitional = true; + transition->_setTarget( + get()->m_pCurrentScene, + get()->m_pNextScene, + get()->m_bEnterNextScene, + get()->m_bTransitional + ); + } + else + { + get()->m_bTransitional = false; } } void e2d::EApp::backScene() +{ + backScene(nullptr); +} + +void e2d::EApp::backScene(ETransition * transition) { ASSERT(s_SceneStack.size(), "Scene stack now is empty!"); // 从栈顶取出场景指针,作为下一场景 @@ -399,6 +476,21 @@ void e2d::EApp::backScene() { get()->m_pCurrentScene->m_bWillSave = false; } + // 设置切换场景动画 + if (transition) + { + get()->m_bTransitional = true; + transition->_setTarget( + get()->m_pCurrentScene, + get()->m_pNextScene, + get()->m_bEnterNextScene, + get()->m_bTransitional + ); + } + else + { + get()->m_bTransitional = false; + } } void e2d::EApp::clearScene() @@ -407,7 +499,7 @@ void e2d::EApp::clearScene() while (s_SceneStack.size()) { auto temp = s_SceneStack.top(); - SafeDelete(&temp); + SafeRelease(&temp); s_SceneStack.pop(); } } @@ -475,41 +567,43 @@ void e2d::EApp::showWindow() ShowWindow(GetHWnd(), SW_SHOWNORMAL); } -void e2d::EApp::free() +void e2d::EApp::_free() { - // 释放场景内存 - SafeDelete(&m_pCurrentScene); - SafeDelete(&m_pNextScene); // 清空场景栈 - while (s_SceneStack.size()) - { - auto temp = s_SceneStack.top(); - SafeDelete(&temp); - s_SceneStack.pop(); - } + clearScene(); + // 释放场景内存 + SafeRelease(&m_pCurrentScene); + SafeRelease(&m_pNextScene); + // 删除图片缓存 ETexture::clearCache(); + // 停止所有定时器、监听器、动画 + ETimerManager::_clearManager(); + EMsgManager::_clearManager(); + EActionManager::_clearManager(); // 删除所有对象 EObjectManager::clearAllObjects(); } void e2d::EApp::quit() { - get()->m_bRunning = false; + get()->m_bEnd = true; } void e2d::EApp::end() { - get()->m_bRunning = false; + get()->m_bEnd = true; } void e2d::EApp::_enterNextScene() { + if (m_pNextScene == nullptr) + return; + // 执行当前场景的 onCloseWindow 函数 if (m_pCurrentScene) { m_pCurrentScene->onExit(); - m_pCurrentScene->_onExit(); if (m_pCurrentScene->m_bWillSave) { @@ -518,12 +612,11 @@ void e2d::EApp::_enterNextScene() } else { - SafeDelete(&m_pCurrentScene); + SafeRelease(&m_pCurrentScene); } } // 执行下一场景的 onEnter 函数 - m_pNextScene->_onEnter(); m_pNextScene->onEnter(); m_pCurrentScene = m_pNextScene; // 切换场景 @@ -627,7 +720,11 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam case WM_MOUSEMOVE: case WM_MOUSEWHEEL: { - EMsgManager::MouseProc(message, wParam, lParam); + // 执行场景切换时屏蔽按键和鼠标消息 + if (!pEApp->m_bTransitional) + { + EMsgManager::MouseProc(message, wParam, lParam); + } } result = 0; wasHandled = true; @@ -637,7 +734,11 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam case WM_KEYDOWN: case WM_KEYUP: { - EMsgManager::KeyboardProc(message, wParam, lParam); + // 执行场景切换时屏蔽按键和鼠标消息 + if (!pEApp->m_bTransitional) + { + EMsgManager::KeyboardProc(message, wParam, lParam); + } } result = 0; wasHandled = true; @@ -687,9 +788,11 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam } else { - pEApp->onActivate(); - pEApp->getCurrentScene()->onActivate(); - pEApp->m_bPaused = false; + if (pEApp->getCurrentScene()->onActivate() && + pEApp->onActivate()) + { + pEApp->m_bPaused = false; + } } } result = 1; diff --git a/Easy2D/Base/EScene.cpp b/Easy2D/Base/EScene.cpp index 8c736f1b..d7647f67 100644 --- a/Easy2D/Base/EScene.cpp +++ b/Easy2D/Base/EScene.cpp @@ -15,11 +15,11 @@ e2d::EScene::EScene() e2d::EScene::~EScene() { - SafeRelease(&m_pRoot); ETimerManager::clearAllTimersBindedWith(this); EMsgManager::clearAllMouseListenersBindedWith(this); EMsgManager::clearAllKeyboardListenersBindedWith(this); EActionManager::clearAllActionsBindedWith(this); + SafeRelease(&m_pRoot); } void e2d::EScene::onEnter() @@ -30,8 +30,9 @@ void e2d::EScene::onExit() { } -void e2d::EScene::onActivate() +bool e2d::EScene::onActivate() { + return true; } bool e2d::EScene::onInactive() @@ -49,26 +50,6 @@ void e2d::EScene::_onRender() m_pRoot->_callOn(); } -void e2d::EScene::_onEnter() -{ - // 启用场景上的所有定时器、监听器和动画 - ETimerManager::_notifyAllTimersBindedWith(this); - EMsgManager::_notifyAllMouseListenersBindedWith(this); - EMsgManager::_notifyAllKeyboardListenersBindedWith(this); - EActionManager::_notifyAllActionsBindedWith(this); -} - -void e2d::EScene::_onExit() -{ - if (m_bWillSave) - { - ETimerManager::_waitAllTimersBindedWith(this); - EMsgManager::_waitAllMouseListenersBindedWith(this); - EMsgManager::_waitAllKeyboardListenersBindedWith(this); - EActionManager::_waitAllActionsBindedWith(this); - } -} - void e2d::EScene::add(ENode * child, int order /* = 0 */) { m_pRoot->addChild(child, order); @@ -99,6 +80,11 @@ e2d::ENode * e2d::EScene::getChild(const EString &childName) return m_pRoot->getChild(childName); } +e2d::ENode * e2d::EScene::getRoot() const +{ + return m_pRoot; +} + void e2d::EScene::clearAllChildren() { m_pRoot->clearAllChildren(); diff --git a/Easy2D/ETimer.cpp b/Easy2D/ETimer.cpp index 3b42e30e..3272236a 100644 --- a/Easy2D/ETimer.cpp +++ b/Easy2D/ETimer.cpp @@ -3,7 +3,6 @@ e2d::ETimer::ETimer() : m_bRunning(false) - , m_bWaiting(false) , m_nRunTimes(0) , m_pParentScene(nullptr) , m_pParentNode(nullptr) @@ -33,12 +32,7 @@ e2d::ETimer::ETimer(const EString & name, const TIMER_CALLBACK & callback, LONGL bool e2d::ETimer::isRunning() const { - return m_bRunning && !m_bWaiting; -} - -bool e2d::ETimer::isWaiting() const -{ - return m_bWaiting; + return m_bRunning; } void e2d::ETimer::start() @@ -52,17 +46,6 @@ void e2d::ETimer::stop() m_bRunning = false; } -void e2d::ETimer::_wait() -{ - m_bWaiting = true; -} - -void e2d::ETimer::_notify() -{ - m_bWaiting = false; - m_tLast = GetNow(); -} - e2d::EString e2d::ETimer::getName() const { return m_sName; diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index 3a108153..c40ae968 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -195,10 +195,10 @@ - + - + @@ -208,30 +208,33 @@ - + - - - - - - - - - + + + + + + + + + + + + + - - + - + @@ -243,6 +246,7 @@ + diff --git a/Easy2D/Easy2D.vcxproj.filters b/Easy2D/Easy2D.vcxproj.filters index 6ca3be05..2c30e2ae 100644 --- a/Easy2D/Easy2D.vcxproj.filters +++ b/Easy2D/Easy2D.vcxproj.filters @@ -13,15 +13,18 @@ {261633d3-3814-40c7-bd6d-201ede6c6ade} - - {cc102a62-b34d-493c-be3c-f3e5dfbe4cf4} - - - {b9bb1728-5106-4574-998e-8564b49cb4a1} - {50293f38-87fe-4dde-b938-cf1b7a2921f8} + + {563b19f2-4c5e-4362-983a-94d2ae724550} + + + {9031e36b-fa85-4b4e-8e80-657c7e68f283} + + + {b9bb1728-5106-4574-998e-8564b49cb4a1} + @@ -36,48 +39,15 @@ Node - - Tool - Base - - Msg - - - Msg\Listener - - - Msg\Listener - - - Msg\Listener - - - Tool - Node - - Msg\Listener - - - Msg\Listener - - - Msg\Listener - Tool - - Msg\Listener - - - Msg\Listener - Node @@ -87,9 +57,6 @@ Node - - Tool - Action @@ -99,18 +66,12 @@ Action - - Action - Action Action - - Action - Action @@ -129,9 +90,6 @@ Action - - Action - Action @@ -147,6 +105,60 @@ Action + + Tool + + + Node + + + Action + + + Action + + + Transition + + + Action + + + Manager + + + Manager + + + Manager + + + Manager + + + Listener + + + Listener + + + Listener + + + Listener + + + Listener + + + Listener + + + Listener + + + Listener + @@ -160,5 +172,6 @@ + \ No newline at end of file diff --git a/Easy2D/Msg/Listener/EKeyboardListener.cpp b/Easy2D/Listener/EKeyboardListener.cpp similarity index 97% rename from Easy2D/Msg/Listener/EKeyboardListener.cpp rename to Easy2D/Listener/EKeyboardListener.cpp index 61b2a160..a95610a4 100644 --- a/Easy2D/Msg/Listener/EKeyboardListener.cpp +++ b/Easy2D/Listener/EKeyboardListener.cpp @@ -1,4 +1,4 @@ -#include "..\..\emsg.h" +#include "..\emsg.h" e2d::EKeyboardListener::EKeyboardListener() : EListener() diff --git a/Easy2D/Msg/Listener/EKeyboardPressListener.cpp b/Easy2D/Listener/EKeyboardPressListener.cpp similarity index 96% rename from Easy2D/Msg/Listener/EKeyboardPressListener.cpp rename to Easy2D/Listener/EKeyboardPressListener.cpp index 69162bec..7935ecc7 100644 --- a/Easy2D/Msg/Listener/EKeyboardPressListener.cpp +++ b/Easy2D/Listener/EKeyboardPressListener.cpp @@ -1,4 +1,4 @@ -#include "..\..\emsg.h" +#include "..\emsg.h" e2d::EKeyboardPressListener::EKeyboardPressListener() : EKeyboardListener() diff --git a/Easy2D/Msg/Listener/EListener.cpp b/Easy2D/Listener/EListener.cpp similarity index 66% rename from Easy2D/Msg/Listener/EListener.cpp rename to Easy2D/Listener/EListener.cpp index ff8b384d..336056a7 100644 --- a/Easy2D/Msg/Listener/EListener.cpp +++ b/Easy2D/Listener/EListener.cpp @@ -1,65 +1,49 @@ -#include "..\..\emsg.h" - -e2d::EListener::EListener() - : m_bRunning(false) - , m_bWaiting(false) - , m_pParentScene(nullptr) - , m_pParentNode(nullptr) -{ -} - -e2d::EListener::EListener(const EString & name) - : EListener() -{ - m_sName = name; -} - -bool e2d::EListener::isRunning() const -{ - return m_bRunning && !m_bWaiting; -} - -bool e2d::EListener::isWaiting() const -{ - return m_bWaiting; -} - -void e2d::EListener::start() -{ - m_bRunning = true; -} - -void e2d::EListener::stop() -{ - m_bRunning = false; -} - -void e2d::EListener::_wait() -{ - m_bWaiting = true; -} - -void e2d::EListener::_notify() -{ - m_bWaiting = false; -} - -e2d::EString e2d::EListener::getName() const -{ - return m_sName; -} - -e2d::EScene * e2d::EListener::getParentScene() const -{ - return m_pParentScene; -} - -e2d::ENode * e2d::EListener::getParentNode() const -{ - return m_pParentNode; -} - -void e2d::EListener::setName(const EString & name) -{ - m_sName = name; -} +#include "..\emsg.h" + +e2d::EListener::EListener() + : m_bRunning(false) + , m_pParentScene(nullptr) + , m_pParentNode(nullptr) +{ +} + +e2d::EListener::EListener(const EString & name) + : EListener() +{ + m_sName = name; +} + +bool e2d::EListener::isRunning() const +{ + return m_bRunning; +} + +void e2d::EListener::start() +{ + m_bRunning = true; +} + +void e2d::EListener::stop() +{ + m_bRunning = false; +} + +e2d::EString e2d::EListener::getName() const +{ + return m_sName; +} + +e2d::EScene * e2d::EListener::getParentScene() const +{ + return m_pParentScene; +} + +e2d::ENode * e2d::EListener::getParentNode() const +{ + return m_pParentNode; +} + +void e2d::EListener::setName(const EString & name) +{ + m_sName = name; +} diff --git a/Easy2D/Msg/Listener/EMouseClickListener.cpp b/Easy2D/Listener/EMouseClickListener.cpp similarity index 93% rename from Easy2D/Msg/Listener/EMouseClickListener.cpp rename to Easy2D/Listener/EMouseClickListener.cpp index f1b3c861..c76890a4 100644 --- a/Easy2D/Msg/Listener/EMouseClickListener.cpp +++ b/Easy2D/Listener/EMouseClickListener.cpp @@ -1,46 +1,46 @@ -#include "..\..\emsg.h" - -e2d::EMouseClickListener::EMouseClickListener() - : EMouseListener() - , m_bPressed(false) -{ -} - -e2d::EMouseClickListener::EMouseClickListener(const EString & name) - : EMouseListener(name) - , m_bPressed(false) -{ -} - -e2d::EMouseClickListener::EMouseClickListener(const MOUSE_CLICK_LISTENER_CALLBACK & callback) - : EMouseListener() - , m_Callback(callback) - , m_bPressed(false) -{ -} - -e2d::EMouseClickListener::EMouseClickListener(const EString & name, const MOUSE_CLICK_LISTENER_CALLBACK & callback) - : EMouseListener(name) - , m_Callback(callback) - , m_bPressed(false) -{ -} - -void e2d::EMouseClickListener::_callOn() -{ - if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN || - EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK) - { - m_bPressed = true; - } - else if (m_bPressed && EMouseMsg::getMsg() == EMouseMsg::LBUTTON_UP) - { - m_Callback(EMouseMsg::getPos()); - m_bPressed = false; - } -} - -void e2d::EMouseClickListener::setCallback(const MOUSE_CLICK_LISTENER_CALLBACK & callback) -{ - m_Callback = callback; -} +#include "..\emsg.h" + +e2d::EMouseClickListener::EMouseClickListener() + : EMouseListener() + , m_bPressed(false) +{ +} + +e2d::EMouseClickListener::EMouseClickListener(const EString & name) + : EMouseListener(name) + , m_bPressed(false) +{ +} + +e2d::EMouseClickListener::EMouseClickListener(const MOUSE_CLICK_LISTENER_CALLBACK & callback) + : EMouseListener() + , m_Callback(callback) + , m_bPressed(false) +{ +} + +e2d::EMouseClickListener::EMouseClickListener(const EString & name, const MOUSE_CLICK_LISTENER_CALLBACK & callback) + : EMouseListener(name) + , m_Callback(callback) + , m_bPressed(false) +{ +} + +void e2d::EMouseClickListener::_callOn() +{ + if (EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DOWN || + EMouseMsg::getMsg() == EMouseMsg::LBUTTON_DBLCLK) + { + m_bPressed = true; + } + else if (m_bPressed && EMouseMsg::getMsg() == EMouseMsg::LBUTTON_UP) + { + m_Callback(EMouseMsg::getPos()); + m_bPressed = false; + } +} + +void e2d::EMouseClickListener::setCallback(const MOUSE_CLICK_LISTENER_CALLBACK & callback) +{ + m_Callback = callback; +} diff --git a/Easy2D/Msg/Listener/EMouseDoubleClickListener.cpp b/Easy2D/Listener/EMouseDoubleClickListener.cpp similarity index 97% rename from Easy2D/Msg/Listener/EMouseDoubleClickListener.cpp rename to Easy2D/Listener/EMouseDoubleClickListener.cpp index 8071f432..26679aff 100644 --- a/Easy2D/Msg/Listener/EMouseDoubleClickListener.cpp +++ b/Easy2D/Listener/EMouseDoubleClickListener.cpp @@ -1,4 +1,4 @@ -#include "..\..\emsg.h" +#include "..\emsg.h" e2d::EMouseDoubleClickListener::EMouseDoubleClickListener() : EMouseListener() diff --git a/Easy2D/Msg/Listener/EMouseDragListener.cpp b/Easy2D/Listener/EMouseDragListener.cpp similarity index 97% rename from Easy2D/Msg/Listener/EMouseDragListener.cpp rename to Easy2D/Listener/EMouseDragListener.cpp index 8eac4183..c2d1ac20 100644 --- a/Easy2D/Msg/Listener/EMouseDragListener.cpp +++ b/Easy2D/Listener/EMouseDragListener.cpp @@ -1,4 +1,4 @@ -#include "..\..\emsg.h" +#include "..\emsg.h" e2d::EMouseDragListener::EMouseDragListener() : EMouseListener() diff --git a/Easy2D/Msg/Listener/EMouseListener.cpp b/Easy2D/Listener/EMouseListener.cpp similarity index 93% rename from Easy2D/Msg/Listener/EMouseListener.cpp rename to Easy2D/Listener/EMouseListener.cpp index 90bcc713..e10f8bf8 100644 --- a/Easy2D/Msg/Listener/EMouseListener.cpp +++ b/Easy2D/Listener/EMouseListener.cpp @@ -1,53 +1,53 @@ -#include "..\..\emsg.h" - -e2d::EMouseListener::EMouseListener() - : EListener() -{ -} - -e2d::EMouseListener::EMouseListener(const EString & name) - : EListener(name) -{ -} - -e2d::EMouseListener::EMouseListener(const MOUSE_LISTENER_CALLBACK & callback) - : EListener() -{ - m_Callback = callback; -} - -e2d::EMouseListener::EMouseListener(const EString & name, const MOUSE_LISTENER_CALLBACK & callback) - : EListener(name) -{ - m_Callback = callback; -} - -void e2d::EMouseListener::_callOn() -{ - m_Callback(); -} - -void e2d::EMouseListener::setCallback(const MOUSE_LISTENER_CALLBACK & callback) -{ - m_Callback = callback; -} - -void e2d::EMouseListener::bindWith(EScene * pParentScene) -{ - WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); - - if (pParentScene) - { - EMsgManager::bindListener(this, pParentScene); - } -} - -void e2d::EMouseListener::bindWith(ENode * pParentNode) -{ - WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); - - if (pParentNode != nullptr && m_pParentScene == nullptr) - { - EMsgManager::bindListener(this, pParentNode); - } -} +#include "..\emsg.h" + +e2d::EMouseListener::EMouseListener() + : EListener() +{ +} + +e2d::EMouseListener::EMouseListener(const EString & name) + : EListener(name) +{ +} + +e2d::EMouseListener::EMouseListener(const MOUSE_LISTENER_CALLBACK & callback) + : EListener() +{ + m_Callback = callback; +} + +e2d::EMouseListener::EMouseListener(const EString & name, const MOUSE_LISTENER_CALLBACK & callback) + : EListener(name) +{ + m_Callback = callback; +} + +void e2d::EMouseListener::_callOn() +{ + m_Callback(); +} + +void e2d::EMouseListener::setCallback(const MOUSE_LISTENER_CALLBACK & callback) +{ + m_Callback = callback; +} + +void e2d::EMouseListener::bindWith(EScene * pParentScene) +{ + WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); + + if (pParentScene) + { + EMsgManager::bindListener(this, pParentScene); + } +} + +void e2d::EMouseListener::bindWith(ENode * pParentNode) +{ + WARN_IF(m_pParentScene != nullptr || m_pParentNode != nullptr, "EListener cannot bind with two object."); + + if (pParentNode != nullptr && m_pParentScene == nullptr) + { + EMsgManager::bindListener(this, pParentNode); + } +} diff --git a/Easy2D/Msg/Listener/EMousePressListener.cpp b/Easy2D/Listener/EMousePressListener.cpp similarity index 97% rename from Easy2D/Msg/Listener/EMousePressListener.cpp rename to Easy2D/Listener/EMousePressListener.cpp index 81d94344..1f71b219 100644 --- a/Easy2D/Msg/Listener/EMousePressListener.cpp +++ b/Easy2D/Listener/EMousePressListener.cpp @@ -1,4 +1,4 @@ -#include "..\..\emsg.h" +#include "..\emsg.h" e2d::EMousePressListener::EMousePressListener() : EMouseListener() diff --git a/Easy2D/Tool/EActionManager.cpp b/Easy2D/Manager/EActionManager.cpp similarity index 66% rename from Easy2D/Tool/EActionManager.cpp rename to Easy2D/Manager/EActionManager.cpp index 8c70df05..cecf5ab5 100644 --- a/Easy2D/Tool/EActionManager.cpp +++ b/Easy2D/Manager/EActionManager.cpp @@ -1,23 +1,18 @@ #include "..\etools.h" #include "..\eactions.h" +#include "..\Win\winbase.h" static e2d::EVector s_vActions; -void e2d::EActionManager::bindAction(EAction * action, ENode * pTargetNode) +void e2d::EActionManager::addAction(EAction * action) { - ASSERT( - (!action->m_pTarget), - "The action is already running, it cannot running again!" - ); WARN_IF(action == nullptr, "EAction NULL pointer exception!"); - WARN_IF(pTargetNode == nullptr, "EAction's target is NULL!"); - if (action && pTargetNode) + if (action) { action->start(); action->retain(); - action->m_pTarget = pTargetNode; s_vActions.push_back(action); } } @@ -130,67 +125,22 @@ void e2d::EActionManager::clearAllActions() EActionManager::clearAllActionsBindedWith(EApp::getCurrentScene()); } -void e2d::EActionManager::_waitAllActionsBindedWith(EScene * pParentScene) +void e2d::EActionManager::_clearManager() { - if (pParentScene) - { - for (const auto &child : pParentScene->getChildren()) - { - EActionManager::_waitAllActionsBindedWith(child); - } - } + s_vActions.clear(); } -void e2d::EActionManager::_notifyAllActionsBindedWith(EScene * pParentScene) +void e2d::EActionManager::_resetAllActions() { - if (pParentScene) + for (const auto & action : s_vActions) { - for (const auto &child : pParentScene->getChildren()) - { - EActionManager::_notifyAllActionsBindedWith(child); - } - } -} - -void e2d::EActionManager::_waitAllActionsBindedWith(ENode * pTargetNode) -{ - if (pTargetNode) - { - for (const auto &action : s_vActions) - { - if (action->getTarget() == pTargetNode) - { - action->_wait(); - } - } - for (const auto &child : pTargetNode->getChildren()) - { - EActionManager::_waitAllActionsBindedWith(child); - } - } -} - -void e2d::EActionManager::_notifyAllActionsBindedWith(ENode * pTargetNode) -{ - if (pTargetNode) - { - for (const auto &action : s_vActions) - { - if (action->getTarget() == pTargetNode) - { - action->_notify(); - } - } - for (const auto &child : pTargetNode->getChildren()) - { - EActionManager::_notifyAllActionsBindedWith(child); - } + action->m_tLast = GetNow(); } } void e2d::EActionManager::ActionProc() { - if (s_vActions.empty()) + if (EApp::isPaused() || s_vActions.empty()) return; EAction * action; @@ -199,7 +149,8 @@ void e2d::EActionManager::ActionProc() { action = s_vActions[i]; // 获取动作运行状态 - if (action->isRunning()) + if (action->isRunning() || + (action->getTarget() && action->getTarget()->getParentScene() == EApp::getCurrentScene())) { if (action->_isEnding()) { diff --git a/Easy2D/Msg/EMsgManager.cpp b/Easy2D/Manager/EMsgManager.cpp similarity index 78% rename from Easy2D/Msg/EMsgManager.cpp rename to Easy2D/Manager/EMsgManager.cpp index 8229bcea..612f6d65 100644 --- a/Easy2D/Msg/EMsgManager.cpp +++ b/Easy2D/Manager/EMsgManager.cpp @@ -1,659 +1,558 @@ -#include "..\emsg.h" -#include "..\enodes.h" -#include "..\Win\winbase.h" - - -// 鼠标消息 -e2d::EMouseMsg s_MouseMsg; -// 按键消息 -e2d::EKeyboardMsg s_KeyboardMsg; -// 鼠标消息监听器 -e2d::EVector s_vMouseListeners; -// 按键消息监听器 -e2d::EVector s_vKeyboardListeners; - - -DWORD e2d::EMouseMsg::getPosX() -{ - return LOWORD(s_MouseMsg.m_lParam); -} - -DWORD e2d::EMouseMsg::getPosY() -{ - return HIWORD(s_MouseMsg.m_lParam); -} - -e2d::EPoint e2d::EMouseMsg::getPos() -{ - return EPoint(LOWORD(s_MouseMsg.m_lParam), HIWORD(s_MouseMsg.m_lParam)); -} - -bool e2d::EMouseMsg::isLButtonDown() -{ - return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_LBUTTON; -} - -bool e2d::EMouseMsg::isMButtonDown() -{ - return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_MBUTTON; -} - -bool e2d::EMouseMsg::isRButtonDown() -{ - return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_RBUTTON; -} - -bool e2d::EMouseMsg::isShiftDown() -{ - return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_SHIFT; -} - -bool e2d::EMouseMsg::isCtrlDown() -{ - return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_CONTROL; -} - -DWORD e2d::EMouseMsg::getWheelDelta() -{ - return GET_WHEEL_DELTA_WPARAM(s_MouseMsg.m_wParam); -} - -e2d::EMouseMsg::MOUSE_MSG e2d::EMouseMsg::getMsg() -{ - return MOUSE_MSG(s_MouseMsg.m_nMsg); -} - - - -e2d::EKeyboardMsg::KEYBOARD_MSG e2d::EKeyboardMsg::getMsg() -{ - return KEYBOARD_MSG(s_KeyboardMsg.m_nMsg); -} - -e2d::EKeyboardMsg::KEY e2d::EKeyboardMsg::getVal() -{ - return KEY(s_KeyboardMsg.m_wParam); -} - -DWORD e2d::EKeyboardMsg::getCount() -{ - return (((DWORD)s_KeyboardMsg.m_lParam) & 0x0000FFFF); -} - -bool e2d::EKeyboardMsg::isKeyDown(KEY key) -{ - if (::GetAsyncKeyState((int)key) & 0x8000) - { - return true; - } - return false; -} - -bool e2d::EKeyboardMsg::isCapitalLockOn() -{ - if (::GetKeyState(VK_CAPITAL) & 0x0001) - { - return true; - } - return false; -} - -bool e2d::EKeyboardMsg::isNumpadLockOn() -{ - if (::GetKeyState(VK_NUMLOCK) & 0x0001) - { - return true; - } - return false; -} - -bool e2d::EKeyboardMsg::isScrollLockOn() -{ - if (::GetKeyState(VK_SCROLL) & 0x0001) - { - return true; - } - return false; -} - - - -void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - // 保存鼠标消息 - s_MouseMsg.m_nMsg = message; - s_MouseMsg.m_wParam = wParam; - s_MouseMsg.m_lParam = lParam; - // 执行鼠标消息监听函数 - for (auto mlistener : s_vMouseListeners) - { - if (mlistener->isRunning()) - { - mlistener->_callOn(); - } - } -} - -void e2d::EMsgManager::KeyboardProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - // 保存按键消息 - s_KeyboardMsg.m_nMsg = message; - s_KeyboardMsg.m_wParam = wParam; - s_KeyboardMsg.m_lParam = lParam; - // 执行按键消息监听函数 - for (auto klistener : s_vKeyboardListeners) - { - if (klistener->isRunning()) - { - klistener->_callOn(); - } - } -} - -void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pParentScene) -{ - ASSERT( - (!listener->m_pParentNode) && (!listener->m_pParentScene), - "The listener is already binded, it cannot bind again!" - ); - WARN_IF(listener == nullptr, "EMouseListener NULL pointer exception!"); - WARN_IF(pParentScene == nullptr, "Bind EMouseListener with a NULL EScene pointer!"); - - if (listener && pParentScene) - { - listener->start(); - listener->retain(); - listener->m_pParentScene = pParentScene; - s_vMouseListeners.push_back(listener); - } -} - -void e2d::EMsgManager::bindListener(EKeyboardListener * listener, EScene * pParentScene) -{ - ASSERT( - (!listener->m_pParentNode) && (!listener->m_pParentScene), - "The listener is already binded, it cannot bind again!" - ); - WARN_IF(listener == nullptr, "EKeyboardListener NULL pointer exception!"); - WARN_IF(pParentScene == nullptr, "Bind EKeyboardListener with a NULL EScene pointer!"); - - if (listener && pParentScene) - { - listener->start(); - listener->retain(); - listener->m_pParentScene = pParentScene; - s_vKeyboardListeners.push_back(listener); - } -} - -void e2d::EMsgManager::bindListener(EMouseListener * listener, ENode * pParentNode) -{ - ASSERT( - (!listener->m_pParentNode) && (!listener->m_pParentScene), - "The listener is already binded, it cannot bind again!" - ); - WARN_IF(listener == nullptr, "EMouseListener NULL pointer exception!"); - WARN_IF(pParentNode == nullptr, "Bind EMouseListener with a NULL ENode pointer!"); - - if (listener && pParentNode) - { - listener->start(); - listener->retain(); - listener->m_pParentNode = pParentNode; - s_vMouseListeners.push_back(listener); - } -} - -void e2d::EMsgManager::bindListener(EKeyboardListener * listener, ENode * pParentNode) -{ - ASSERT( - (!listener->m_pParentNode) && (!listener->m_pParentScene), - "The listener is already binded, it cannot bind again!" - ); - WARN_IF(listener == nullptr, "EKeyboardListener NULL pointer exception!"); - WARN_IF(pParentNode == nullptr, "Bind EKeyboardListener with a NULL ENode pointer!"); - - if (listener && pParentNode) - { - listener->start(); - listener->retain(); - listener->m_pParentNode = pParentNode; - s_vKeyboardListeners.push_back(listener); - } -} - -void e2d::EMsgManager::startMouseListeners(const EString & name) -{ - for (auto l : s_vMouseListeners) - { - if (l->getName() == name) - { - l->start(); - } - } -} - -void e2d::EMsgManager::stopMouseListeners(const EString & name) -{ - for (auto l : s_vMouseListeners) - { - if (l->getName() == name) - { - l->stop(); - } - } -} - -void e2d::EMsgManager::delMouseListeners(const EString & name) -{ - // 删除鼠标消息监听器 - EVector::iterator mIter; - for (mIter = s_vMouseListeners.begin(); mIter != s_vMouseListeners.end();) - { - if ((*mIter)->getName() == name) - { - SafeRelease(&(*mIter)); - mIter = s_vMouseListeners.erase(mIter); - } - else - { - mIter++; - } - } -} - -void e2d::EMsgManager::startKeyboardListeners(const EString & name) -{ - // 启动按键消息监听器 - for (auto l : s_vKeyboardListeners) - { - if (l->getName() == name) - { - l->start(); - } - } -} - -void e2d::EMsgManager::stopKeyboardListeners(const EString & name) -{ - // 停止按键消息监听器 - for (auto l : s_vKeyboardListeners) - { - if (l->getName() == name) - { - l->stop(); - } - } -} - -void e2d::EMsgManager::delKeyboardListeners(const EString & name) -{ - // 删除按键消息监听器 - EVector::iterator kIter; - for (kIter = s_vKeyboardListeners.begin(); kIter != s_vKeyboardListeners.end();) - { - if ((*kIter)->getName() == name) - { - SafeRelease(&(*kIter)); - kIter = s_vKeyboardListeners.erase(kIter); - } - else - { - kIter++; - } - } -} - -void e2d::EMsgManager::startAllMouseListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentScene() == pParentScene) - { - l->start(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::startAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::stopAllMouseListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentScene() == pParentScene) - { - l->stop(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::stopAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::startAllMouseListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentNode() == pParentNode) - { - l->start(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::startAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::stopAllMouseListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentNode() == pParentNode) - { - l->stop(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::stopAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::startAllKeyboardListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentScene() == pParentScene) - { - l->start(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::startAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::stopAllKeyboardListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentScene() == pParentScene) - { - l->stop(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::stopAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::startAllKeyboardListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentNode() == pParentNode) - { - l->start(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::startAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::stopAllKeyboardListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentNode() == pParentNode) - { - l->stop(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::stopAllKeyboardListenersBindedWith(child); - } -} - -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); - s_vMouseListeners.erase(s_vMouseListeners.begin() + i); - } - else - { - i++; - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::clearAllMouseListenersBindedWith(child); - } -} - -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); - s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); - } - else - { - i++; - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::clearAllKeyboardListenersBindedWith(child); - } -} - -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); - s_vMouseListeners.erase(s_vMouseListeners.begin() + i); - } - else - { - i++; - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::clearAllMouseListenersBindedWith(child); - } -} - -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); - s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); - } - else - { - i++; - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::clearAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_waitAllMouseListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentScene() == pParentScene) - { - l->_wait(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::_waitAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_notifyAllMouseListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentScene() == pParentScene) - { - l->_notify(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::_notifyAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_waitAllMouseListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentNode() == pParentNode) - { - l->_wait(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::_waitAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_notifyAllMouseListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vMouseListeners) - { - if (l->getParentNode() == pParentNode) - { - l->_notify(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::_notifyAllMouseListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_waitAllKeyboardListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentScene() == pParentScene) - { - l->_wait(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::_waitAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_notifyAllKeyboardListenersBindedWith(EScene * pParentScene) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentScene() == pParentScene) - { - l->_notify(); - } - } - for (auto child : pParentScene->getChildren()) - { - EMsgManager::_notifyAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_waitAllKeyboardListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentNode() == pParentNode) - { - l->_wait(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::_waitAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::_notifyAllKeyboardListenersBindedWith(ENode * pParentNode) -{ - for (auto l : s_vKeyboardListeners) - { - if (l->getParentNode() == pParentNode) - { - l->_notify(); - } - } - for (auto child : pParentNode->getChildren()) - { - EMsgManager::_notifyAllKeyboardListenersBindedWith(child); - } -} - -void e2d::EMsgManager::startAllMouseListeners() -{ - EMsgManager::startAllMouseListenersBindedWith(EApp::getCurrentScene()); -} - -void e2d::EMsgManager::stopAllMouseListeners() -{ - EMsgManager::stopAllMouseListenersBindedWith(EApp::getCurrentScene()); -} - -void e2d::EMsgManager::clearAllMouseListeners() -{ - EMsgManager::clearAllMouseListenersBindedWith(EApp::getCurrentScene()); -} - -void e2d::EMsgManager::startAllKeyboardListeners() -{ - EMsgManager::startAllKeyboardListenersBindedWith(EApp::getCurrentScene()); -} - -void e2d::EMsgManager::stopAllKeyboardListeners() -{ - EMsgManager::stopAllKeyboardListenersBindedWith(EApp::getCurrentScene()); -} - -void e2d::EMsgManager::clearAllKeyboardListeners() -{ - EMsgManager::clearAllKeyboardListenersBindedWith(EApp::getCurrentScene()); +#include "..\emsg.h" +#include "..\enodes.h" +#include "..\Win\winbase.h" + + +// 鼠标消息 +e2d::EMouseMsg s_MouseMsg; +// 按键消息 +e2d::EKeyboardMsg s_KeyboardMsg; +// 鼠标消息监听器 +e2d::EVector s_vMouseListeners; +// 按键消息监听器 +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) + { + if (mlistener->isRunning()) + { + if (mlistener->getParentScene() == EApp::getCurrentScene() || + (mlistener->getParentNode() && mlistener->getParentNode()->getParentScene() == EApp::getCurrentScene())) + { + mlistener->_callOn(); + } + } + } +} + +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) + { + if (klistener->isRunning()) + { + if (klistener->getParentScene() == EApp::getCurrentScene() || + (klistener->getParentNode() && klistener->getParentNode()->getParentScene() == EApp::getCurrentScene())) + { + klistener->_callOn(); + } + } + } +} + + +DWORD e2d::EMouseMsg::getPosX() +{ + return LOWORD(s_MouseMsg.m_lParam); +} + +DWORD e2d::EMouseMsg::getPosY() +{ + return HIWORD(s_MouseMsg.m_lParam); +} + +e2d::EPoint e2d::EMouseMsg::getPos() +{ + return EPoint(LOWORD(s_MouseMsg.m_lParam), HIWORD(s_MouseMsg.m_lParam)); +} + +bool e2d::EMouseMsg::isLButtonDown() +{ + return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_LBUTTON; +} + +bool e2d::EMouseMsg::isMButtonDown() +{ + return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_MBUTTON; +} + +bool e2d::EMouseMsg::isRButtonDown() +{ + return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_RBUTTON; +} + +bool e2d::EMouseMsg::isShiftDown() +{ + return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_SHIFT; +} + +bool e2d::EMouseMsg::isCtrlDown() +{ + return GET_KEYSTATE_WPARAM(s_MouseMsg.m_wParam) == MK_CONTROL; +} + +DWORD e2d::EMouseMsg::getWheelDelta() +{ + return GET_WHEEL_DELTA_WPARAM(s_MouseMsg.m_wParam); +} + +e2d::EMouseMsg::MOUSE_MSG e2d::EMouseMsg::getMsg() +{ + return MOUSE_MSG(s_MouseMsg.m_nMsg); +} + + + +e2d::EKeyboardMsg::KEYBOARD_MSG e2d::EKeyboardMsg::getMsg() +{ + return KEYBOARD_MSG(s_KeyboardMsg.m_nMsg); +} + +e2d::EKeyboardMsg::KEY e2d::EKeyboardMsg::getVal() +{ + return KEY(s_KeyboardMsg.m_wParam); +} + +DWORD e2d::EKeyboardMsg::getCount() +{ + return (((DWORD)s_KeyboardMsg.m_lParam) & 0x0000FFFF); +} + +bool e2d::EKeyboardMsg::isKeyDown(KEY key) +{ + if (::GetAsyncKeyState((int)key) & 0x8000) + { + return true; + } + return false; +} + +bool e2d::EKeyboardMsg::isCapitalLockOn() +{ + if (::GetKeyState(VK_CAPITAL) & 0x0001) + { + return true; + } + return false; +} + +bool e2d::EKeyboardMsg::isNumpadLockOn() +{ + if (::GetKeyState(VK_NUMLOCK) & 0x0001) + { + return true; + } + return false; +} + +bool e2d::EKeyboardMsg::isScrollLockOn() +{ + if (::GetKeyState(VK_SCROLL) & 0x0001) + { + return true; + } + return false; +} + +void e2d::EMsgManager::bindListener(e2d::EMouseListener * listener, EScene * pParentScene) +{ + ASSERT( + (!listener->m_pParentNode) && (!listener->m_pParentScene), + "The listener is already binded, it cannot bind again!" + ); + WARN_IF(listener == nullptr, "EMouseListener NULL pointer exception!"); + WARN_IF(pParentScene == nullptr, "Bind EMouseListener with a NULL EScene pointer!"); + + if (listener && pParentScene) + { + listener->start(); + listener->retain(); + listener->m_pParentScene = pParentScene; + s_vMouseListeners.push_back(listener); + } +} + +void e2d::EMsgManager::bindListener(EKeyboardListener * listener, EScene * pParentScene) +{ + ASSERT( + (!listener->m_pParentNode) && (!listener->m_pParentScene), + "The listener is already binded, it cannot bind again!" + ); + WARN_IF(listener == nullptr, "EKeyboardListener NULL pointer exception!"); + WARN_IF(pParentScene == nullptr, "Bind EKeyboardListener with a NULL EScene pointer!"); + + if (listener && pParentScene) + { + listener->start(); + listener->retain(); + listener->m_pParentScene = pParentScene; + s_vKeyboardListeners.push_back(listener); + } +} + +void e2d::EMsgManager::bindListener(EMouseListener * listener, ENode * pParentNode) +{ + ASSERT( + (!listener->m_pParentNode) && (!listener->m_pParentScene), + "The listener is already binded, it cannot bind again!" + ); + WARN_IF(listener == nullptr, "EMouseListener NULL pointer exception!"); + WARN_IF(pParentNode == nullptr, "Bind EMouseListener with a NULL ENode pointer!"); + + if (listener && pParentNode) + { + listener->start(); + listener->retain(); + listener->m_pParentNode = pParentNode; + s_vMouseListeners.push_back(listener); + } +} + +void e2d::EMsgManager::bindListener(EKeyboardListener * listener, ENode * pParentNode) +{ + ASSERT( + (!listener->m_pParentNode) && (!listener->m_pParentScene), + "The listener is already binded, it cannot bind again!" + ); + WARN_IF(listener == nullptr, "EKeyboardListener NULL pointer exception!"); + WARN_IF(pParentNode == nullptr, "Bind EKeyboardListener with a NULL ENode pointer!"); + + if (listener && pParentNode) + { + listener->start(); + listener->retain(); + listener->m_pParentNode = pParentNode; + s_vKeyboardListeners.push_back(listener); + } +} + +void e2d::EMsgManager::startMouseListeners(const EString & name) +{ + for (auto l : s_vMouseListeners) + { + if (l->getName() == name) + { + l->start(); + } + } +} + +void e2d::EMsgManager::stopMouseListeners(const EString & name) +{ + for (auto l : s_vMouseListeners) + { + if (l->getName() == name) + { + l->stop(); + } + } +} + +void e2d::EMsgManager::delMouseListeners(const EString & name) +{ + // 删除鼠标消息监听器 + EVector::iterator mIter; + for (mIter = s_vMouseListeners.begin(); mIter != s_vMouseListeners.end();) + { + if ((*mIter)->getName() == name) + { + SafeRelease(&(*mIter)); + mIter = s_vMouseListeners.erase(mIter); + } + else + { + mIter++; + } + } +} + +void e2d::EMsgManager::startKeyboardListeners(const EString & name) +{ + // 启动按键消息监听器 + for (auto l : s_vKeyboardListeners) + { + if (l->getName() == name) + { + l->start(); + } + } +} + +void e2d::EMsgManager::stopKeyboardListeners(const EString & name) +{ + // 停止按键消息监听器 + for (auto l : s_vKeyboardListeners) + { + if (l->getName() == name) + { + l->stop(); + } + } +} + +void e2d::EMsgManager::delKeyboardListeners(const EString & name) +{ + // 删除按键消息监听器 + EVector::iterator kIter; + for (kIter = s_vKeyboardListeners.begin(); kIter != s_vKeyboardListeners.end();) + { + if ((*kIter)->getName() == name) + { + SafeRelease(&(*kIter)); + kIter = s_vKeyboardListeners.erase(kIter); + } + else + { + kIter++; + } + } +} + +void e2d::EMsgManager::startAllMouseListenersBindedWith(EScene * pParentScene) +{ + for (auto l : s_vMouseListeners) + { + if (l->getParentScene() == pParentScene) + { + l->start(); + } + } + for (auto child : pParentScene->getChildren()) + { + EMsgManager::startAllMouseListenersBindedWith(child); + } +} + +void e2d::EMsgManager::stopAllMouseListenersBindedWith(EScene * pParentScene) +{ + for (auto l : s_vMouseListeners) + { + if (l->getParentScene() == pParentScene) + { + l->stop(); + } + } + for (auto child : pParentScene->getChildren()) + { + EMsgManager::stopAllMouseListenersBindedWith(child); + } +} + +void e2d::EMsgManager::startAllMouseListenersBindedWith(ENode * pParentNode) +{ + for (auto l : s_vMouseListeners) + { + if (l->getParentNode() == pParentNode) + { + l->start(); + } + } + for (auto child : pParentNode->getChildren()) + { + EMsgManager::startAllMouseListenersBindedWith(child); + } +} + +void e2d::EMsgManager::stopAllMouseListenersBindedWith(ENode * pParentNode) +{ + for (auto l : s_vMouseListeners) + { + if (l->getParentNode() == pParentNode) + { + l->stop(); + } + } + for (auto child : pParentNode->getChildren()) + { + EMsgManager::stopAllMouseListenersBindedWith(child); + } +} + +void e2d::EMsgManager::startAllKeyboardListenersBindedWith(EScene * pParentScene) +{ + for (auto l : s_vKeyboardListeners) + { + if (l->getParentScene() == pParentScene) + { + l->start(); + } + } + for (auto child : pParentScene->getChildren()) + { + EMsgManager::startAllKeyboardListenersBindedWith(child); + } +} + +void e2d::EMsgManager::stopAllKeyboardListenersBindedWith(EScene * pParentScene) +{ + for (auto l : s_vKeyboardListeners) + { + if (l->getParentScene() == pParentScene) + { + l->stop(); + } + } + for (auto child : pParentScene->getChildren()) + { + EMsgManager::stopAllKeyboardListenersBindedWith(child); + } +} + +void e2d::EMsgManager::startAllKeyboardListenersBindedWith(ENode * pParentNode) +{ + for (auto l : s_vKeyboardListeners) + { + if (l->getParentNode() == pParentNode) + { + l->start(); + } + } + for (auto child : pParentNode->getChildren()) + { + EMsgManager::startAllKeyboardListenersBindedWith(child); + } +} + +void e2d::EMsgManager::stopAllKeyboardListenersBindedWith(ENode * pParentNode) +{ + for (auto l : s_vKeyboardListeners) + { + if (l->getParentNode() == pParentNode) + { + l->stop(); + } + } + for (auto child : pParentNode->getChildren()) + { + EMsgManager::stopAllKeyboardListenersBindedWith(child); + } +} + +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); + s_vMouseListeners.erase(s_vMouseListeners.begin() + i); + } + else + { + i++; + } + } + for (auto child : pParentScene->getChildren()) + { + EMsgManager::clearAllMouseListenersBindedWith(child); + } +} + +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); + s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); + } + else + { + i++; + } + } + for (auto child : pParentScene->getChildren()) + { + EMsgManager::clearAllKeyboardListenersBindedWith(child); + } +} + +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); + s_vMouseListeners.erase(s_vMouseListeners.begin() + i); + } + else + { + i++; + } + } + for (auto child : pParentNode->getChildren()) + { + EMsgManager::clearAllMouseListenersBindedWith(child); + } +} + +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); + s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i); + } + else + { + i++; + } + } + for (auto child : pParentNode->getChildren()) + { + EMsgManager::clearAllKeyboardListenersBindedWith(child); + } +} + +void e2d::EMsgManager::_clearManager() +{ + s_vMouseListeners.clear(); + s_vKeyboardListeners.clear(); +} + +void e2d::EMsgManager::startAllMouseListeners() +{ + EMsgManager::startAllMouseListenersBindedWith(EApp::getCurrentScene()); +} + +void e2d::EMsgManager::stopAllMouseListeners() +{ + EMsgManager::stopAllMouseListenersBindedWith(EApp::getCurrentScene()); +} + +void e2d::EMsgManager::clearAllMouseListeners() +{ + EMsgManager::clearAllMouseListenersBindedWith(EApp::getCurrentScene()); +} + +void e2d::EMsgManager::startAllKeyboardListeners() +{ + EMsgManager::startAllKeyboardListenersBindedWith(EApp::getCurrentScene()); +} + +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/Tool/EObjectManager.cpp b/Easy2D/Manager/EObjectManager.cpp similarity index 96% rename from Easy2D/Tool/EObjectManager.cpp rename to Easy2D/Manager/EObjectManager.cpp index 6f113d0f..9414e5f7 100644 --- a/Easy2D/Tool/EObjectManager.cpp +++ b/Easy2D/Manager/EObjectManager.cpp @@ -47,9 +47,9 @@ void e2d::EObjectManager::add(e2d::EObject * nptr) void e2d::EObjectManager::clearAllObjects() { - for (auto o : s_vPool) + for (const auto &obj : s_vPool) { - delete o; + delete obj; } s_vPool.clear(); } diff --git a/Easy2D/Tool/ETimerManager.cpp b/Easy2D/Manager/ETimerManager.cpp similarity index 78% rename from Easy2D/Tool/ETimerManager.cpp rename to Easy2D/Manager/ETimerManager.cpp index 2c5ab30f..109e8086 100644 --- a/Easy2D/Tool/ETimerManager.cpp +++ b/Easy2D/Manager/ETimerManager.cpp @@ -181,55 +181,16 @@ void e2d::ETimerManager::clearAllTimersBindedWith(ENode * pParentNode) } } -void e2d::ETimerManager::_notifyAllTimersBindedWith(EScene * pParentScene) +void e2d::ETimerManager::_clearManager() { - for (auto t : s_vTimers) - { - if (t->getParentScene() == pParentScene) - t->_notify(); - } - for (auto child : pParentScene->getChildren()) - { - _notifyAllTimersBindedWith(child); - } + s_vTimers.clear(); } -void e2d::ETimerManager::_waitAllTimersBindedWith(EScene * pParentScene) +void e2d::ETimerManager::_resetAllTimers() { - for (auto t : s_vTimers) + for (const auto & t : s_vTimers) { - if (t->getParentScene() == pParentScene) - t->_wait(); - } - for (auto child : pParentScene->getChildren()) - { - _waitAllTimersBindedWith(child); - } -} - -void e2d::ETimerManager::_notifyAllTimersBindedWith(ENode * pParentNode) -{ - for (auto t : s_vTimers) - { - if (t->getParentNode() == pParentNode) - t->_notify(); - } - for (auto child : pParentNode->getChildren()) - { - _notifyAllTimersBindedWith(child); - } -} - -void e2d::ETimerManager::_waitAllTimersBindedWith(ENode * pParentNode) -{ - for (auto t : s_vTimers) - { - if (t->getParentNode() == pParentNode) - t->_notify(); - } - for (auto child : pParentNode->getChildren()) - { - _waitAllTimersBindedWith(child); + t->m_tLast = GetNow(); } } @@ -250,14 +211,21 @@ void e2d::ETimerManager::clearAllTimers() void e2d::ETimerManager::TimerProc() { + if (EApp::isPaused()) + return; + for (auto t : s_vTimers) { if (t->isRunning()) { - if (GetInterval(t->m_tLast) >= t->m_nInterval) + if (t->getParentScene() == EApp::getCurrentScene() || + (t->getParentNode() && t->getParentNode()->getParentScene() == EApp::getCurrentScene())) { - t->_callOn(); - t->m_tLast = GetNow(); + if (GetInterval(t->m_tLast) >= t->m_nInterval) + { + t->_callOn(); + t->m_tLast = GetNow(); + } } } } diff --git a/Easy2D/Node/ENode.cpp b/Easy2D/Node/ENode.cpp index 1b68da43..50513be3 100644 --- a/Easy2D/Node/ENode.cpp +++ b/Easy2D/Node/ENode.cpp @@ -106,11 +106,6 @@ void e2d::ENode::_onEnter() if (!this->m_bDisplayedInScene && this->isVisiable()) { this->m_bDisplayedInScene = true; - - ETimerManager::_notifyAllTimersBindedWith(this); - EMsgManager::_notifyAllMouseListenersBindedWith(this); - EMsgManager::_notifyAllKeyboardListenersBindedWith(this); - EActionManager::_notifyAllActionsBindedWith(this); this->onEnter(); for (const auto &child : m_vChildren) @@ -125,11 +120,6 @@ void e2d::ENode::_onExit() if (this->m_bDisplayedInScene) { this->m_bDisplayedInScene = false; - - ETimerManager::_waitAllTimersBindedWith(this); - EMsgManager::_waitAllMouseListenersBindedWith(this); - EMsgManager::_waitAllKeyboardListenersBindedWith(this); - EActionManager::_waitAllActionsBindedWith(this); this->onExit(); for (const auto &child : m_vChildren) @@ -462,18 +452,6 @@ void e2d::ENode::setAnchor(float anchorX, float anchorY) m_bTransformChildrenNeeded = true; } -void e2d::ENode::setParent(ENode * parent) -{ - if (m_pParent) - { - m_pParent->addChild(this); - } - else - { - removeFromParent(); - } -} - void e2d::ENode::addChild(ENode * child, int order /* = 0 */) { WARN_IF(child == nullptr, "ENode::addChild NULL pointer exception."); @@ -639,7 +617,12 @@ void e2d::ENode::clearAllChildren(bool release /* = true */) void e2d::ENode::runAction(EAction * action) { - EActionManager::bindAction(action, this); + ASSERT( + (!action->getTarget()), + "The action is already running, it cannot running again!" + ); + action->setTarget(this); + EActionManager::addAction(action); } void e2d::ENode::resumeAction(EAction * action) diff --git a/Easy2D/Node/ESprite.cpp b/Easy2D/Node/ESprite.cpp index ad9747af..aa877370 100644 --- a/Easy2D/Node/ESprite.cpp +++ b/Easy2D/Node/ESprite.cpp @@ -3,8 +3,8 @@ e2d::ESprite::ESprite() - : m_fSourcePosX(0) - , m_fSourcePosY(0) + : m_fSourceClipX(0) + , m_fSourceClipY(0) , m_pTexture(nullptr) { } @@ -44,7 +44,7 @@ void e2d::ESprite::setTexture(ETexture * texture) m_pTexture = texture; m_pTexture->retain(); - m_fSourcePosX = m_fSourcePosY = 0; + m_fSourceClipX = m_fSourceClipY = 0; ENode::_setWidth(m_pTexture->getSourceWidth()); ENode::_setHeight(m_pTexture->getSourceHeight()); } @@ -55,12 +55,18 @@ void e2d::ESprite::setTexture(ETexture * texture, float x, float y, float width, clipTexture(x, y, width, height); } +void e2d::ESprite::loadFromSpriteFrame(ESpriteFrame * frame) +{ + setTexture(frame->m_pTexture); + clipTexture(frame->m_fSourceClipX, frame->m_fSourceClipY, frame->m_fSourceClipWidth, frame->m_fSourceClipHeight); +} + void e2d::ESprite::clipTexture(float x, float y, float width, float height) { - m_fSourcePosX = max(x, 0); - m_fSourcePosY = max(y, 0); - ENode::_setWidth(min(max(width, 0), m_pTexture->getSourceWidth() - m_fSourcePosX)); - ENode::_setHeight(min(max(height, 0), m_pTexture->getSourceHeight() - m_fSourcePosX)); + 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)); } void e2d::ESprite::_onRender() @@ -73,7 +79,12 @@ void e2d::ESprite::_onRender() D2D1::RectF(0, 0, getRealWidth(), getRealHeight()), m_fDisplayOpacity, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, - D2D1::RectF(m_fSourcePosX, m_fSourcePosY, getRealWidth(), getRealHeight()) + D2D1::RectF( + m_fSourceClipX, + m_fSourceClipY, + m_fSourceClipX + getRealWidth(), + m_fSourceClipY + getRealHeight() + ) ); } } diff --git a/Easy2D/Node/ESpriteFrame.cpp b/Easy2D/Node/ESpriteFrame.cpp index 6de60dab..77bb45ee 100644 --- a/Easy2D/Node/ESpriteFrame.cpp +++ b/Easy2D/Node/ESpriteFrame.cpp @@ -1 +1,85 @@ -#include "..\enodes.h" \ No newline at end of file +#include "..\enodes.h" + +e2d::ESpriteFrame::ESpriteFrame() + : m_fSourceClipX(0) + , m_fSourceClipY(0) + , m_fSourceClipWidth(0) + , m_fSourceClipHeight(0) + , m_pTexture(nullptr) +{ +} + +e2d::ESpriteFrame::ESpriteFrame(ETexture * texture) + : ESpriteFrame() +{ + _setTexture(texture); +} + +e2d::ESpriteFrame::ESpriteFrame(const EString & imageFileName) + : ESpriteFrame() +{ + _setTexture(new ETexture(imageFileName)); +} + +e2d::ESpriteFrame::ESpriteFrame(const EString & resourceName, const EString & resourceType) + : ESpriteFrame() +{ + _setTexture(new ETexture(resourceName, resourceType)); +} + +e2d::ESpriteFrame::ESpriteFrame(ETexture * texture, float x, float y, float width, float height) + : ESpriteFrame() +{ + _setTexture(texture); + _clipTexture(x, y, width, height); +} + +e2d::ESpriteFrame::ESpriteFrame(const EString & imageFileName, float x, float y, float width, float height) + : ESpriteFrame() +{ + _setTexture(new ETexture(imageFileName)); + _clipTexture(x, y, width, height); +} + +e2d::ESpriteFrame::ESpriteFrame(const EString & resourceName, const EString & resourceType, float x, float y, float width, float height) + : ESpriteFrame() +{ + _setTexture(new ETexture(resourceName, resourceType)); + _clipTexture(x, y, width, height); +} + +e2d::ESpriteFrame::~ESpriteFrame() +{ + if (m_pTexture) + { + m_pTexture->release(); + } +} + +void e2d::ESpriteFrame::_setTexture(ETexture * texture) +{ + if (texture) + { + if (m_pTexture) + { + m_pTexture->release(); + } + m_pTexture = texture; + m_pTexture->retain(); + m_fSourceClipX = 0; + m_fSourceClipY = 0; + m_fSourceClipWidth = texture->getSourceWidth(); + m_fSourceClipHeight = texture->getSourceHeight(); + } +} + +void e2d::ESpriteFrame::_clipTexture(float x, float y, float width, float height) +{ + if (m_pTexture) + { + m_fSourceClipX = min(max(x, 0), m_pTexture->getSourceWidth()); + m_fSourceClipY = min(max(y, 0), m_pTexture->getSourceHeight()); + m_fSourceClipWidth = min(max(width, 0), m_pTexture->getSourceWidth() - m_fSourceClipX); + m_fSourceClipHeight = min(max(height, 0), m_pTexture->getSourceHeight() - m_fSourceClipY); + } +} diff --git a/Easy2D/Node/ETexture.cpp b/Easy2D/Node/ETexture.cpp index 5f91721a..b4836bfb 100644 --- a/Easy2D/Node/ETexture.cpp +++ b/Easy2D/Node/ETexture.cpp @@ -42,7 +42,6 @@ e2d::ETexture::ETexture(const EString & resourceName, const EString & resourceTy e2d::ETexture::~ETexture() { - SafeReleaseInterface(&m_pBitmap); } void e2d::ETexture::loadFromFile(const EString & fileName) @@ -52,8 +51,6 @@ void e2d::ETexture::loadFromFile(const EString & fileName) if (fileName.empty()) return; - SafeReleaseInterface(&m_pBitmap); - if (!e2d::ETexture::preload(fileName)) { WARN_IF(true, "Load ETexture from file failed!"); @@ -73,8 +70,6 @@ void e2d::ETexture::loadFromResource(const EString & resourceName, const EString if (resourceName.empty() || resourceType.empty()) return; - SafeReleaseInterface(&m_pBitmap); - if (!e2d::ETexture::preload(resourceName, resourceType)) { WARN_IF(true, "Load ETexture from resource failed!"); diff --git a/Easy2D/Tool/EMusicUtils.cpp b/Easy2D/Tool/EMusicUtils.cpp new file mode 100644 index 00000000..11746935 --- /dev/null +++ b/Easy2D/Tool/EMusicUtils.cpp @@ -0,0 +1,6 @@ +#include "..\etools.h" + + +void e2d::EMusicUtils::play(LPCTSTR musicFileName, bool loop) +{ +} \ No newline at end of file diff --git a/Easy2D/Transition/ETransitionFade.cpp b/Easy2D/Transition/ETransitionFade.cpp new file mode 100644 index 00000000..ef210534 --- /dev/null +++ b/Easy2D/Transition/ETransitionFade.cpp @@ -0,0 +1,36 @@ +#include "..\etransitions.h" +#include "..\eactions.h" + +e2d::ETransitionFade::ETransitionFade(float fadeOutDuration, float fadeInDuration) + : m_fFadeOutDuration(fadeOutDuration) + , m_fFadeInDuration(fadeInDuration) +{ +} + +void e2d::ETransitionFade::_setTarget(EScene * prev, EScene * next, bool & enterNextScene, bool & transitional) +{ + // 第一个场景淡出 + 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 action4 = new EActionCallback([&] { + transitional = false; + }); + + // 添加顺序动作 + EActionManager::addAction(new EActionSequence(4, action1, action2, action3, action4)); +} \ No newline at end of file diff --git a/Easy2D/Win/winbase.cpp b/Easy2D/Win/winbase.cpp index 9a36412e..c54a2ce8 100644 --- a/Easy2D/Win/winbase.cpp +++ b/Easy2D/Win/winbase.cpp @@ -49,7 +49,7 @@ ID2D1HwndRenderTarget * &GetRenderTarget() // Create a Direct2D render target. HRESULT hr; - hr = s_pDirect2dFactory->CreateHwndRenderTarget( + hr = GetFactory()->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(s_HWnd, size), &s_pRenderTarget @@ -79,7 +79,12 @@ ID2D1SolidColorBrush * &GetSolidColorBrush() { if (!s_pSolidBrush) { - s_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &s_pSolidBrush); + HRESULT hr; + hr = GetRenderTarget()->CreateSolidColorBrush( + D2D1::ColorF(D2D1::ColorF::White), + &s_pSolidBrush + ); + ASSERT(SUCCEEDED(hr), "Create Solid Color Brush Failed!"); } return s_pSolidBrush; } diff --git a/Easy2D/eactions.h b/Easy2D/eactions.h index 0538722a..a8d96ff2 100644 --- a/Easy2D/eactions.h +++ b/Easy2D/eactions.h @@ -9,6 +9,7 @@ class EActionTwo; class EActionLoop; class EActionSequence; class EActionTwoAtSameTime; +class ETransitionFade; class EAction : public EObject @@ -45,13 +46,18 @@ public: // 获取一个新的逆向动作 virtual EAction * reverse() const; + // 获取执行该动作的目标 + virtual ENode * getTarget(); + // 设置动作每一帧的时间间隔 virtual void setInterval( LONGLONG milliSeconds ); - // 获取执行该动作的目标 - virtual ENode * getTarget(); + // 设置动作执行目标 + virtual void setTarget( + ENode * node + ); protected: // 初始化动作 @@ -66,30 +72,23 @@ protected: // 重置动作 virtual void _reset(); - // 进入等待状态 - virtual void _wait(); - - // 唤醒 - virtual void _notify(); - protected: bool m_bRunning; - bool m_bWaiting; bool m_bEnding; bool m_bInit; ENode * m_pTarget; EScene * m_pParentScene; LONGLONG m_nAnimationInterval; - std::chrono::steady_clock::time_point m_nLast; + std::chrono::steady_clock::time_point m_tLast; }; -class EAnimation : +class EActionGradual : public EAction { public: // 创建时长动画 - EAnimation( + EActionGradual( float duration ); @@ -113,7 +112,7 @@ protected: class EActionMoveBy : - public EAnimation + public EActionGradual { public: // 创建相对位移动画 @@ -170,7 +169,7 @@ protected: class EActionScaleBy : - public EAnimation + public EActionGradual { public: // 创建相对缩放动画 @@ -232,7 +231,7 @@ protected: class EActionOpacityBy : - public EAnimation + public EActionGradual { public: // 创建透明度相对渐变动画 @@ -311,7 +310,7 @@ public: class EActionRotateBy : - public EAnimation + public EActionGradual { public: // 创建相对旋转动画 @@ -537,19 +536,19 @@ protected: }; -class EActionFrames : +class EAnimation : public EAction { public: // 创建帧动画 - EActionFrames(); + EAnimation(); // 创建特定帧间隔的帧动画 - EActionFrames( + EAnimation( LONGLONG frameDelay /* 帧间隔(毫秒) */ ); - virtual ~EActionFrames(); + virtual ~EAnimation(); // 添加帧 void addFrame( @@ -557,10 +556,10 @@ public: ); // 获取该动画的拷贝对象 - virtual EActionFrames * clone() const override; + virtual EAnimation * clone() const override; // 获取该动画的逆动画 - virtual EActionFrames * reverse() const override; + virtual EAnimation * reverse() const override; protected: // 初始化动作 diff --git a/Easy2D/easy2d.h b/Easy2D/easy2d.h index 6c8486ae..76c3a9de 100644 --- a/Easy2D/easy2d.h +++ b/Easy2D/easy2d.h @@ -23,6 +23,7 @@ #include "emsg.h" #include "etools.h" #include "eactions.h" +#include "etransitions.h" #if defined(DEBUG) || defined(_DEBUG) diff --git a/Easy2D/ebase.h b/Easy2D/ebase.h index 11ad3fb9..95e544dd 100644 --- a/Easy2D/ebase.h +++ b/Easy2D/ebase.h @@ -13,6 +13,7 @@ class ENode; class EObjectManager; class EMouseListener; class EKeyboardListener; +class ETransition; class EApp { @@ -21,6 +22,13 @@ public: virtual ~EApp(); + enum WINDOW_STYLE + { + NO_CLOSE = 1, /* 禁用关闭按钮 */ + NO_MINI_SIZE = 2, /* 禁用最小化按钮 */ + TOP_MOST = 4 /* 窗口置顶 */ + }; + // 初始化游戏界面 bool init( const EString &title, /* 窗口标题 */ @@ -41,13 +49,8 @@ public: // 启动程序 void run(); - // 预设画面帧数 - void setFPS( - UINT32 fps - ); - // 重写这个函数,它将在窗口激活时执行 - virtual void onActivate(); + virtual bool onActivate(); // 重写这个函数,它将在窗口非激活时执行 virtual bool onInactive(); @@ -55,27 +58,58 @@ public: // 重写这个函数,它将在关闭窗口时执行 virtual bool onCloseWindow(); - // 释放所有内存资源 - void free(); - // 获取程序实例 static EApp * get(); - // 显示或隐藏控制台(默认隐藏) + // 暂停游戏 + static void pause(); + + // 继续游戏 + static void resume(); + + // 获取游戏是否暂停 + static bool isPaused(); + + // 切换场景 + static void enterScene( + EScene * scene, /* 下一个场景的指针 */ + bool saveCurrentScene = true /* 是否保存当前场景 */ + ); + + // 切换场景 + static void enterScene( + EScene * scene, /* 下一个场景的指针 */ + ETransition * transition, /* 场景切换动画 */ + bool saveCurrentScene = true /* 是否保存当前场景 */ + ); + + // 返回上一场景 + static void backScene(); + + // 返回上一场景 + static void backScene( + ETransition * transition /* 场景切换动画 */ + ); + + // 清空保存的所有场景 + static void clearScene(); + + // 隐藏窗口 + static void hideWindow(); + + // 显示窗口 + static void showWindow(); + + // 是否打开控制台 static void showConsole( bool show ); - // 修改窗口大小 - static void setWindowSize( - UINT32 width, - UINT32 height - ); + // 终止程序 + static void quit(); - // 设置窗口标题 - static void setWindowTitle( - const EString &title - ); + // 终止程序 + static void end(); // 获取窗口标题 static EString getTitle(); @@ -86,18 +120,6 @@ public: // 获取窗口高度 static UINT32 getHeight(); - // 切换场景 - static void enterScene( - EScene * scene, /* 下一个场景的指针 */ - bool saveCurrentScene = true /* 是否保存当前场景 */ - ); - - // 返回上一场景 - static void backScene(); - - // 清空保存的所有场景 - static void clearScene(); - // 获取当前场景 static EScene * getCurrentScene(); @@ -110,6 +132,17 @@ public: // 获取 AppName static EString getAppName(); + // 修改窗口大小 + static void setWindowSize( + UINT32 width, + UINT32 height + ); + + // 设置窗口标题 + static void setWindowTitle( + const EString & title + ); + // 设置 AppName static void setAppName( const EString &appname @@ -125,17 +158,10 @@ public: bool value ); - // 隐藏窗口 - static void hideWindow(); - - // 显示窗口 - static void showWindow(); - - // 终止程序 - static void quit(); - - // 终止程序 - static void end(); + // 预设画面帧数 + static void setFPS( + UINT32 fps + ); protected: // 创建设备无关资源 @@ -154,7 +180,7 @@ protected: void _onControl(); // 渲染游戏画面 - bool _onRender(); + void _onRender(); // 进入下一场景 void _enterNextScene(); @@ -165,6 +191,9 @@ protected: UINT32 height ); + // 释放所有内存资源 + void _free(); + // 窗口程序 static LRESULT CALLBACK WndProc( HWND hWnd, @@ -174,19 +203,48 @@ protected: ); protected: - bool m_bRunning; + bool m_bEnd; bool m_bPaused; + bool m_bManualPaused; + bool m_bTransitional; + bool m_bEnterNextScene; + bool m_bTopMost; EString m_sTitle; EString m_sAppName; EColor m_ClearColor; LONGLONG nAnimationInterval; - EScene * m_pCurrentScene; EScene * m_pNextScene; }; -class EScene +class EObject +{ + friend EObjectManager; + +public: + EObject(); + + virtual ~EObject(); + + // 引用计数加一 + void retain(); + + // 引用计数减一 + void release(); + + // 让引擎自动释放这个对象 + void autoRelease(); + +private: + int m_nRefCount; + bool m_bManaged; + bool m_bAutoRelease; +}; + + +class EScene : + public EObject { friend EApp; @@ -202,7 +260,7 @@ public: virtual void onExit(); // 重写这个函数,它将在窗口激活时执行 - virtual void onActivate(); + virtual bool onActivate(); // 重写这个函数,它将在窗口非激活时执行 virtual bool onInactive(); @@ -239,6 +297,9 @@ public: const EString &childName ); + // 获取根节点 + ENode * getRoot() const; + // 清空所有子成员 void clearAllChildren(); @@ -252,41 +313,10 @@ protected: // 渲染场景画面 void _onRender(); - // 进入场景时需调用该函数 - virtual void _onEnter(); - - // 退出场景时需调用该函数 - virtual void _onExit(); - protected: bool m_bSortNeeded; bool m_bWillSave; ENode * m_pRoot; }; - -class EObject -{ - friend EObjectManager; - -public: - EObject(); - - virtual ~EObject(); - - // 引用计数加一 - void retain(); - - // 引用计数减一 - void release(); - - // 让引擎自动释放这个对象 - void autoRelease(); - -private: - int m_nRefCount; - bool m_bManaged; - bool m_bAutoRelease; -}; - } \ No newline at end of file diff --git a/Easy2D/emsg.h b/Easy2D/emsg.h index 688ae077..edd47dff 100644 --- a/Easy2D/emsg.h +++ b/Easy2D/emsg.h @@ -153,9 +153,6 @@ public: // 获取监听器状态 bool isRunning() const; - // 获取监听器挂起状态 - bool isWaiting() const; - // 启动监听 void start(); @@ -187,19 +184,12 @@ public: ) = 0; protected: - // 进入等待状态 - void _wait(); - - // 唤醒 - void _notify(); - // 执行监听器回调函数 virtual void _callOn() = 0; protected: EString m_sName; bool m_bRunning; - bool m_bWaiting; EScene * m_pParentScene; ENode * m_pParentNode; }; @@ -605,46 +595,8 @@ public: static void clearAllKeyboardListeners(); private: - // 挂起绑定在场景上的所有鼠标消息监听器 - static void _waitAllMouseListenersBindedWith( - EScene * pParentScene - ); - - // 重启绑定在场景上的所有鼠标消息监听器 - static void _notifyAllMouseListenersBindedWith( - EScene * pParentScene - ); - - // 挂起绑定在节点上的所有鼠标消息监听器 - static void _waitAllMouseListenersBindedWith( - ENode * pParentNode - ); - - // 重启绑定在节点上的所有鼠标消息监听器 - static void _notifyAllMouseListenersBindedWith( - ENode * pParentNode - ); - - - // 挂起绑定在场景及其子节点上的所有按键监听器 - static void _waitAllKeyboardListenersBindedWith( - EScene * pParentScene - ); - - // 重启绑定在场景及其子节点上的所有按键监听器 - static void _notifyAllKeyboardListenersBindedWith( - EScene * pParentScene - ); - - // 挂起绑定在节点上的所有按键监听器 - static void _waitAllKeyboardListenersBindedWith( - ENode * pParentNode - ); - - // 重启绑定在节点上的所有按键监听器 - static void _notifyAllKeyboardListenersBindedWith( - ENode * pParentNode - ); + // 清除所有监听器 + static void _clearManager(); // 鼠标消息程序 static void MouseProc( diff --git a/Easy2D/enodes.h b/Easy2D/enodes.h index 9e517fb0..2b82173d 100644 --- a/Easy2D/enodes.h +++ b/Easy2D/enodes.h @@ -222,11 +222,6 @@ public: float anchorY ); - // 设置父节点 - virtual void setParent( - ENode* parent - ); - // 添加子节点 virtual void addChild( ENode * child, @@ -422,6 +417,84 @@ protected: }; +class ESpriteFrame : + public EObject +{ + friend ESprite; + +public: + // 创建空的精灵帧 + ESpriteFrame(); + + // 创建空的精灵帧 + ESpriteFrame( + ETexture * texture + ); + + // 创建空的精灵帧 + ESpriteFrame( + const EString & imageFileName + ); + + // 创建空的精灵帧 + ESpriteFrame( + const EString & resourceName, + const EString & resourceType + ); + + // 创建空的精灵帧 + ESpriteFrame( + ETexture * texture, + float x, + float y, + float width, + float height + ); + + // 创建空的精灵帧 + ESpriteFrame( + const EString & imageFileName, + float x, + float y, + float width, + float height + ); + + // 创建空的精灵帧 + ESpriteFrame( + const EString & resourceName, + const EString & resourceType, + float x, + float y, + float width, + float height + ); + + virtual ~ESpriteFrame(); + +protected: + // 获取纹理 + void _setTexture( + ETexture * texture + ); + + // 裁剪纹理 + void _clipTexture( + float x, + float y, + float width, + float height + ); + +protected: + float m_fSourceClipX; + float m_fSourceClipY; + float m_fSourceClipWidth; + float m_fSourceClipHeight; + ETexture * m_pTexture; +}; + + class ESprite : public ENode { @@ -475,6 +548,11 @@ public: float height ); + // 从 ESpriteFrame 加载资源 + void loadFromSpriteFrame( + ESpriteFrame * frame + ); + // 裁剪纹理 void clipTexture( float x, @@ -488,20 +566,12 @@ protected: virtual void _onRender() override; protected: - float m_fSourcePosX; - float m_fSourcePosY; + float m_fSourceClipX; + float m_fSourceClipY; ETexture * m_pTexture; }; -class ESpriteFrame : - public EObject -{ -protected: - ETexture * texture; -}; - - class EFont : public EObject { diff --git a/Easy2D/etools.h b/Easy2D/etools.h index edb18eaf..51eea928 100644 --- a/Easy2D/etools.h +++ b/Easy2D/etools.h @@ -59,9 +59,6 @@ public: // 获取定时器状态 bool isRunning() const; - // 获取定时器挂起状态 - bool isWaiting() const; - // 启动监听 void start(); @@ -98,19 +95,12 @@ public: ); protected: - // 进入等待状态 - void _wait(); - - // 唤醒 - void _notify(); - // 执行回调函数 virtual void _callOn(); protected: EString m_sName; bool m_bRunning; - bool m_bWaiting; int m_nRunTimes; EScene * m_pParentScene; ENode * m_pParentNode; @@ -195,25 +185,11 @@ public: static void clearAllTimers(); private: - // 挂起绑定在场景及其子节点上的所有定时器 - static void _waitAllTimersBindedWith( - EScene * pParentScene - ); + // 清空定时器管理器 + static void _clearManager(); - // 重启绑定在场景及其子节点上的所有定时器 - static void _notifyAllTimersBindedWith( - EScene * pParentScene - ); - - // 挂起绑定在节点上的所有定时器 - static void _waitAllTimersBindedWith( - ENode * pParentNode - ); - - // 重启绑定在节点上的所有定时器 - static void _notifyAllTimersBindedWith( - ENode * pParentNode - ); + // 重置定时器状态 + static void _resetAllTimers(); // 定时器执行程序 static void TimerProc(); @@ -228,10 +204,9 @@ class EActionManager friend ENode; public: - // 绑定动作到节点 - static void bindAction( - EAction * action, - ENode * pTargetNode + // 添加动作 + static void addAction( + EAction * action ); // 启动绑定在场景子节点上的所有动作 @@ -274,31 +249,25 @@ public: static void clearAllActions(); private: - // 挂起绑定在场景子节点上的所有动作 - static void _waitAllActionsBindedWith( - EScene * pParentScene - ); + // 清空动画管理器 + static void _clearManager(); - // 重启绑定在场景子节点上的所有动作 - static void _notifyAllActionsBindedWith( - EScene * pParentScene - ); - - // 挂起绑定在节点上的所有动作 - static void _waitAllActionsBindedWith( - ENode * pTargetNode - ); - - // 重启绑定在节点上的所有动作 - static void _notifyAllActionsBindedWith( - ENode * pTargetNode - ); + // 重置所有动作状态 + static void _resetAllActions(); // 动作执行程序 static void ActionProc(); }; +class EMusicUtils +{ +public: + // 播放音效 + static void play(LPCTSTR musicFileName, bool loop = false); +}; + + class EFileUtils { public: diff --git a/Easy2D/etransitions.h b/Easy2D/etransitions.h new file mode 100644 index 00000000..5f6066cd --- /dev/null +++ b/Easy2D/etransitions.h @@ -0,0 +1,49 @@ +#pragma once +#include "ebase.h" + +namespace e2d +{ + +class ETransition : + public EObject +{ + friend EApp; +public: + ETransition() {} + +protected: + // 保存当前场景和下一场景的指针,和控制场景切换的变量 + virtual void _setTarget( + EScene * prev, + EScene * next, + bool &enterNextScene, + bool &transitional + ) = 0; +}; + + +class ETransitionFade : + public ETransition +{ +public: + // 创建淡入淡出式的场景切换动画 + ETransitionFade( + float fadeOutDuration, /* 前一场景淡出动画持续时长 */ + float fadeInDuration /* 后一场景淡入动画持续时长 */ + ); + +protected: + // 保存当前场景和下一场景的指针,和控制场景切换的变量 + virtual void _setTarget( + EScene * prev, + EScene * next, + bool &enterNextScene, + bool &transitional + ) override; + +protected: + float m_fFadeOutDuration; + float m_fFadeInDuration; +}; + +} \ No newline at end of file