using chrono

This commit is contained in:
Nomango 2017-10-10 01:14:03 +08:00
parent 8ed4c25f6c
commit bc88158d19
22 changed files with 191 additions and 182 deletions

View File

@ -56,14 +56,10 @@ void Action::notify()
m_bWaiting = false; m_bWaiting = false;
} }
void Action::setInterval(UINT ms) void Action::setInterval(LONGLONG milliSeconds)
{ {
// 设置动作的时间间隔 // 设置动作的时间间隔
LARGE_INTEGER nFreq; m_nAnimationInterval = milliSeconds;
QueryPerformanceFrequency(&nFreq);
m_nAnimationInterval.QuadPart = (LONGLONG)(ms / 1000.0 * nFreq.QuadPart);
// 保存时间间隔的时长
this->m_nMilliSeconds = ms;
} }
Action * Action::reverse() const Action * Action::reverse() const

View File

@ -19,7 +19,7 @@ void ActionCallback::_init()
Action::_init(); Action::_init();
} }
void ActionCallback::_exec(LARGE_INTEGER nNow) void ActionCallback::_exec(std::chrono::steady_clock::time_point nNow)
{ {
m_Callback(); m_Callback();
this->stop(); this->stop();

View File

@ -1,8 +1,9 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
ActionDelay::ActionDelay(float duration) ActionDelay::ActionDelay(float duration)
{ {
setInterval(UINT(duration * 1000)); setInterval(LONGLONG(duration * 1000));
} }
ActionDelay::~ActionDelay() ActionDelay::~ActionDelay()
@ -11,20 +12,20 @@ ActionDelay::~ActionDelay()
ActionDelay * ActionDelay::copy() const ActionDelay * ActionDelay::copy() const
{ {
return new ActionDelay(m_nMilliSeconds / 1000.0f); return new ActionDelay(m_nAnimationInterval / 1000.0f);
} }
void ActionDelay::_init() void ActionDelay::_init()
{ {
Action::_init(); Action::_init();
// 记录当前时间 // 记录当前时间
QueryPerformanceCounter(&m_nLast); m_nLast = steady_clock::now();
} }
void ActionDelay::_exec(LARGE_INTEGER nNow) void ActionDelay::_exec(steady_clock::time_point nNow)
{ {
// 判断时间间隔是否足够 // 判断时间间隔是否足够
if (nNow.QuadPart - m_nLast.QuadPart > m_nAnimationInterval.QuadPart) if (duration_cast<milliseconds>(nNow - m_nLast).count() > m_nAnimationInterval)
{ {
this->stop(); this->stop();
} }
@ -33,6 +34,6 @@ void ActionDelay::_exec(LARGE_INTEGER nNow)
void ActionDelay::_reset() void ActionDelay::_reset()
{ {
Action::_reset(); Action::_reset();
// 重新记录当前时间 // 记录当前时间
QueryPerformanceCounter(&m_nLast); m_nLast = steady_clock::now();
} }

View File

@ -1,4 +1,5 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
ActionFrames::ActionFrames() : ActionFrames::ActionFrames() :
m_nFrameIndex(0) m_nFrameIndex(0)
@ -7,7 +8,7 @@ ActionFrames::ActionFrames() :
setInterval(500); setInterval(500);
} }
ActionFrames::ActionFrames(UINT frameDelay) : ActionFrames::ActionFrames(LONGLONG frameDelay) :
m_nFrameIndex(0) m_nFrameIndex(0)
{ {
setInterval(frameDelay); setInterval(frameDelay);
@ -25,16 +26,16 @@ void ActionFrames::_init()
{ {
Action::_init(); Action::_init();
// 记录当前时间 // 记录当前时间
QueryPerformanceCounter(&m_nLast); m_nLast = steady_clock::now();
} }
void ActionFrames::_exec(LARGE_INTEGER nNow) void ActionFrames::_exec(steady_clock::time_point nNow)
{ {
// 判断时间间隔是否足够 // 判断时间间隔是否足够
while (nNow.QuadPart - m_nLast.QuadPart > m_nAnimationInterval.QuadPart) while (duration_cast<milliseconds>(nNow - m_nLast).count() > m_nAnimationInterval)
{ {
// 用求余的方法重新记录时间 // 重新记录时间
m_nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % m_nAnimationInterval.QuadPart); m_nLast += milliseconds(m_nAnimationInterval);
m_pTargetSprite->setImage(m_vFrames[m_nFrameIndex]); m_pTargetSprite->setImage(m_vFrames[m_nFrameIndex]);
m_nFrameIndex++; m_nFrameIndex++;
// 判断动作是否结束 // 判断动作是否结束
@ -49,6 +50,8 @@ void ActionFrames::_reset()
{ {
Action::_reset(); Action::_reset();
m_nFrameIndex = 0; m_nFrameIndex = 0;
// 记录当前时间
m_nLast = steady_clock::now();
} }
void ActionFrames::addFrame(Image * frame) void ActionFrames::addFrame(Image * frame)
@ -62,7 +65,7 @@ void ActionFrames::addFrame(Image * frame)
ActionFrames * ActionFrames::copy() const ActionFrames * ActionFrames::copy() const
{ {
auto a = new ActionFrames(this->m_nMilliSeconds); auto a = new ActionFrames(this->m_nAnimationInterval);
for (auto f : m_vFrames) for (auto f : m_vFrames)
{ {
a->addFrame(f); a->addFrame(f);

View File

@ -1,4 +1,5 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
ActionMoveBy::ActionMoveBy(float duration, CVector vec) : ActionMoveBy::ActionMoveBy(float duration, CVector vec) :
Animation(duration) Animation(duration)
@ -16,7 +17,7 @@ void ActionMoveBy::_init()
m_BeginPos = m_pTargetSprite->getPos(); m_BeginPos = m_pTargetSprite->getPos();
} }
void ActionMoveBy::_exec(LARGE_INTEGER nNow) void ActionMoveBy::_exec(steady_clock::time_point nNow)
{ {
if (Animation::_isDelayEnough(nNow)) if (Animation::_isDelayEnough(nNow))
{ {
@ -40,7 +41,7 @@ void ActionMoveBy::_reset()
ActionMoveBy * ActionMoveBy::copy() const ActionMoveBy * ActionMoveBy::copy() const
{ {
return new ActionMoveBy(m_nMilliSeconds / 1000.0f, m_MoveVector); return new ActionMoveBy(m_nAnimationInterval / 1000.0f, m_MoveVector);
} }
ActionMoveBy * ActionMoveBy::reverse() const ActionMoveBy * ActionMoveBy::reverse() const

View File

@ -12,7 +12,7 @@ ActionMoveTo::~ActionMoveTo()
ActionMoveTo * ActionMoveTo::copy() const ActionMoveTo * ActionMoveTo::copy() const
{ {
return new ActionMoveTo(m_nMilliSeconds / 1000.0f, m_EndPos); return new ActionMoveTo(m_nAnimationInterval / 1000.0f, m_EndPos);
} }
void ActionMoveTo::_init() void ActionMoveTo::_init()

View File

@ -23,7 +23,7 @@ void ActionNeverStop::_init()
m_Action->_init(); m_Action->_init();
} }
void ActionNeverStop::_exec(LARGE_INTEGER nNow) void ActionNeverStop::_exec(std::chrono::steady_clock::time_point nNow)
{ {
m_Action->_exec(nNow); m_Action->_exec(nNow);

View File

@ -1,4 +1,5 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
ActionOpacityBy::ActionOpacityBy(float duration, float opacity) : ActionOpacityBy::ActionOpacityBy(float duration, float opacity) :
Animation(duration) Animation(duration)
@ -16,7 +17,7 @@ void ActionOpacityBy::_init()
m_nBeginVal = m_pTargetSprite->getOpacity(); m_nBeginVal = m_pTargetSprite->getOpacity();
} }
void ActionOpacityBy::_exec(LARGE_INTEGER nNow) void ActionOpacityBy::_exec(steady_clock::time_point nNow)
{ {
if (Animation::_isDelayEnough(nNow)) if (Animation::_isDelayEnough(nNow))
{ {
@ -39,7 +40,7 @@ void ActionOpacityBy::_reset()
ActionOpacityBy * ActionOpacityBy::copy() const ActionOpacityBy * ActionOpacityBy::copy() const
{ {
return new ActionOpacityBy(m_nMilliSeconds / 1000.0f, m_nVariation); return new ActionOpacityBy(m_nAnimationInterval / 1000.0f, m_nVariation);
} }
ActionOpacityBy * ActionOpacityBy::reverse() const ActionOpacityBy * ActionOpacityBy::reverse() const

View File

@ -12,7 +12,7 @@ ActionOpacityTo::~ActionOpacityTo()
ActionOpacityTo * ActionOpacityTo::copy() const ActionOpacityTo * ActionOpacityTo::copy() const
{ {
return new ActionOpacityTo(m_nMilliSeconds / 1000.0f, m_nEndVal); return new ActionOpacityTo(m_nAnimationInterval / 1000.0f, m_nEndVal);
} }
void ActionOpacityTo::_init() void ActionOpacityTo::_init()

View File

@ -1,4 +1,5 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
ActionScaleBy::ActionScaleBy(float duration, float scaleX, float scaleY) : ActionScaleBy::ActionScaleBy(float duration, float scaleX, float scaleY) :
Animation(duration) Animation(duration)
@ -18,7 +19,7 @@ void ActionScaleBy::_init()
m_nBeginScaleY = m_pTargetSprite->getScaleY(); m_nBeginScaleY = m_pTargetSprite->getScaleY();
} }
void ActionScaleBy::_exec(LARGE_INTEGER nNow) void ActionScaleBy::_exec(steady_clock::time_point nNow)
{ {
if (Animation::_isDelayEnough(nNow)) if (Animation::_isDelayEnough(nNow))
{ {
@ -41,7 +42,7 @@ void ActionScaleBy::_reset()
ActionScaleBy * ActionScaleBy::copy() const ActionScaleBy * ActionScaleBy::copy() const
{ {
return new ActionScaleBy(m_nMilliSeconds / 1000.0f, m_nVariationX, m_nVariationY); return new ActionScaleBy(m_nAnimationInterval / 1000.0f, m_nVariationX, m_nVariationY);
} }
ActionScaleBy * ActionScaleBy::reverse() const ActionScaleBy * ActionScaleBy::reverse() const

View File

@ -13,7 +13,7 @@ ActionScaleTo::~ActionScaleTo()
ActionScaleTo * ActionScaleTo::copy() const ActionScaleTo * ActionScaleTo::copy() const
{ {
return new ActionScaleTo(m_nMilliSeconds / 1000.0f, m_nEndScaleX, m_nEndScaleY); return new ActionScaleTo(m_nAnimationInterval / 1000.0f, m_nEndScaleX, m_nEndScaleY);
} }
void ActionScaleTo::_init() void ActionScaleTo::_init()

View File

@ -41,7 +41,7 @@ void ActionSequence::_init()
m_vActions[0]->_init(); m_vActions[0]->_init();
} }
void ActionSequence::_exec(LARGE_INTEGER nNow) void ActionSequence::_exec(std::chrono::steady_clock::time_point nNow)
{ {
m_vActions[m_nActionIndex]->_exec(nNow); m_vActions[m_nActionIndex]->_exec(nNow);

View File

@ -40,7 +40,7 @@ void ActionTwo::_init()
m_FirstAction->_init(); m_FirstAction->_init();
} }
void ActionTwo::_exec(LARGE_INTEGER nNow) void ActionTwo::_exec(std::chrono::steady_clock::time_point nNow)
{ {
if (!m_FirstAction->isEnding()) if (!m_FirstAction->isEnding())
{ {

View File

@ -1,4 +1,5 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
Animation::Animation(float duration) Animation::Animation(float duration)
{ {
@ -19,17 +20,17 @@ void Animation::_init()
{ {
Action::_init(); Action::_init();
// 记录当前时间 // 记录当前时间
QueryPerformanceCounter(&m_nLast); m_nLast = steady_clock::now();
} }
bool Animation::_isDelayEnough(LARGE_INTEGER nNow) bool Animation::_isDelayEnough(steady_clock::time_point nNow)
{ {
// 判断时间间隔是否足够 // 判断时间间隔是否足够
if (nNow.QuadPart - m_nLast.QuadPart > m_nAnimationInterval.QuadPart) if (duration_cast<milliseconds>(nNow - m_nLast).count() > m_nAnimationInterval)
{ {
// 用求余的方法重新记录时间 // 重新记录时间
m_nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % m_nAnimationInterval.QuadPart); m_nLast += milliseconds(m_nAnimationInterval);
m_nDuration += m_nMilliSeconds; m_nDuration += m_nAnimationInterval;
return true; return true;
} }
return false; return false;
@ -39,6 +40,6 @@ void Animation::_reset()
{ {
Action::_reset(); Action::_reset();
m_nDuration = 0; m_nDuration = 0;
// 重新记录当前时间 // 记录当前时间
QueryPerformanceCounter(&m_nLast); m_nLast = steady_clock::now();
} }

View File

@ -1,17 +1,20 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
#include "..\EasyX\easyx.h" #include "..\EasyX\easyx.h"
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include <imm.h> #include <imm.h>
#pragma comment(lib, "imm32.lib") #pragma comment(lib, "imm32.lib")
#include <mmsystem.h> #include <stack>
#pragma comment(lib, "winmm.lib") #include <chrono>
#include <thread>
using namespace std::chrono;
// App 的唯一实例 // App 的唯一实例
static App * s_pInstance = nullptr; static App * s_pInstance = nullptr;
// 坐标原点的物理坐标 // 场景栈
static int originX = 0; static std::stack<Scene*> s_SceneStack;
static int originY = 0;
App::App() : App::App() :
m_pCurrentScene(nullptr), m_pCurrentScene(nullptr),
@ -23,7 +26,6 @@ App::App() :
{ {
assert(!s_pInstance); // 不能同时存在两个 App 实例 assert(!s_pInstance); // 不能同时存在两个 App 实例
s_pInstance = this; // 保存实例对象 s_pInstance = this; // 保存实例对象
setFPS(60); // 默认 FPS 为 60
} }
App::~App() App::~App()
@ -40,46 +42,48 @@ int App::run()
{ {
// 开启批量绘图 // 开启批量绘图
BeginBatchDraw(); BeginBatchDraw();
// 修改时间精度
timeBeginPeriod(1);
// 获取 CPU 每秒滴答声个数
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
// 创建时间变量
LARGE_INTEGER nLast;
LARGE_INTEGER nNow;
// 记录当前时间 // 记录当前时间
QueryPerformanceCounter(&nLast); steady_clock::time_point nLast = steady_clock::now();
// 帧间隔
LONGLONG nAnimationInterval = 17LL;
// 时间间隔 // 时间间隔
LONGLONG interval = 0LL; LONGLONG nInterval = 0LL;
// 挂起时长 // 挂起时长
LONG waitMS = 0L; LONGLONG nWaitMS = 0L;
// 将隐藏的窗口显示 // 将隐藏的窗口显示
ShowWindow(GetHWnd(), SW_NORMAL); ShowWindow(GetHWnd(), SW_NORMAL);
// 运行游戏 // 运行游戏
m_bRunning = true; m_bRunning = true;
// 启动多线程
//std::thread t(std::bind(&App::_mainLoop, this));
//t.join();
// 进入主循环 // 进入主循环
while (m_bRunning) while (m_bRunning)
{ {
// 获取当前时间 // 刷新计时
QueryPerformanceCounter(&nNow); ::FlushSteadyClock();
// 计算时间间隔 // 计算时间间隔
interval = nNow.QuadPart - nLast.QuadPart; nInterval = duration_cast<milliseconds>(GetNow() - nLast).count();
// 判断间隔时间是否足够 // 判断间隔时间是否足够
if (interval >= m_nAnimationInterval.QuadPart) if (nInterval >= nAnimationInterval)
{ {
// 记录当前时间 // 记录当前时间
nLast.QuadPart = nNow.QuadPart; nLast = GetNow();
// 执行游戏逻辑 // 刷新游戏画面
_mainLoop(); _draw();
} }
else else
{ {
// 计算挂起时长 // 计算挂起时长
waitMS = LONG((m_nAnimationInterval.QuadPart - interval) * 1000LL / freq.QuadPart) - 1L; /*nWaitMS = nAnimationInterval * 2 - nInterval;
// 挂起线程,释放 CPU 占用 // 挂起线程,释放 CPU 占用
if (waitMS > 1L) Sleep(waitMS); if (nWaitMS > 1LL)
{
std::this_thread::sleep_for(milliseconds(nWaitMS));
}*/
} }
} }
// 停止批量绘图 // 停止批量绘图
@ -88,8 +92,6 @@ int App::run()
close(); close();
// 释放所有内存占用 // 释放所有内存占用
free(); free();
// 重置时间精度
timeEndPeriod(1);
return 0; return 0;
} }
@ -132,7 +134,7 @@ void App::_initGraph()
} }
} }
void App::_mainLoop() void App::_draw()
{ {
// 下一场景指针不为空时,切换场景 // 下一场景指针不为空时,切换场景
if (m_pNextScene) if (m_pNextScene)
@ -147,7 +149,6 @@ void App::_mainLoop()
m_pCurrentScene->_onDraw(); // 绘制当前场景 m_pCurrentScene->_onDraw(); // 绘制当前场景
FlushBatchDraw(); // 刷新画面 FlushBatchDraw(); // 刷新画面
// 其他执行程序
MouseMsg::__exec(); // 鼠标检测 MouseMsg::__exec(); // 鼠标检测
KeyMsg::__exec(); // 键盘按键检测 KeyMsg::__exec(); // 键盘按键检测
Timer::__exec(); // 定时器执行程序 Timer::__exec(); // 定时器执行程序
@ -155,6 +156,23 @@ void App::_mainLoop()
FreePool::__flush(); // 刷新内存池 FreePool::__flush(); // 刷新内存池
} }
void App::_mainLoop()
{
while (true)
{
if (m_bRunning)
{
MouseMsg::__exec(); // 鼠标检测
KeyMsg::__exec(); // 键盘按键检测
Timer::__exec(); // 定时器执行程序
ActionManager::__exec(); // 动作管理器执行程序
FreePool::__flush(); // 刷新内存池
}
std::this_thread::sleep_for(milliseconds(10));
}
}
void App::createWindow(int width, int height, int mode) void App::createWindow(int width, int height, int mode)
{ {
// 保存窗口信息 // 保存窗口信息
@ -251,7 +269,7 @@ void App::enterScene(Scene * scene, bool save)
void App::backScene() void App::backScene()
{ {
// 从栈顶取出场景指针,作为下一场景 // 从栈顶取出场景指针,作为下一场景
s_pInstance->m_pNextScene = s_pInstance->m_SceneStack.top(); s_pInstance->m_pNextScene = s_SceneStack.top();
// 不保存当前场景 // 不保存当前场景
s_pInstance->m_bSaveScene = false; s_pInstance->m_bSaveScene = false;
} }
@ -259,11 +277,11 @@ void App::backScene()
void App::clearScene() void App::clearScene()
{ {
// 清空场景栈 // 清空场景栈
while (s_pInstance->m_SceneStack.size()) while (s_SceneStack.size())
{ {
auto temp = s_pInstance->m_SceneStack.top(); auto temp = s_SceneStack.top();
SafeDelete(temp); SafeDelete(temp);
s_pInstance->m_SceneStack.pop(); s_SceneStack.pop();
} }
} }
@ -287,11 +305,11 @@ void App::_enterNextScene()
bool bBackScene = false; bool bBackScene = false;
// 若下一场景处于栈顶,说明正在返回上一场景 // 若下一场景处于栈顶,说明正在返回上一场景
if (m_SceneStack.size() && m_pNextScene == m_SceneStack.top()) if (s_SceneStack.size() && m_pNextScene == s_SceneStack.top())
{ {
bBackScene = true; bBackScene = true;
// 删除栈顶场景 // 删除栈顶场景
m_SceneStack.pop(); s_SceneStack.pop();
} }
// 执行当前场景的 onExit 函数 // 执行当前场景的 onExit 函数
@ -301,7 +319,7 @@ void App::_enterNextScene()
if (m_bSaveScene) if (m_bSaveScene)
{ {
// 若要保存当前场景,把它放入栈中 // 若要保存当前场景,把它放入栈中
m_SceneStack.push(m_pCurrentScene); s_SceneStack.push(m_pCurrentScene);
// 暂停当前场景上运行的所有定时器 // 暂停当前场景上运行的所有定时器
Timer::waitAllSceneTimers(m_pCurrentScene); Timer::waitAllSceneTimers(m_pCurrentScene);
MouseMsg::waitAllSceneListeners(m_pCurrentScene); MouseMsg::waitAllSceneListeners(m_pCurrentScene);
@ -367,14 +385,6 @@ Scene * App::getLoadingScene()
return s_pInstance->m_pLoadingScene; return s_pInstance->m_pLoadingScene;
} }
void App::setFPS(DWORD fps)
{
// 设置画面帧率,以毫秒为单位
LARGE_INTEGER nFreq;
QueryPerformanceFrequency(&nFreq);
s_pInstance->m_nAnimationInterval.QuadPart = (LONGLONG)(1.0 / fps * nFreq.QuadPart);
}
int App::getWidth() int App::getWidth()
{ {
return s_pInstance->m_Size.cx; return s_pInstance->m_Size.cx;
@ -385,34 +395,17 @@ int App::getHeight()
return s_pInstance->m_Size.cy; return s_pInstance->m_Size.cy;
} }
void App::setOrigin(int originX, int originY)
{
::originX = originX;
::originY = originY;
setorigin(originX, originY);
}
int App::getOriginX()
{
return ::originX;
}
int App::getOriginY()
{
return ::originY;
}
void App::free() void App::free()
{ {
// 释放场景内存 // 释放场景内存
SafeDelete(m_pCurrentScene); SafeDelete(m_pCurrentScene);
SafeDelete(m_pNextScene); SafeDelete(m_pNextScene);
// 清空场景栈 // 清空场景栈
while (m_SceneStack.size()) while (s_SceneStack.size())
{ {
auto temp = m_SceneStack.top(); auto temp = s_SceneStack.top();
SafeDelete(temp); SafeDelete(temp);
m_SceneStack.pop(); s_SceneStack.pop();
} }
// 删除所有定时器 // 删除所有定时器
Timer::clearAllTimers(); Timer::clearAllTimers();

View File

@ -391,9 +391,11 @@
<ClCompile Include="Tool\Math.cpp" /> <ClCompile Include="Tool\Math.cpp" />
<ClCompile Include="Tool\MusicUtils.cpp" /> <ClCompile Include="Tool\MusicUtils.cpp" />
<ClCompile Include="Tool\Timer.cpp" /> <ClCompile Include="Tool\Timer.cpp" />
<ClCompile Include="Win\winbase.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="easy2d.h" /> <ClInclude Include="easy2d.h" />
<ClInclude Include="Win\winbase.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -37,6 +37,9 @@
<Filter Include="源文件\Base"> <Filter Include="源文件\Base">
<UniqueIdentifier>{261633d3-3814-40c7-bd6d-201ede6c6ade}</UniqueIdentifier> <UniqueIdentifier>{261633d3-3814-40c7-bd6d-201ede6c6ade}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="源文件\Win">
<UniqueIdentifier>{37b7730c-acb0-4b57-b1f8-01680951611c}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Style\Color.cpp"> <ClCompile Include="Style\Color.cpp">
@ -171,10 +174,16 @@
<ClCompile Include="Tool\Math.cpp"> <ClCompile Include="Tool\Math.cpp">
<Filter>源文件\Tool</Filter> <Filter>源文件\Tool</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Win\winbase.cpp">
<Filter>源文件\Win</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="easy2d.h"> <ClInclude Include="easy2d.h">
<Filter>头文件</Filter> <Filter>头文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Win\winbase.h">
<Filter>源文件\Win</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,15 +1,13 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
#include <assert.h> #include <assert.h>
static std::vector<Action*> s_vActions; static std::vector<Action*> s_vActions;
void ActionManager::__exec() void ActionManager::__exec()
{ {
// 获取当前时间
static LARGE_INTEGER nNow;
QueryPerformanceCounter(&nNow);
// 临时指针 // 临时指针
Action * action; static Action * action;
// 循环遍历所有正在运行的动作 // 循环遍历所有正在运行的动作
for (size_t i = 0; i < s_vActions.size(); i++) for (size_t i = 0; i < s_vActions.size(); i++)
{ {
@ -31,7 +29,7 @@ void ActionManager::__exec()
action->_init(); action->_init();
} }
// 执行动作 // 执行动作
action->_exec(nNow); action->_exec(GetNow());
} }
} }
} }

View File

@ -1,16 +1,17 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\Win\winbase.h"
// 储存所有定时器的容器 // 储存所有定时器的容器
static std::vector<Timer*> s_vTimers; static std::vector<Timer*> s_vTimers;
Timer::Timer(TString name, UINT ms, const TIMER_CALLBACK & callback) : Timer::Timer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback) :
m_sName(name), m_sName(name),
m_bRunning(false), m_bRunning(false),
m_bWaiting(false), m_bWaiting(false),
m_callback(callback), m_callback(callback),
m_pParentScene(nullptr) m_pParentScene(nullptr)
{ {
setInterval(ms); // 设置定时器的时间间隔 setInterval(milliSeconds); // 设置定时器的时间间隔
} }
Timer::~Timer() Timer::~Timer()
@ -22,7 +23,7 @@ void Timer::start()
// 标志该定时器正在运行 // 标志该定时器正在运行
m_bRunning = true; m_bRunning = true;
// 记录当前时间 // 记录当前时间
QueryPerformanceCounter(&m_nLast); m_nLast = steady_clock::now();
} }
void Timer::stop() void Timer::stop()
@ -45,14 +46,10 @@ bool Timer::isRunning()
return m_bRunning && !m_bWaiting; // 获取该定时器的运行状态 return m_bRunning && !m_bWaiting; // 获取该定时器的运行状态
} }
void Timer::setInterval(UINT ms) void Timer::setInterval(LONGLONG milliSeconds)
{ {
// 设置定时器的时间间隔 // 设置定时器的时间间隔
LARGE_INTEGER nFreq; m_nAnimationInterval = milliSeconds;
QueryPerformanceFrequency(&nFreq);
m_nAnimationInterval.QuadPart = (LONGLONG)(ms / 1000.0 * nFreq.QuadPart);
// 保存时间间隔的时长
this->m_nMilliSeconds = ms;
} }
void Timer::setCallback(const TIMER_CALLBACK & callback) void Timer::setCallback(const TIMER_CALLBACK & callback)
@ -65,9 +62,9 @@ void Timer::setName(TString name)
m_sName = name; // 修改定时器名称 m_sName = name; // 修改定时器名称
} }
UINT Timer::getInterval() const LONGLONG Timer::getInterval() const
{ {
return m_nMilliSeconds; // 获取定时器的时间间隔 return m_nAnimationInterval;// 获取定时器的时间间隔
} }
TString Timer::getName() const TString Timer::getName() const
@ -82,9 +79,6 @@ void Timer::__exec()
{ {
return; return;
} }
// 获取当前时间
static LARGE_INTEGER nNow;
QueryPerformanceCounter(&nNow);
// 循环遍历所有的定时器 // 循环遍历所有的定时器
for (auto timer : s_vTimers) for (auto timer : s_vTimers)
{ {
@ -94,10 +88,10 @@ void Timer::__exec()
continue; continue;
} }
// 判断时间间隔是否足够 // 判断时间间隔是否足够
if (nNow.QuadPart - timer->m_nLast.QuadPart > timer->m_nAnimationInterval.QuadPart) if (duration_cast<milliseconds>(GetNow() - timer->m_nLast).count() > timer->m_nAnimationInterval)
{ {
// 用求余的方法重新记录时间 // 重新记录时间
timer->m_nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % timer->m_nAnimationInterval.QuadPart); timer->m_nLast += milliseconds(timer->m_nAnimationInterval);
// 运行回调函数 // 运行回调函数
timer->m_callback(); timer->m_callback();
} }
@ -119,10 +113,10 @@ void Timer::addTimer(TString name, const TIMER_CALLBACK & callback)
addTimer(name, 20, callback); addTimer(name, 20, callback);
} }
void Timer::addTimer(TString name, UINT ms, const TIMER_CALLBACK & callback) void Timer::addTimer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback)
{ {
// 创建定时器 // 创建定时器
auto timer = new Timer(name, ms, callback); auto timer = new Timer(name, milliSeconds, callback);
// 添加定时器 // 添加定时器
addTimer(timer); addTimer(timer);
} }

13
Easy2D/Win/winbase.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "winbase.h"
static steady_clock::time_point nNow;
steady_clock::time_point GetNow()
{
return nNow;
}
void FlushSteadyClock()
{
nNow = steady_clock::now(); // 获取当前时间
}

7
Easy2D/Win/winbase.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <chrono>
using namespace std::chrono;
steady_clock::time_point GetNow();
void FlushSteadyClock();

View File

@ -21,8 +21,8 @@
#include <tchar.h> #include <tchar.h>
#include <atltypes.h> #include <atltypes.h>
#include <atlimage.h> #include <atlimage.h>
#include <chrono>
#include <vector> #include <vector>
#include <stack>
#include <functional> #include <functional>
#include <random> #include <random>
@ -136,12 +136,6 @@ public:
// 获取程序实例 // 获取程序实例
static App * get(); static App * get();
// 设置坐标原点
static void setOrigin(int originX, int originY);
// 获取坐标原点的物理横坐标
static int getOriginX();
// 获取坐标原点的物理纵坐标
static int getOriginY();
// 终止程序 // 终止程序
static void quit(); static void quit();
// 终止程序 // 终止程序
@ -172,8 +166,6 @@ public:
static TString getAppName(); static TString getAppName();
// 修改窗口背景色 // 修改窗口背景色
static void setBkColor(COLORREF color); static void setBkColor(COLORREF color);
// 设置帧率
static void setFPS(DWORD fps);
// 重置绘图样式为默认值 // 重置绘图样式为默认值
static void reset(); static void reset();
// 获取当前场景 // 获取当前场景
@ -182,20 +174,19 @@ public:
static Scene * getLoadingScene(); static Scene * getLoadingScene();
protected: protected:
TString m_sTitle; TString m_sTitle;
TString m_sAppName; TString m_sAppName;
Scene* m_pCurrentScene; Scene* m_pCurrentScene;
Scene* m_pNextScene; Scene* m_pNextScene;
Scene* m_pLoadingScene; Scene* m_pLoadingScene;
std::stack<Scene*> m_SceneStack; CSize m_Size;
LARGE_INTEGER m_nAnimationInterval; int m_nWindowMode;
CSize m_Size; bool m_bRunning;
int m_nWindowMode; bool m_bSaveScene;
bool m_bRunning;
bool m_bSaveScene;
protected: protected:
void _initGraph(); void _initGraph();
void _draw();
void _mainLoop(); void _mainLoop();
void _enterNextScene(); void _enterNextScene();
}; };
@ -1158,7 +1149,7 @@ public:
// 唤醒 // 唤醒
virtual void notify(); virtual void notify();
// 设置动作每一帧时间间隔 // 设置动作每一帧时间间隔
virtual void setInterval(UINT ms); virtual void setInterval(LONGLONG milliSeconds);
// 获取一个新的拷贝动作 // 获取一个新的拷贝动作
virtual Action * copy() const = 0; virtual Action * copy() const = 0;
// 获取一个新的逆向动作 // 获取一个新的逆向动作
@ -1167,19 +1158,18 @@ public:
virtual Sprite * getTarget(); virtual Sprite * getTarget();
protected: protected:
bool m_bRunning; bool m_bRunning;
bool m_bWaiting; bool m_bWaiting;
bool m_bEnding; bool m_bEnding;
bool m_bInit; bool m_bInit;
Sprite * m_pTargetSprite; Sprite * m_pTargetSprite;
Scene * m_pParentScene; Scene * m_pParentScene;
UINT m_nMilliSeconds; LONGLONG m_nAnimationInterval;
LARGE_INTEGER m_nLast; std::chrono::steady_clock::time_point m_nLast;
LARGE_INTEGER m_nAnimationInterval;
protected: protected:
virtual void _init(); virtual void _init();
virtual void _exec(LARGE_INTEGER nNow) = 0; virtual void _exec(std::chrono::steady_clock::time_point nNow) = 0;
virtual void _reset(); virtual void _reset();
}; };
@ -1191,12 +1181,12 @@ public:
virtual ~Animation(); virtual ~Animation();
protected: protected:
UINT m_nDuration; LONGLONG m_nDuration;
UINT m_nTotalDuration; LONGLONG m_nTotalDuration;
protected: protected:
bool _isEnd() const; bool _isEnd() const;
bool _isDelayEnough(LARGE_INTEGER nNow); bool _isDelayEnough(std::chrono::steady_clock::time_point nNow);
virtual void _init() override; virtual void _init() override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1217,7 +1207,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1256,7 +1246,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1294,7 +1284,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1345,7 +1335,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1367,7 +1357,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1382,7 +1372,7 @@ public:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1400,7 +1390,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1409,7 +1399,7 @@ class ActionFrames :
{ {
public: public:
ActionFrames(); ActionFrames();
ActionFrames(UINT frameDelay); ActionFrames(LONGLONG frameDelay);
~ActionFrames(); ~ActionFrames();
void addFrame(Image * frame); void addFrame(Image * frame);
@ -1422,7 +1412,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1440,7 +1430,7 @@ protected:
protected: protected:
virtual void _init() override; virtual void _init() override;
virtual void _exec(LARGE_INTEGER nNow) override; virtual void _exec(std::chrono::steady_clock::time_point nNow) override;
virtual void _reset() override; virtual void _reset() override;
}; };
@ -1521,7 +1511,7 @@ class Timer
{ {
friend App; friend App;
public: public:
Timer(TString name, UINT ms, const TIMER_CALLBACK & callback); Timer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback);
~Timer(); ~Timer();
// 启动定时器 // 启动定时器
@ -1535,13 +1525,13 @@ public:
// 定时器是否正在运行 // 定时器是否正在运行
bool isRunning(); bool isRunning();
// 设置间隔时间 // 设置间隔时间
void setInterval(UINT ms); void setInterval(LONGLONG milliSeconds);
// 设置回调函数 // 设置回调函数
void setCallback(const TIMER_CALLBACK& callback); void setCallback(const TIMER_CALLBACK& callback);
// 设置定时器名称 // 设置定时器名称
void setName(TString name); void setName(TString name);
// 获取定时器间隔时间 // 获取定时器间隔时间
UINT getInterval() const; LONGLONG getInterval() const;
// 获取定时器名称 // 获取定时器名称
TString getName() const; TString getName() const;
@ -1550,7 +1540,7 @@ public:
// 添加定时器 // 添加定时器
static void addTimer(TString name, const TIMER_CALLBACK & callback); static void addTimer(TString name, const TIMER_CALLBACK & callback);
// 添加定时器 // 添加定时器
static void addTimer(TString name, UINT ms, const TIMER_CALLBACK & callback); static void addTimer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback);
// 启动特定定时器 // 启动特定定时器
static void startTimer(TString name); static void startTimer(TString name);
// 停止特定定时器 // 停止特定定时器
@ -1572,10 +1562,9 @@ protected:
bool m_bWaiting; bool m_bWaiting;
TString m_sName; TString m_sName;
TIMER_CALLBACK m_callback; TIMER_CALLBACK m_callback;
LARGE_INTEGER m_nLast; LONGLONG m_nAnimationInterval;
LARGE_INTEGER m_nAnimationInterval;
UINT m_nMilliSeconds;
Scene * m_pParentScene; Scene * m_pParentScene;
std::chrono::steady_clock::time_point m_nLast;
private: private:
static void __exec(); static void __exec();