增加Time时间点和Duration时间段

This commit is contained in:
Nomango 2018-07-21 22:57:21 +08:00
parent e16249b1a4
commit 7d17c3b225
26 changed files with 183 additions and 203 deletions

View File

@ -24,7 +24,7 @@ bool e2d::Action::isRunning()
void e2d::Action::resume()
{
_running = true;
_last = Time::getTotalTime();
_last = Game::getInstance()->getTotalTime();
}
void e2d::Action::pause()
@ -56,7 +56,7 @@ void e2d::Action::reset()
{
_initialized = false;
_done = false;
_last = Time::getTotalTime();
_last = Game::getInstance()->getTotalTime();
}
bool e2d::Action::_isDone()
@ -74,7 +74,7 @@ void e2d::Action::_startWithTarget(Node* target)
void e2d::Action::_init()
{
_initialized = true;
_last = Time::getTotalTime();
_last = Game::getInstance()->getTotalTime();
}
void e2d::Action::_update()

View File

@ -56,7 +56,7 @@ void e2d::Animate::_update()
return;
}
while ((Time::getTotalTime() - _last) >= _animation->getInterval())
while ((Game::getInstance()->getTotalTime() - _last) >= _animation->getInterval())
{
auto& frames = _animation->getFrames();
auto target = dynamic_cast<Sprite*>(_target);
@ -80,7 +80,7 @@ void e2d::Animate::_update()
void e2d::Animate::_resetTime()
{
Action::_resetTime();
_last = Time::getTotalTime();
_last = Game::getInstance()->getTotalTime();
}
void e2d::Animate::reset()

View File

@ -31,7 +31,7 @@ void e2d::Delay::_update()
{
Action::_update();
_delta = Time::getTotalTime() - _last;
_delta = Game::getInstance()->getTotalTime() - _last;
if (_delta >= _delay)
{
@ -42,5 +42,5 @@ void e2d::Delay::_update()
void e2d::Delay::_resetTime()
{
Action::_resetTime();
_last = Time::getTotalTime() - _delta;
_last = Game::getInstance()->getTotalTime() - _delta;
}

View File

@ -28,7 +28,7 @@ void e2d::FiniteTimeAction::_update()
}
else
{
_delta = std::min((Time::getTotalTime() - _last) / _duration, 1.0);
_delta = std::min((Game::getInstance()->getTotalTime() - _last) / _duration, 1.0);
if (_delta >= 1)
{
@ -40,5 +40,5 @@ void e2d::FiniteTimeAction::_update()
void e2d::FiniteTimeAction::_resetTime()
{
Action::_resetTime();
_last = Time::getTotalTime() - _delta * _duration;
_last = Game::getInstance()->getTotalTime() - _delta * _duration;
}

View File

@ -49,6 +49,10 @@ e2d::GC::GC()
e2d::GC::~GC()
{
// 删除所有对象
GC::clear();
// 清除图片缓存
Image::clearCache();
// 删除所有单例
Game::destroyInstance();
Renderer::destroyInstance();
@ -92,6 +96,11 @@ void e2d::GC::flush()
void e2d::GC::clear()
{
_instance._cleanup = true;
SceneManager::getInstance()->clear();
Timer::getInstance()->clearAllTasks();
ActionManager::getInstance()->clearAll();
for (auto pair : _instance._pool)
{
if (pair.second)

View File

@ -1,6 +1,9 @@
#include "..\e2dbase.h"
#include "..\e2dmanager.h"
#include "..\e2dtool.h"
#include <thread>
using namespace std::chrono;
e2d::Game * e2d::Game::_instance = nullptr;
@ -11,6 +14,8 @@ e2d::Game::Game()
, _config(nullptr)
{
CoInitialize(nullptr);
_start = _last = _now = steady_clock::now();
}
e2d::Game::~Game()
@ -36,7 +41,7 @@ void e2d::Game::destroyInstance()
}
}
void e2d::Game::start(bool cleanup)
void e2d::Game::start()
{
auto input = Input::getInstance();
auto window = Window::getInstance();
@ -45,51 +50,56 @@ void e2d::Game::start(bool cleanup)
auto sceneManager = SceneManager::getInstance();
auto actionManager = ActionManager::getInstance();
// 显示窗口
::ShowWindow(window->getHWnd(), SW_SHOWNORMAL);
// 刷新窗口内容
::UpdateWindow(window->getHWnd());
// 处理窗口消息
window->poll();
// 初始化计时
Time::__init();
if (!input || !window || !renderer || !timer || !sceneManager || !actionManager)
{
throw SystemException(L"初始化失败");
}
HWND hWnd = window->getHWnd();
if (hWnd == nullptr)
{
throw SystemException(L"无法创建窗口");
}
// 显示窗口
::ShowWindow(hWnd, SW_SHOWNORMAL);
::UpdateWindow(hWnd);
window->poll();
// 开始游戏
const milliseconds frameInterval(15LL);
milliseconds wait, interval;
_ended = false;
_last = _now = steady_clock::now();
while (!_ended)
{
// 处理窗口消息
window->poll();
// 刷新时间
Time::__updateNow();
_now = steady_clock::now();
interval = duration_cast<milliseconds>(_now - _last);
// 判断是否达到了刷新状态
if (Time::__isReady())
if (frameInterval < interval)
{
if (_config->_unconfigured)
{
_config->_update();
}
_last = _now;
input->update(); // 获取用户输入
timer->update(); // 更新定时器
actionManager->update(); // 更新动作管理器
sceneManager->update(); // 更新场景内容
_config->_update(); // 更新游戏配置
renderer->render(); // 渲染游戏画面
window->poll(); // 处理窗口消息
GC::flush(); // 刷新内存池
Time::__updateLast(); // 刷新时间信息
}
else
{
Time::__sleep(); // 挂起线程
wait = frameInterval - interval;
if (wait.count() > 1LL)
{
std::this_thread::sleep_for(wait - milliseconds(1LL));
}
}
}
if (cleanup)
{
Game::cleanup();
}
}
void e2d::Game::pause()
@ -101,7 +111,9 @@ void e2d::Game::resume()
{
if (_paused && !_ended)
{
Time::__reset();
_last = _now = steady_clock::now();
Timer::getInstance()->updateTime();
ActionManager::getInstance()->updateTime();
}
_paused = false;
}
@ -129,6 +141,11 @@ e2d::Config* e2d::Game::getConfig()
return _config;
}
double e2d::Game::getTotalTime() const
{
return duration_cast<microseconds>(steady_clock::now() - _start).count() / 1000.0 / 1000.0;
}
void e2d::Game::quit()
{
_ended = true; // 这个变量将控制游戏是否结束
@ -136,16 +153,7 @@ void e2d::Game::quit()
void e2d::Game::cleanup()
{
// 删除所有场景
SceneManager::getInstance()->clear();
// 清空定时器
Timer::getInstance()->clearAllTasks();
// 清除所有动作
ActionManager::getInstance()->clearAll();
// 清空图片缓存
Image::clearCache();
// 清空音乐缓存
Player::getInstance()->clearCache();
// 删除所有对象
GC::clear();
Image::clearCache();
Player::getInstance()->clearCache();
}

View File

@ -161,11 +161,11 @@ void e2d::Renderer::_renderFps()
{
++_renderTimes;
double fDelay = Time::getTotalTime() - _lastRenderTime;
double fDelay = Game::getInstance()->getTotalTime() - _lastRenderTime;
if (fDelay >= 0.1)
{
_fpsText = String::format(L"FPS: %.1lf", (1 / fDelay) * _renderTimes);
_lastRenderTime = Time::getTotalTime();
_lastRenderTime = Game::getInstance()->getTotalTime();
_renderTimes = 0;
}

View File

@ -1,73 +0,0 @@
#include "..\e2dbase.h"
#include "..\e2dtool.h"
#include "..\e2dmanager.h"
#include <thread>
using namespace std::chrono;
// 游戏开始时间
steady_clock::time_point e2d::Time::_start;
// 当前时间
steady_clock::time_point e2d::Time::_now;
// 上一帧刷新时间
steady_clock::time_point e2d::Time::_last;
// 固定的刷新时间
steady_clock::time_point e2d::Time::_fixedLast;
// 每一帧间隔
milliseconds e2d::Time::_interval;
double e2d::Time::getTotalTime()
{
return duration_cast<microseconds>(_now - _start).count() / 1000.0 / 1000.0;
}
double e2d::Time::getDeltaTime()
{
return duration_cast<microseconds>(_now - _last).count() / 1000.0 / 1000.0;
}
bool e2d::Time::__init()
{
_start = _fixedLast = _last = _now = steady_clock::now();
_interval = milliseconds(15);
return true;
}
bool e2d::Time::__isReady()
{
return _interval < duration_cast<milliseconds>(_now - _fixedLast);
}
void e2d::Time::__updateNow()
{
_now = steady_clock::now();
}
void e2d::Time::__updateLast()
{
_fixedLast += _interval;
_last = _now;
_now = steady_clock::now();
}
void e2d::Time::__reset()
{
_last = _fixedLast = _now = steady_clock::now();
Timer::getInstance()->updateTime();
ActionManager::getInstance()->updateTime();
}
void e2d::Time::__sleep()
{
// 计算挂起时长
int nWaitMS = 16 - static_cast<int>(duration_cast<milliseconds>(_now - _fixedLast).count());
if (nWaitMS > 1)
{
// 挂起线程,释放 CPU 占用
std::this_thread::sleep_for(milliseconds(nWaitMS));
}
}

View File

@ -107,6 +107,9 @@ bool e2d::Config::isColliderVisible() const
void e2d::Config::_update()
{
if (!_unconfigured)
return;
_unconfigured = false;
if (_soundEnabled)

17
core/Common/Duration.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "..\e2dcommon.h"
using namespace std::chrono;
e2d::Duration::Duration()
{
}
e2d::Duration e2d::Duration::operator+(Duration const & size) const
{
return Duration();
}
e2d::Duration e2d::Duration::operator-(Duration const & size) const
{
return Duration();
}

View File

@ -296,9 +296,12 @@ bool e2d::Image::preload(const Resource& res)
void e2d::Image::clearCache()
{
if (_bitmapCache.empty())
return;
for (auto bitmap : _bitmapCache)
{
SafeRelease(bitmap.second);
bitmap.second->Release();
}
_bitmapCache.clear();
}

18
core/Common/Time.cpp Normal file
View File

@ -0,0 +1,18 @@
#include "..\e2dcommon.h"
using namespace std::chrono;
e2d::Time::Time()
{
}
e2d::Time e2d::Time::operator+(Duration const & size) const
{
return Time();
}
e2d::Duration e2d::Time::operator-(Time const & size) const
{
return Duration();
}

View File

@ -213,12 +213,16 @@ void e2d::ActionManager::clearAllBindedWith(Node * target)
void e2d::ActionManager::clearAll()
{
for (auto action : _runningActions)
if (!_runningActions.empty())
{
GC::release(action);
for (auto action : _runningActions)
{
GC::release(action);
}
_runningActions.clear();
}
_actions.clear();
_runningActions.clear();
}
std::vector<e2d::Action*> e2d::ActionManager::get(const String& name)

View File

@ -85,20 +85,19 @@ void e2d::SceneManager::pop(Transition * transition /* = nullptr */)
// 设置切换场景动作
if (transition)
{
_transition = transition;
GC::retain(transition);
transition->_init(_currScene, _nextScene);
transition->_update();
_transition = transition;
}
}
void e2d::SceneManager::clear()
{
// 清空场景栈
while (_scenes.size())
while (!_scenes.empty())
{
auto temp = _scenes.top();
GC::safeRelease(temp);
_scenes.top()->release();
_scenes.pop();
}
}

View File

@ -13,9 +13,13 @@ e2d::Player::Player()
e2d::Player::~Player()
{
for (auto pair : _musicList)
GC::release(pair.second);
_musicList.clear();
if (!_musicList.empty())
{
for (auto pair : _musicList)
{
delete pair.second;
}
}
if (_masteringVoice)
_masteringVoice->DestroyVoice();
@ -31,9 +35,8 @@ e2d::Player * e2d::Player::getInstance()
{
_instance = new (std::nothrow) Player;
HRESULT hr;
if (FAILED(hr = XAudio2Create(&_instance->_xAudio2, 0)) ||
FAILED(hr = _instance->_xAudio2->CreateMasteringVoice(&_instance->_masteringVoice)))
if (FAILED(XAudio2Create(&_instance->_xAudio2, 0)) ||
FAILED(_instance->_xAudio2->CreateMasteringVoice(&_instance->_masteringVoice)))
{
throw SystemException(L"³õʼ»¯ XAudio2 ×é¼þʧ°Ü");
}
@ -68,11 +71,10 @@ bool e2d::Player::preload(const Resource& res)
if (_musicList.end() != _musicList.find(res))
return true;
Music * music = new (e2d::autorelease) Music();
Music * music = new Music();
if (music->open(res))
{
GC::retain(music);
music->setVolume(_volume);
_musicList.insert(std::make_pair(res, music));
return true;
@ -139,10 +141,6 @@ void e2d::Player::stop(const String& filePath)
void e2d::Player::stop(const Resource& res)
{
if (res.isResource())
{
}
if (_musicList.end() != _musicList.find(res))
_musicList[res]->stop();
}
@ -204,7 +202,7 @@ void e2d::Player::clearCache()
{
for (auto pair : _musicList)
{
GC::release(pair.second);
delete pair.second;
}
_musicList.clear();
}

View File

@ -60,7 +60,7 @@ bool e2d::Task::isReady() const
{
return true;
}
if ((Time::getTotalTime() - _lastTime) >= _delay)
if ((Game::getInstance()->getTotalTime() - _lastTime) >= _delay)
{
return true;
}
@ -80,5 +80,5 @@ e2d::String e2d::Task::getName() const
void e2d::Task::updateTime()
{
_lastTime = Time::getTotalTime();
_lastTime = Game::getInstance()->getTotalTime();
}

View File

@ -100,6 +100,9 @@ void e2d::Timer::removeAllTasks()
void e2d::Timer::clearAllTasks()
{
if (_tasks.empty())
return;
for (auto task : _tasks)
{
GC::release(task);

View File

@ -45,7 +45,7 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
throw SystemException(L"场景过渡动画图层创建失败");
}
_last = Time::getTotalTime();
_last = Game::getInstance()->getTotalTime();
_outScene = prev;
_inScene = next;
GC::retain(_outScene);
@ -64,7 +64,7 @@ void e2d::Transition::_update()
}
else
{
_delta = std::min((Time::getTotalTime() - _last) / _duration, 1.0);
_delta = std::min((Game::getInstance()->getTotalTime() - _last) / _duration, 1.0);
}
this->_updateCustom();

View File

@ -21,9 +21,7 @@ public:
static void destroyInstance();
// 启动游戏
void start(
bool cleanup = true /* 自动清理资源 */
);
void start();
// 暂停游戏
void pause();
@ -48,6 +46,8 @@ public:
// 获取游戏配置
Config* getConfig();
double getTotalTime() const;
private:
Game();
@ -59,6 +59,9 @@ private:
bool _ended;
bool _paused;
Config* _config;
std::chrono::steady_clock::time_point _start;
std::chrono::steady_clock::time_point _now;
std::chrono::steady_clock::time_point _last;
static Game * _instance;
};
@ -185,46 +188,6 @@ private:
};
// 时间控制
class Time
{
friend class Game;
public:
// 获取上一帧的时间间隔(秒)
static double getDeltaTime();
// 获取游戏总时长(秒)
static double getTotalTime();
private:
// 初始化计时操作
static bool __init();
// 是否达到更新时间
static bool __isReady();
// 更新当前时间
static void __updateNow();
// 更新时间信息
static void __updateLast();
// 重置时间信息
static void __reset();
// 挂起线程
static void __sleep();
private:
static std::chrono::steady_clock::time_point _start;
static std::chrono::steady_clock::time_point _now;
static std::chrono::steady_clock::time_point _last;
static std::chrono::steady_clock::time_point _fixedLast;
static std::chrono::milliseconds _interval;
};
// 输入设备
class Input
{

View File

@ -404,6 +404,34 @@ protected:
};
// 时间段
class Duration
{
public:
Duration();
Duration operator + (Duration const & size) const;
Duration operator - (Duration const & size) const;
protected:
std::chrono::milliseconds _duration;
};
// 时间点
class Time
{
public:
Time();
Time operator + (Duration const & size) const;
Duration operator - (Time const & size) const;
protected:
std::chrono::steady_clock::time_point _time;
};
// ×ÖÌå
class Font
{

View File

@ -55,11 +55,11 @@
<ClCompile Include="..\..\core\Base\GC.cpp" />
<ClCompile Include="..\..\core\Base\Input.cpp" />
<ClCompile Include="..\..\core\Base\Renderer.cpp" />
<ClCompile Include="..\..\core\Base\Time.cpp" />
<ClCompile Include="..\..\core\Base\Window.cpp" />
<ClCompile Include="..\..\core\Common\Collider.cpp" />
<ClCompile Include="..\..\core\Common\Color.cpp" />
<ClCompile Include="..\..\core\Common\Config.cpp" />
<ClCompile Include="..\..\core\Common\Duration.cpp" />
<ClCompile Include="..\..\core\Common\Font.cpp" />
<ClCompile Include="..\..\core\Common\Function.cpp" />
<ClCompile Include="..\..\core\Common\Image.cpp" />
@ -70,6 +70,7 @@
<ClCompile Include="..\..\core\Common\Scene.cpp" />
<ClCompile Include="..\..\core\Common\Size.cpp" />
<ClCompile Include="..\..\core\Common\String.cpp" />
<ClCompile Include="..\..\core\Common\Time.cpp" />
<ClCompile Include="..\..\core\Custom\Exception.cpp" />
<ClCompile Include="..\..\core\Custom\SystemException.cpp" />
<ClCompile Include="..\..\core\Custom\TextRenderer.cpp" />

View File

@ -115,9 +115,6 @@
<ClCompile Include="..\..\core\Base\Renderer.cpp">
<Filter>Base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Base\Time.cpp">
<Filter>Base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Base\Window.cpp">
<Filter>Base</Filter>
</ClCompile>

View File

@ -199,11 +199,11 @@
<ClCompile Include="..\..\core\Base\GC.cpp" />
<ClCompile Include="..\..\core\Base\Input.cpp" />
<ClCompile Include="..\..\core\Base\Renderer.cpp" />
<ClCompile Include="..\..\core\Base\Time.cpp" />
<ClCompile Include="..\..\core\Base\Window.cpp" />
<ClCompile Include="..\..\core\Common\Collider.cpp" />
<ClCompile Include="..\..\core\Common\Color.cpp" />
<ClCompile Include="..\..\core\Common\Config.cpp" />
<ClCompile Include="..\..\core\Common\Duration.cpp" />
<ClCompile Include="..\..\core\Common\Font.cpp" />
<ClCompile Include="..\..\core\Common\Function.cpp" />
<ClCompile Include="..\..\core\Common\Image.cpp" />
@ -214,6 +214,7 @@
<ClCompile Include="..\..\core\Common\Scene.cpp" />
<ClCompile Include="..\..\core\Common\Size.cpp" />
<ClCompile Include="..\..\core\Common\String.cpp" />
<ClCompile Include="..\..\core\Common\Time.cpp" />
<ClCompile Include="..\..\core\Custom\Exception.cpp" />
<ClCompile Include="..\..\core\Custom\SystemException.cpp" />
<ClCompile Include="..\..\core\Custom\TextRenderer.cpp" />

View File

@ -115,9 +115,6 @@
<ClCompile Include="..\..\core\Base\Renderer.cpp">
<Filter>Base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Base\Time.cpp">
<Filter>Base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Base\Window.cpp">
<Filter>Base</Filter>
</ClCompile>

View File

@ -219,11 +219,11 @@
<ClCompile Include="..\..\core\Base\GC.cpp" />
<ClCompile Include="..\..\core\Base\Input.cpp" />
<ClCompile Include="..\..\core\Base\Renderer.cpp" />
<ClCompile Include="..\..\core\Base\Time.cpp" />
<ClCompile Include="..\..\core\Base\Window.cpp" />
<ClCompile Include="..\..\core\Common\Collider.cpp" />
<ClCompile Include="..\..\core\Common\Color.cpp" />
<ClCompile Include="..\..\core\Common\Config.cpp" />
<ClCompile Include="..\..\core\Common\Duration.cpp" />
<ClCompile Include="..\..\core\Common\Font.cpp" />
<ClCompile Include="..\..\core\Common\Function.cpp" />
<ClCompile Include="..\..\core\Common\Point.cpp" />
@ -234,6 +234,7 @@
<ClCompile Include="..\..\core\Common\Size.cpp" />
<ClCompile Include="..\..\core\Common\String.cpp" />
<ClCompile Include="..\..\core\Common\Image.cpp" />
<ClCompile Include="..\..\core\Common\Time.cpp" />
<ClCompile Include="..\..\core\Custom\Exception.cpp" />
<ClCompile Include="..\..\core\Custom\SystemException.cpp" />
<ClCompile Include="..\..\core\Custom\TextRenderer.cpp" />

View File

@ -78,9 +78,6 @@
<ClCompile Include="..\..\core\Manager\SceneManager.cpp">
<Filter>Manager</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Base\Time.cpp">
<Filter>Base</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Base\Renderer.cpp">
<Filter>Base</Filter>
</ClCompile>
@ -249,6 +246,12 @@
<ClCompile Include="..\..\core\Event\Collision.cpp">
<Filter>Event</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Common\Time.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="..\..\core\Common\Duration.cpp">
<Filter>Common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\core\easy2d.h" />