修复了若干BUG

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,6 +12,45 @@ typedef std::wstring EString;
template<typename T>
using EVector = std::vector<T>;
struct EWindowStyle
{
EWindowStyle()
{
ICON_ID = 0;
NO_CLOSE = false;
NO_MINI_SIZE = false;
TOP_MOST = false;
}
EWindowStyle(
LPCTSTR ICON_ID
)
{
this->ICON_ID = ICON_ID;
NO_CLOSE = false;
NO_MINI_SIZE = false;
TOP_MOST = false;
}
EWindowStyle(
LPCTSTR ICON_ID,
bool NO_CLOSE,
bool NO_MINI_SIZE,
bool TOP_MOST
)
{
this->ICON_ID = ICON_ID;
this->NO_CLOSE = NO_CLOSE;
this->NO_MINI_SIZE = NO_MINI_SIZE;
this->TOP_MOST = TOP_MOST;
}
LPCTSTR ICON_ID; /* 程序图标 ID */
bool NO_CLOSE; /* 禁用关闭按钮 */
bool NO_MINI_SIZE; /* 禁用最小化按钮 */
bool TOP_MOST; /* 窗口置顶 */
};
struct EPoint
{
EPoint()
@ -71,14 +110,22 @@ struct ESize
};
typedef std::function<void()> KEY_LISTENER_CALLBACK;
typedef std::function<void()> MOUSE_LISTENER_CALLBACK;
typedef std::function<void(EPoint mousePos)> MOUSE_CLICK_LISTENER_CALLBACK;
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_PRESS_LISTENER_CALLBACK;
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_DBLCLK_LISTENER_CALLBACK;
typedef std::function<void(EPoint begin, EPoint end)> MOUSE_DRAG_LISTENER_CALLBACK;
// 定时器回调函数(参数为该定时器被调用的次数,从 0 开始)
typedef std::function<void(int)> TIMER_CALLBACK;
// 按钮点击回调函数
typedef std::function<void()> BUTTON_CLICK_CALLBACK;
// 按键消息监听回调函数
typedef std::function<void()> KEY_LISTENER_CALLBACK;
// 鼠标消息监听回调函数
typedef std::function<void()> MOUSE_LISTENER_CALLBACK;
// 鼠标点击消息监听回调函数(参数为点击位置)
typedef std::function<void(EPoint mousePos)> MOUSE_CLICK_LISTENER_CALLBACK;
// 鼠标按下消息监听回调函数(参数为按下位置)
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_PRESS_LISTENER_CALLBACK;
// 鼠标双击消息监听回调函数(参数为双击位置)
typedef MOUSE_CLICK_LISTENER_CALLBACK MOUSE_DBLCLK_LISTENER_CALLBACK;
// 鼠标拖动消息监听函数(参数为拖动前位置和拖动后位置)
typedef std::function<void(EPoint begin, EPoint end)> MOUSE_DRAG_LISTENER_CALLBACK;

View File

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

View File

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

View File

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

View File

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

View File

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