计时功能优化
This commit is contained in:
		
							parent
							
								
									d1ad592df7
								
							
						
					
					
						commit
						c7115a1162
					
				|  | @ -6,7 +6,6 @@ e2d::Action::Action() | ||||||
| 	, _done(false) | 	, _done(false) | ||||||
| 	, _initialized(false) | 	, _initialized(false) | ||||||
| 	, _target(nullptr) | 	, _target(nullptr) | ||||||
| 	, _last(0) |  | ||||||
| { | { | ||||||
| 	ActionManager::getInstance()->__add(this); | 	ActionManager::getInstance()->__add(this); | ||||||
| } | } | ||||||
|  | @ -24,7 +23,6 @@ bool e2d::Action::isRunning() | ||||||
| void e2d::Action::resume() | void e2d::Action::resume() | ||||||
| { | { | ||||||
| 	_running = true; | 	_running = true; | ||||||
| 	_last = Game::getInstance()->getTotalDuration().seconds(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Action::pause() | void e2d::Action::pause() | ||||||
|  | @ -56,7 +54,7 @@ void e2d::Action::reset() | ||||||
| { | { | ||||||
| 	_initialized = false; | 	_initialized = false; | ||||||
| 	_done = false; | 	_done = false; | ||||||
| 	_last = Game::getInstance()->getTotalDuration().seconds(); | 	_started = Time::now(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool e2d::Action::_isDone() | bool e2d::Action::_isDone() | ||||||
|  | @ -74,7 +72,7 @@ void e2d::Action::_startWithTarget(Node* target) | ||||||
| void e2d::Action::_init() | void e2d::Action::_init() | ||||||
| { | { | ||||||
| 	_initialized = true; | 	_initialized = true; | ||||||
| 	_last = Game::getInstance()->getTotalDuration().seconds(); | 	_started = Time::now(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Action::_update() | void e2d::Action::_update() | ||||||
|  |  | ||||||
|  | @ -56,8 +56,7 @@ void e2d::Animate::_update() | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	auto game = Game::getInstance(); | 	while ((Time::now() - _started).seconds() >= _animation->getInterval()) | ||||||
| 	while ((game->getTotalDuration().seconds() - _last) >= _animation->getInterval()) |  | ||||||
| 	{ | 	{ | ||||||
| 		auto& frames = _animation->getFrames(); | 		auto& frames = _animation->getFrames(); | ||||||
| 		auto target = dynamic_cast<Sprite*>(_target); | 		auto target = dynamic_cast<Sprite*>(_target); | ||||||
|  | @ -67,7 +66,7 @@ void e2d::Animate::_update() | ||||||
| 			target->open(frames[_frameIndex]); | 			target->open(frames[_frameIndex]); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		_last += _animation->getInterval(); | 		_started += Duration(_animation->getInterval()); | ||||||
| 		++_frameIndex; | 		++_frameIndex; | ||||||
| 
 | 
 | ||||||
| 		if (_frameIndex == frames.size()) | 		if (_frameIndex == frames.size()) | ||||||
|  | @ -81,7 +80,6 @@ void e2d::Animate::_update() | ||||||
| void e2d::Animate::_resetTime() | void e2d::Animate::_resetTime() | ||||||
| { | { | ||||||
| 	Action::_resetTime(); | 	Action::_resetTime(); | ||||||
| 	_last = Game::getInstance()->getTotalDuration().seconds(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Animate::reset() | void e2d::Animate::reset() | ||||||
|  |  | ||||||
|  | @ -31,7 +31,7 @@ void e2d::Delay::_update() | ||||||
| { | { | ||||||
| 	Action::_update(); | 	Action::_update(); | ||||||
| 
 | 
 | ||||||
| 	_delta = Game::getInstance()->getTotalDuration().seconds() - _last; | 	_delta = (Time::now() - _started).seconds(); | ||||||
| 
 | 
 | ||||||
| 	if (_delta >= _delay) | 	if (_delta >= _delay) | ||||||
| 	{ | 	{ | ||||||
|  | @ -42,5 +42,5 @@ void e2d::Delay::_update() | ||||||
| void e2d::Delay::_resetTime() | void e2d::Delay::_resetTime() | ||||||
| { | { | ||||||
| 	Action::_resetTime(); | 	Action::_resetTime(); | ||||||
| 	_last = Game::getInstance()->getTotalDuration().seconds() - _delta; | 	_started = Time::now() - Duration(_delta); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ void e2d::FiniteTimeAction::_update() | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		_delta = std::min((Game::getInstance()->getTotalDuration().seconds() - _last) / _duration, 1.f); | 		_delta = std::min((Time::now() - _started).seconds() / _duration, 1.f); | ||||||
| 
 | 
 | ||||||
| 		if (_delta >= 1) | 		if (_delta >= 1) | ||||||
| 		{ | 		{ | ||||||
|  | @ -40,5 +40,5 @@ void e2d::FiniteTimeAction::_update() | ||||||
| void e2d::FiniteTimeAction::_resetTime() | void e2d::FiniteTimeAction::_resetTime() | ||||||
| { | { | ||||||
| 	Action::_resetTime(); | 	Action::_resetTime(); | ||||||
| 	_last = Game::getInstance()->getTotalDuration().seconds() - _delta * _duration; | 	_started = Time::now() - Duration(_delta * _duration); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -12,8 +12,6 @@ e2d::Game::Game() | ||||||
| 	, _config() | 	, _config() | ||||||
| { | { | ||||||
| 	CoInitialize(nullptr); | 	CoInitialize(nullptr); | ||||||
| 
 |  | ||||||
| 	_start = _last = _now = Time::now(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Game::~Game() | e2d::Game::~Game() | ||||||
|  | @ -39,26 +37,25 @@ void e2d::Game::destroyInstance() | ||||||
| 
 | 
 | ||||||
| void e2d::Game::start() | void e2d::Game::start() | ||||||
| { | { | ||||||
| 	SceneManager::getInstance()->update(); | 	_quit = false; | ||||||
| 
 | 
 | ||||||
|  | 	const int minInterval = 5; | ||||||
|  | 	Time last = Time::now(); | ||||||
| 	HWND hWnd = Window::getInstance()->getHWnd(); | 	HWND hWnd = Window::getInstance()->getHWnd(); | ||||||
|  | 	 | ||||||
| 	::ShowWindow(hWnd, SW_SHOWNORMAL); | 	::ShowWindow(hWnd, SW_SHOWNORMAL); | ||||||
| 	::UpdateWindow(hWnd); | 	::UpdateWindow(hWnd); | ||||||
| 	Window::getInstance()->poll(); | 	Window::getInstance()->poll(); | ||||||
| 
 | 	SceneManager::getInstance()->update(); | ||||||
| 	_quit = false; |  | ||||||
| 	_last = _now = Time::now(); |  | ||||||
| 
 |  | ||||||
| 	const Duration minInterval(15); |  | ||||||
| 	 | 	 | ||||||
| 	while (!_quit) | 	while (!_quit) | ||||||
| 	{ | 	{ | ||||||
| 		_now = Time::now(); | 		auto now = Time::now(); | ||||||
| 		Duration interval = _now - _last; | 		auto dur = now - last; | ||||||
| 
 | 
 | ||||||
| 		if (minInterval < interval) | 		if (dur.milliseconds() > minInterval) | ||||||
| 		{ | 		{ | ||||||
| 			_last = _now; | 			last = now; | ||||||
| 			Input::getInstance()->update(); | 			Input::getInstance()->update(); | ||||||
| 			Timer::getInstance()->update(); | 			Timer::getInstance()->update(); | ||||||
| 			ActionManager::getInstance()->update(); | 			ActionManager::getInstance()->update(); | ||||||
|  | @ -72,7 +69,7 @@ void e2d::Game::start() | ||||||
| 			// ID2D1HwndRenderTarget 在渲染时会等待显示器刷新,即开启了垂直同步,
 | 			// ID2D1HwndRenderTarget 在渲染时会等待显示器刷新,即开启了垂直同步,
 | ||||||
| 			// 它起到了非常稳定的延时作用,所以大部分时候不需要手动挂起线程进行延时。
 | 			// 它起到了非常稳定的延时作用,所以大部分时候不需要手动挂起线程进行延时。
 | ||||||
| 			// 下面的代码仅在一些情况下(例如窗口最小化时)挂起线程,防止占用过高 CPU 。
 | 			// 下面的代码仅在一些情况下(例如窗口最小化时)挂起线程,防止占用过高 CPU 。
 | ||||||
| 			int wait = (minInterval - interval).milliseconds(); | 			int wait = minInterval - dur.milliseconds(); | ||||||
| 			if (wait > 1) | 			if (wait > 1) | ||||||
| 			{ | 			{ | ||||||
| 				std::this_thread::sleep_for(std::chrono::milliseconds(wait)); | 				std::this_thread::sleep_for(std::chrono::milliseconds(wait)); | ||||||
|  | @ -90,7 +87,6 @@ void e2d::Game::resume() | ||||||
| { | { | ||||||
| 	if (_paused && !_quit) | 	if (_paused && !_quit) | ||||||
| 	{ | 	{ | ||||||
| 		_last = _now = Time::now(); |  | ||||||
| 		Timer::getInstance()->updateTime(); | 		Timer::getInstance()->updateTime(); | ||||||
| 		ActionManager::getInstance()->updateTime(); | 		ActionManager::getInstance()->updateTime(); | ||||||
| 	} | 	} | ||||||
|  | @ -120,11 +116,6 @@ const e2d::Config& e2d::Game::getConfig() | ||||||
| 	return _config; | 	return _config; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Duration e2d::Game::getTotalDuration() const |  | ||||||
| { |  | ||||||
| 	return std::move(_now - _start); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void e2d::Game::quit() | void e2d::Game::quit() | ||||||
| { | { | ||||||
| 	_quit = true; | 	_quit = true; | ||||||
|  |  | ||||||
|  | @ -107,15 +107,14 @@ void e2d::Renderer::render() | ||||||
| 
 | 
 | ||||||
| void e2d::Renderer::_renderFps() | void e2d::Renderer::_renderFps() | ||||||
| { | { | ||||||
| 	++_renderTimes; | 	int duration = (Time::now() - _lastRenderTime).milliseconds(); | ||||||
| 
 | 
 | ||||||
| 	auto& now = Time::now(); | 	++_renderTimes; | ||||||
| 	int duration = (now - _lastRenderTime).milliseconds(); |  | ||||||
| 	if (duration >= 100) | 	if (duration >= 100) | ||||||
| 	{ | 	{ | ||||||
| 		String fpsText	= String::format(L"FPS: %.1f", (1000.f / duration * _renderTimes)); | 		String fpsText	= String::format(L"FPS: %.1f", (1000.f / duration * _renderTimes)); | ||||||
|  | 		_lastRenderTime = Time::now(); | ||||||
| 		_renderTimes	= 0; | 		_renderTimes	= 0; | ||||||
| 		_lastRenderTime = now; |  | ||||||
| 
 | 
 | ||||||
| 		auto writeFactory = Renderer::getWriteFactory(); | 		auto writeFactory = Renderer::getWriteFactory(); | ||||||
| 		if (!_fpsFormat) | 		if (!_fpsFormat) | ||||||
|  |  | ||||||
|  | @ -3,6 +3,9 @@ | ||||||
| #include <imm.h> | #include <imm.h> | ||||||
| #pragma comment (lib ,"imm32.lib") | #pragma comment (lib ,"imm32.lib") | ||||||
| 
 | 
 | ||||||
|  | #define WINDOW_STYLE	WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME | ||||||
|  | #define REGISTER_CLASS	L"Easy2DApp" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| e2d::Window * e2d::Window::_instance = nullptr; | e2d::Window * e2d::Window::_instance = nullptr; | ||||||
| 
 | 
 | ||||||
|  | @ -51,9 +54,7 @@ bool e2d::Window::createMutex(const String & mutex) | ||||||
| 	if (mutex.isEmpty()) | 	if (mutex.isEmpty()) | ||||||
| 		return false; | 		return false; | ||||||
| 
 | 
 | ||||||
| 	// 创建进程互斥体
 | 	HANDLE hMutex = ::CreateMutex(nullptr, TRUE, LPCWSTR(L"Easy2DApp-" + mutex)); | ||||||
| 	String fullMutexName = L"Easy2DApp-" + mutex; |  | ||||||
| 	HANDLE hMutex = ::CreateMutex(nullptr, TRUE, (LPCWSTR)fullMutexName); |  | ||||||
| 
 | 
 | ||||||
| 	if (hMutex == nullptr) | 	if (hMutex == nullptr) | ||||||
| 	{ | 	{ | ||||||
|  | @ -68,7 +69,7 @@ bool e2d::Window::createMutex(const String & mutex) | ||||||
| 		if (!this->_title.isEmpty()) | 		if (!this->_title.isEmpty()) | ||||||
| 		{ | 		{ | ||||||
| 			// 获取窗口句柄
 | 			// 获取窗口句柄
 | ||||||
| 			HWND hProgramWnd = ::FindWindow(L"Easy2DApp", (LPCTSTR)this->_title); | 			HWND hProgramWnd = ::FindWindow(REGISTER_CLASS, (LPCTSTR)_title); | ||||||
| 			if (hProgramWnd) | 			if (hProgramWnd) | ||||||
| 			{ | 			{ | ||||||
| 				// 获取窗口显示状态
 | 				// 获取窗口显示状态
 | ||||||
|  | @ -85,14 +86,14 @@ bool e2d::Window::createMutex(const String & mutex) | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HWND e2d::Window::__create() | HWND e2d::Window::__registerWindow() | ||||||
| { | { | ||||||
| 	// 注册窗口类
 |  | ||||||
| 	WNDCLASSEX wcex = { 0 }; | 	WNDCLASSEX wcex = { 0 }; | ||||||
| 	wcex.cbSize			= sizeof(WNDCLASSEX); | 	wcex.cbSize			= sizeof(WNDCLASSEX); | ||||||
| 	wcex.lpszClassName = L"Easy2DApp"; | 	wcex.lpszClassName	= REGISTER_CLASS; | ||||||
| 	wcex.style			= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; | 	wcex.style			= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; | ||||||
| 	wcex.lpfnWndProc	= Window::WndProc; | 	wcex.lpfnWndProc	= Window::WndProc; | ||||||
|  | 	wcex.hIcon			= nullptr; | ||||||
| 	wcex.cbClsExtra		= 0; | 	wcex.cbClsExtra		= 0; | ||||||
| 	wcex.cbWndExtra		= sizeof(LONG_PTR); | 	wcex.cbWndExtra		= sizeof(LONG_PTR); | ||||||
| 	wcex.hInstance		= HINST_THISCOMPONENT; | 	wcex.hInstance		= HINST_THISCOMPONENT; | ||||||
|  | @ -100,64 +101,44 @@ HWND e2d::Window::__create() | ||||||
| 	wcex.lpszMenuName	= nullptr; | 	wcex.lpszMenuName	= nullptr; | ||||||
| 	wcex.hCursor		= ::LoadCursor(nullptr, IDC_ARROW); | 	wcex.hCursor		= ::LoadCursor(nullptr, IDC_ARROW); | ||||||
| 
 | 
 | ||||||
| 	if (this->_iconID != 0) | 	if (_iconID != 0) | ||||||
| 	{ | 	{ | ||||||
| 		wcex.hIcon = (HICON)::LoadImage( | 		wcex.hIcon = (HICON)::LoadImage( | ||||||
| 			HINST_THISCOMPONENT, | 			HINST_THISCOMPONENT, | ||||||
| 			MAKEINTRESOURCE(this->_iconID), | 			MAKEINTRESOURCE(_iconID), | ||||||
| 			IMAGE_ICON, | 			IMAGE_ICON, | ||||||
| 			0, | 			0, | ||||||
| 			0, | 			0, | ||||||
| 			LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | 			LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		wcex.hIcon = nullptr; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	// 注册窗口类
 | ||||||
| 	RegisterClassEx(&wcex); | 	RegisterClassEx(&wcex); | ||||||
| 
 | 
 | ||||||
| 	// 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它
 |  | ||||||
| 	// 适应窗口缩放
 |  | ||||||
| 	float dpiScaleX = 0.f, dpiScaleY = 0.f; |  | ||||||
| 	Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); |  | ||||||
| 
 |  | ||||||
| 	int nWidth = static_cast<int>(ceil(_size.width * dpiScaleX / 96.f)); |  | ||||||
| 	int nHeight = static_cast<int>(ceil(_size.height * dpiScaleY / 96.f)); |  | ||||||
| 
 |  | ||||||
| 	// 计算窗口大小
 | 	// 计算窗口大小
 | ||||||
| 	DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME; | 	Rect wRect = __adjustWindow(int(_size.width), int(_size.height)); | ||||||
| 	RECT wr = { 0, 0, static_cast<LONG>(nWidth), static_cast<LONG>(nHeight) }; |  | ||||||
| 	::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL); |  | ||||||
| 	// 获取新的宽高
 |  | ||||||
| 	nWidth = static_cast<int>(wr.right - wr.left); |  | ||||||
| 	nHeight = static_cast<int>(wr.bottom - wr.top); |  | ||||||
| 
 |  | ||||||
| 	// 获取屏幕分辨率
 |  | ||||||
| 	int screenWidth = ::GetSystemMetrics(SM_CXSCREEN); |  | ||||||
| 	int screenHeight = ::GetSystemMetrics(SM_CYSCREEN); |  | ||||||
| 
 | 
 | ||||||
| 	// 创建窗口
 | 	// 创建窗口
 | ||||||
| 	HWND hWnd = ::CreateWindowEx( | 	HWND hWnd = ::CreateWindowEx( | ||||||
| 		NULL, | 		NULL, | ||||||
| 		L"Easy2DApp", | 		REGISTER_CLASS, | ||||||
| 		(LPCTSTR)_title, | 		(LPCTSTR)_title, | ||||||
| 		dwStyle, | 		WINDOW_STYLE, | ||||||
| 		(screenWidth - nWidth) / 2, (screenHeight - nHeight) / 2, | 		int(wRect.origin.x), | ||||||
| 		nWidth, nHeight, | 		int(wRect.origin.y), | ||||||
|  | 		int(wRect.size.width), | ||||||
|  | 		int(wRect.size.height), | ||||||
| 		nullptr, | 		nullptr, | ||||||
| 		nullptr, | 		nullptr, | ||||||
| 		HINST_THISCOMPONENT, | 		HINST_THISCOMPONENT, | ||||||
| 		nullptr | 		nullptr | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	HRESULT hr = hWnd ? S_OK : E_FAIL; | 	if (hWnd) | ||||||
| 
 |  | ||||||
| 	if (SUCCEEDED(hr)) |  | ||||||
| 	{ | 	{ | ||||||
| 		// 禁用输入法
 | 		// 禁用输入法
 | ||||||
| 		this->setTypewritingEnabled(false); | 		setTypewritingEnabled(false); | ||||||
| 		// 禁用控制台关闭按钮
 | 		// 禁用控制台关闭按钮
 | ||||||
| 		HWND consoleHWnd = ::GetConsoleWindow(); | 		HWND consoleHWnd = ::GetConsoleWindow(); | ||||||
| 		if (consoleHWnd) | 		if (consoleHWnd) | ||||||
|  | @ -170,11 +151,35 @@ HWND e2d::Window::__create() | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		::UnregisterClass(L"Easy2DApp", HINST_THISCOMPONENT); | 		::UnregisterClass(REGISTER_CLASS, HINST_THISCOMPONENT); | ||||||
| 	} | 	} | ||||||
| 	return hWnd; | 	return hWnd; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | e2d::Rect e2d::Window::__adjustWindow(int width, int height) | ||||||
|  | { | ||||||
|  | 	float dpiScaleX = 0.f, dpiScaleY = 0.f; | ||||||
|  | 	Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); | ||||||
|  | 
 | ||||||
|  | 	Rect result; | ||||||
|  | 	RECT wRECT		= { 0, 0, LONG(ceil(width * dpiScaleX / 96.f)), LONG(ceil(height * dpiScaleY / 96.f)) }; | ||||||
|  | 	int maxWidth	= ::GetSystemMetrics(SM_CXSCREEN); | ||||||
|  | 	int maxHeight	= ::GetSystemMetrics(SM_CYSCREEN); | ||||||
|  | 
 | ||||||
|  | 	// 计算合适的窗口大小
 | ||||||
|  | 	::AdjustWindowRectEx(&wRECT, WINDOW_STYLE, FALSE, NULL); | ||||||
|  | 	width = static_cast<int>(wRECT.right - wRECT.left); | ||||||
|  | 	height = static_cast<int>(wRECT.bottom - wRECT.top); | ||||||
|  | 
 | ||||||
|  | 	// 当输入的窗口大小比分辨率大时,给出警告
 | ||||||
|  | 	WARN_IF(maxWidth < width || maxHeight < height, "The window is larger than screen!"); | ||||||
|  | 	width = std::min(width, maxWidth); | ||||||
|  | 	height = std::min(height, maxHeight); | ||||||
|  | 
 | ||||||
|  | 	float x = float((maxWidth - width) / 2), y = float((maxHeight - height) / 2); | ||||||
|  | 	return std::move(Rect(x, y, float(width), float(height))); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void e2d::Window::poll() | void e2d::Window::poll() | ||||||
| { | { | ||||||
| 	while (::PeekMessage(&_msg, nullptr, 0, 0, PM_REMOVE)) | 	while (::PeekMessage(&_msg, nullptr, 0, 0, PM_REMOVE)) | ||||||
|  | @ -213,7 +218,7 @@ HWND e2d::Window::getHWnd() | ||||||
| { | { | ||||||
| 	if (!_hWnd) | 	if (!_hWnd) | ||||||
| 	{ | 	{ | ||||||
| 		_hWnd = this->__create(); | 		_hWnd = __registerWindow(); | ||||||
| 		if (_hWnd == nullptr) | 		if (_hWnd == nullptr) | ||||||
| 		{ | 		{ | ||||||
| 			throw SystemException(L"注册窗口失败"); | 			throw SystemException(L"注册窗口失败"); | ||||||
|  | @ -224,37 +229,24 @@ HWND e2d::Window::getHWnd() | ||||||
| 
 | 
 | ||||||
| void e2d::Window::setSize(int width, int height) | void e2d::Window::setSize(int width, int height) | ||||||
| { | { | ||||||
| 	this->_size = Size(static_cast<float>(width), static_cast<float>(height)); | 	_size = Size(static_cast<float>(width), static_cast<float>(height)); | ||||||
| 	if (_hWnd) | 	if (_hWnd) | ||||||
| 	{ | 	{ | ||||||
| 		float dpiScaleX = 0.f, dpiScaleY = 0.f; | 		Rect wRect = __adjustWindow(width, height); | ||||||
| 		Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); | 		::MoveWindow( | ||||||
| 
 | 			_hWnd, | ||||||
| 		width = static_cast<int>(ceil(width * dpiScaleX / 96.f)); | 			int(wRect.origin.x), | ||||||
| 		height = static_cast<int>(ceil(height * dpiScaleY / 96.f)); | 			int(wRect.origin.y), | ||||||
| 		// 计算窗口大小
 | 			int(wRect.size.width), | ||||||
| 		DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME; | 			int(wRect.size.height), | ||||||
| 		RECT wr = { 0, 0, static_cast<LONG>(width), static_cast<LONG>(height) }; | 			TRUE | ||||||
| 		::AdjustWindowRectEx(&wr, dwStyle, FALSE, NULL); | 		); | ||||||
| 		// 获取新的宽高
 |  | ||||||
| 		width = static_cast<int>(wr.right - wr.left); |  | ||||||
| 		height = static_cast<int>(wr.bottom - wr.top); |  | ||||||
| 		// 获取屏幕分辨率
 |  | ||||||
| 		int screenWidth = ::GetSystemMetrics(SM_CXSCREEN); |  | ||||||
| 		int screenHeight = ::GetSystemMetrics(SM_CYSCREEN); |  | ||||||
| 		// 当输入的窗口大小比分辨率大时,给出警告
 |  | ||||||
| 		WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!"); |  | ||||||
| 		// 取最小值
 |  | ||||||
| 		width = std::min(width, screenWidth); |  | ||||||
| 		height = std::min(height, screenHeight); |  | ||||||
| 		// 修改窗口大小,并设置窗口在屏幕居中
 |  | ||||||
| 		::MoveWindow(_hWnd, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, TRUE); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Window::setTitle(const String& title) | void e2d::Window::setTitle(const String& title) | ||||||
| { | { | ||||||
| 	this->_title = title; | 	_title = title; | ||||||
| 	if (_hWnd) | 	if (_hWnd) | ||||||
| 	{ | 	{ | ||||||
| 		::SetWindowText(_hWnd, (LPCWSTR)title); | 		::SetWindowText(_hWnd, (LPCWSTR)title); | ||||||
|  |  | ||||||
|  | @ -7,13 +7,8 @@ e2d::Duration::Duration() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Duration::Duration(int ms) | e2d::Duration::Duration(float seconds) | ||||||
| 	: _ms(ms) | 	: _ms(static_cast<long long>(seconds * 1000.f)) | ||||||
| { |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| e2d::Duration::Duration(const std::chrono::milliseconds& ms) |  | ||||||
| 	: _ms(ms) |  | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -59,12 +54,16 @@ bool e2d::Duration::operator<=(const Duration & other) const | ||||||
| 
 | 
 | ||||||
| e2d::Duration e2d::Duration::operator+(Duration const & other) const | e2d::Duration e2d::Duration::operator+(Duration const & other) const | ||||||
| { | { | ||||||
| 	return std::move(Duration(_ms + other._ms)); | 	Duration d; | ||||||
|  | 	d._ms = _ms + other._ms; | ||||||
|  | 	return std::move(d); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Duration e2d::Duration::operator-(Duration const & other) const | e2d::Duration e2d::Duration::operator-(Duration const & other) const | ||||||
| { | { | ||||||
| 	return std::move(Duration(_ms - other._ms)); | 	Duration d; | ||||||
|  | 	d._ms = _ms - other._ms; | ||||||
|  | 	return std::move(d); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Duration & e2d::Duration::operator+=(Duration const &other) | e2d::Duration & e2d::Duration::operator+=(Duration const &other) | ||||||
|  |  | ||||||
|  | @ -7,11 +7,6 @@ e2d::Time::Time() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Time::Time(const steady_clock::time_point& time) |  | ||||||
| 	: _timePoint(time) |  | ||||||
| { |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| time_t e2d::Time::getTimeStamp() const | time_t e2d::Time::getTimeStamp() const | ||||||
| { | { | ||||||
| 	auto& duration = time_point_cast<milliseconds>(_timePoint).time_since_epoch(); | 	auto& duration = time_point_cast<milliseconds>(_timePoint).time_since_epoch(); | ||||||
|  | @ -25,7 +20,16 @@ bool e2d::Time::isZero() const | ||||||
| 
 | 
 | ||||||
| e2d::Time e2d::Time::operator+(Duration const & other) const | e2d::Time e2d::Time::operator+(Duration const & other) const | ||||||
| { | { | ||||||
| 	return std::move(Time(_timePoint + milliseconds(other.milliseconds()))); | 	Time t; | ||||||
|  | 	t._timePoint = _timePoint + milliseconds(other.milliseconds()); | ||||||
|  | 	return std::move(t); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | e2d::Time e2d::Time::operator-(Duration const & other) const | ||||||
|  | { | ||||||
|  | 	Time t; | ||||||
|  | 	t._timePoint = _timePoint - milliseconds(other.milliseconds()); | ||||||
|  | 	return std::move(t); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Time & e2d::Time::operator+=(Duration const & other) | e2d::Time & e2d::Time::operator+=(Duration const & other) | ||||||
|  | @ -34,11 +38,6 @@ e2d::Time & e2d::Time::operator+=(Duration const & other) | ||||||
| 	return (*this); | 	return (*this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Time e2d::Time::operator-(Duration const & other) const |  | ||||||
| { |  | ||||||
| 	return std::move(Time(_timePoint - milliseconds(other.milliseconds()))); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| e2d::Time & e2d::Time::operator-=(Duration const &other) | e2d::Time & e2d::Time::operator-=(Duration const &other) | ||||||
| { | { | ||||||
| 	_timePoint -= milliseconds(other.milliseconds()); | 	_timePoint -= milliseconds(other.milliseconds()); | ||||||
|  | @ -47,11 +46,13 @@ e2d::Time & e2d::Time::operator-=(Duration const &other) | ||||||
| 
 | 
 | ||||||
| e2d::Duration e2d::Time::operator-(Time const & other) const | e2d::Duration e2d::Time::operator-(Time const & other) const | ||||||
| { | { | ||||||
| 	auto& ms = duration_cast<milliseconds>(_timePoint - other._timePoint); | 	auto ms = duration_cast<milliseconds>(_timePoint - other._timePoint).count(); | ||||||
| 	return std::move(Duration(ms)); | 	return std::move(Duration(static_cast<float>(ms) / 1000.f)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::Time e2d::Time::now() | e2d::Time e2d::Time::now() | ||||||
| { | { | ||||||
| 	return std::move(Time(steady_clock::now())); | 	Time t; | ||||||
|  | 	t._timePoint = steady_clock::now(); | ||||||
|  | 	return std::move(t); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,8 +22,7 @@ void e2d::SceneManager::destroyInstance() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| e2d::SceneManager::SceneManager() | e2d::SceneManager::SceneManager() | ||||||
| 	: _saveCurrScene(true) | 	: _currScene(nullptr) | ||||||
| 	, _currScene(nullptr) |  | ||||||
| 	, _nextScene(nullptr) | 	, _nextScene(nullptr) | ||||||
| 	, _transition(nullptr) | 	, _transition(nullptr) | ||||||
| 	, _scenes() | 	, _scenes() | ||||||
|  | @ -34,7 +33,7 @@ e2d::SceneManager::~SceneManager() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::SceneManager::push(Scene * scene, Transition * transition /* = nullptr */, bool saveCurrentScene /* = true */) | void e2d::SceneManager::push(Scene * scene, bool saveCurrentScene) | ||||||
| { | { | ||||||
| 	if (!scene) | 	if (!scene) | ||||||
| 		return; | 		return; | ||||||
|  | @ -44,58 +43,59 @@ void e2d::SceneManager::push(Scene * scene, Transition * transition /* = nullptr | ||||||
| 	_nextScene = scene; | 	_nextScene = scene; | ||||||
| 	_nextScene->retain(); | 	_nextScene->retain(); | ||||||
| 	 | 	 | ||||||
| 	// 设置切换场景动作
 | 	// 初始化场景切换动画
 | ||||||
| 	if (transition) | 	if (_transition && !_transition->init(_currScene, _nextScene)) | ||||||
| 	{ | 	{ | ||||||
| 		if (_transition) | 		WARN("Transition initialize failed!"); | ||||||
| 		{ |  | ||||||
| 			_transition->_stop(); |  | ||||||
| 		_transition->release(); | 		_transition->release(); | ||||||
| 		} | 		_transition = nullptr; | ||||||
| 		_transition = transition; |  | ||||||
| 		transition->retain(); |  | ||||||
| 		transition->_init(_currScene, _nextScene); |  | ||||||
| 		transition->_update(); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (_currScene) | 	if (saveCurrentScene && _currScene) | ||||||
| 	{ | 	{ | ||||||
| 		_saveCurrScene = saveCurrentScene; | 		_scenes.push(_currScene); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::SceneManager::pop(Transition * transition /* = nullptr */) | e2d::Scene* e2d::SceneManager::pop() | ||||||
| { | { | ||||||
| 	// 栈为空时,调用返回场景函数失败
 | 	// 栈为空时,调用返回场景函数失败
 | ||||||
| 	if (_scenes.size() == 0) | 	if (_scenes.size() == 0) | ||||||
| 	{ | 	{ | ||||||
| 		WARN("Scene stack is empty!"); | 		WARN("Scene stack is empty!"); | ||||||
| 		return; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// 从栈顶取出场景指针,作为下一场景
 |  | ||||||
| 	_nextScene = _scenes.top(); | 	_nextScene = _scenes.top(); | ||||||
| 	_scenes.pop(); | 	_scenes.pop(); | ||||||
| 
 | 
 | ||||||
| 	// 返回上一场景时,不保存当前场景
 | 	// 初始化场景切换动画
 | ||||||
| 	if (_currScene) | 	if (_transition && !_transition->init(_currScene, _nextScene)) | ||||||
| 	{ | 	{ | ||||||
| 		_saveCurrScene = false; | 		WARN("Transition initialize failed!"); | ||||||
|  | 		_transition->release(); | ||||||
|  | 		_transition = nullptr; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// 设置切换场景动作
 | 	return _nextScene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void e2d::SceneManager::setTransition(Transition * transition) | ||||||
|  | { | ||||||
| 	if (transition) | 	if (transition) | ||||||
| 	{ | 	{ | ||||||
| 		transition->retain(); | 		if (_transition) | ||||||
| 		transition->_init(_currScene, _nextScene); | 		{ | ||||||
| 		transition->_update(); | 			_transition->stop(); | ||||||
|  | 			_transition->release(); | ||||||
|  | 		} | ||||||
| 		_transition = transition; | 		_transition = transition; | ||||||
|  | 		_transition->retain(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::SceneManager::clear() | void e2d::SceneManager::clear() | ||||||
| { | { | ||||||
| 	// 清空场景栈
 |  | ||||||
| 	while (!_scenes.empty()) | 	while (!_scenes.empty()) | ||||||
| 	{ | 	{ | ||||||
| 		_scenes.top()->release(); | 		_scenes.top()->release(); | ||||||
|  | @ -108,7 +108,7 @@ e2d::Scene * e2d::SceneManager::getCurrentScene() | ||||||
| 	return _currScene; | 	return _currScene; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::stack<e2d::Scene*> e2d::SceneManager::getSceneStack() | const std::stack<e2d::Scene*>& e2d::SceneManager::getSceneStack() | ||||||
| { | { | ||||||
| 	return _scenes; | 	return _scenes; | ||||||
| } | } | ||||||
|  | @ -120,18 +120,12 @@ bool e2d::SceneManager::isTransitioning() | ||||||
| 
 | 
 | ||||||
| void e2d::SceneManager::update() | void e2d::SceneManager::update() | ||||||
| { | { | ||||||
| 	if (_transition == nullptr) | 	if (_currScene) _currScene->update(); | ||||||
|  | 	if (_nextScene) _nextScene->update(); | ||||||
|  | 
 | ||||||
|  | 	if (_transition) | ||||||
| 	{ | 	{ | ||||||
| 		// 更新场景内容
 | 		_transition->update(); | ||||||
| 		if (_currScene) |  | ||||||
| 		{ |  | ||||||
| 			_currScene->update(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		// 更新场景动作
 |  | ||||||
| 		_transition->_update(); |  | ||||||
| 		 | 		 | ||||||
| 		if (_transition->isDone()) | 		if (_transition->isDone()) | ||||||
| 		{ | 		{ | ||||||
|  | @ -144,26 +138,17 @@ void e2d::SceneManager::update() | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// 下一场景指针不为空时,切换场景
 |  | ||||||
| 	if (_nextScene) | 	if (_nextScene) | ||||||
| 	{ | 	{ | ||||||
| 		if (_currScene) | 		if (_currScene) | ||||||
| 		{ | 		{ | ||||||
| 			// 执行当前场景的 onExit 函数
 |  | ||||||
| 			_currScene->onExit(); | 			_currScene->onExit(); | ||||||
| 
 | 			if (_scenes.empty() || _scenes.top() != _currScene) | ||||||
| 			// 若要保存当前场景,把它放入栈中
 |  | ||||||
| 			if (_saveCurrScene) |  | ||||||
| 			{ |  | ||||||
| 				_scenes.push(_currScene); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ | 			{ | ||||||
| 				_currScene->release(); | 				_currScene->release(); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// 执行下一场景的 onEnter 函数
 |  | ||||||
| 		_nextScene->onEnter(); | 		_nextScene->onEnter(); | ||||||
| 
 | 
 | ||||||
| 		_currScene = _nextScene; | 		_currScene = _nextScene; | ||||||
|  | @ -175,16 +160,12 @@ void e2d::SceneManager::render() | ||||||
| { | { | ||||||
| 	if (_transition) | 	if (_transition) | ||||||
| 	{ | 	{ | ||||||
| 		_transition->_render(); | 		_transition->render(); | ||||||
| 	} | 	} | ||||||
| 	else | 	else if (_currScene) | ||||||
| 	{ |  | ||||||
| 		// 绘制当前场景
 |  | ||||||
| 		if (_currScene) |  | ||||||
| 	{ | 	{ | ||||||
| 		_currScene->render(); | 		_currScene->render(); | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::SceneManager::dispatch(const MouseEvent & e) | void e2d::SceneManager::dispatch(const MouseEvent & e) | ||||||
|  |  | ||||||
|  | @ -6,8 +6,7 @@ e2d::Task::Task(const Function & func, const String & name) | ||||||
| 	, _stopped(false) | 	, _stopped(false) | ||||||
| 	, _runTimes(0) | 	, _runTimes(0) | ||||||
| 	, _totalTimes(-1) | 	, _totalTimes(-1) | ||||||
| 	, _delay(0.f) | 	, _delay() | ||||||
| 	, _lastTime(0.f) |  | ||||||
| 	, _callback(func) | 	, _callback(func) | ||||||
| 	, _name(name) | 	, _name(name) | ||||||
| { | { | ||||||
|  | @ -17,9 +16,8 @@ e2d::Task::Task(const Function & func, float delay, int times, const String & na | ||||||
| 	: _running(true) | 	: _running(true) | ||||||
| 	, _stopped(false) | 	, _stopped(false) | ||||||
| 	, _runTimes(0) | 	, _runTimes(0) | ||||||
| 	, _totalTimes(times) |  | ||||||
| 	, _delay(std::max(delay, 0.f)) | 	, _delay(std::max(delay, 0.f)) | ||||||
| 	, _lastTime(0.f) | 	, _totalTimes(times) | ||||||
| 	, _callback(func) | 	, _callback(func) | ||||||
| 	, _name(name) | 	, _name(name) | ||||||
| { | { | ||||||
|  | @ -38,17 +36,24 @@ void e2d::Task::resume() | ||||||
| 
 | 
 | ||||||
| void e2d::Task::update() | void e2d::Task::update() | ||||||
| { | { | ||||||
| 	if (_callback) | 	if (_totalTimes == 0) | ||||||
| 	{ | 	{ | ||||||
| 		_callback(); | 		_stopped = true; | ||||||
|  | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	++_runTimes; | 	++_runTimes; | ||||||
| 	_lastTime += _delay; | 	_lastTime += _delay; | ||||||
| 
 | 
 | ||||||
|  | 	if (_callback) | ||||||
|  | 	{ | ||||||
|  | 		_callback(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (_runTimes == _totalTimes) | 	if (_runTimes == _totalTimes) | ||||||
| 	{ | 	{ | ||||||
| 		_stopped = true; | 		_stopped = true; | ||||||
|  | 		return; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -56,11 +61,11 @@ bool e2d::Task::isReady() const | ||||||
| { | { | ||||||
| 	if (_running) | 	if (_running) | ||||||
| 	{ | 	{ | ||||||
| 		if (_delay == 0) | 		if (_delay.milliseconds() == 0) | ||||||
| 		{ | 		{ | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 		if ((Game::getInstance()->getTotalDuration().seconds() - _lastTime) >= _delay) | 		if (Time::now() - _lastTime >= _delay) | ||||||
| 		{ | 		{ | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
|  | @ -80,5 +85,5 @@ e2d::String e2d::Task::getName() const | ||||||
| 
 | 
 | ||||||
| void e2d::Task::updateTime() | void e2d::Task::updateTime() | ||||||
| { | { | ||||||
| 	_lastTime = Game::getInstance()->getTotalDuration().seconds(); | 	_lastTime = Time::now(); | ||||||
| } | } | ||||||
|  | @ -6,14 +6,20 @@ e2d::BoxTransition::BoxTransition(float duration) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::BoxTransition::_init(Scene * prev, Scene * next) | bool e2d::BoxTransition::init(Scene * prev, Scene * next) | ||||||
| { | { | ||||||
| 	Transition::_init(prev, next); | 	if (Transition::init(prev, next)) | ||||||
|  | 	{ | ||||||
| 		_inLayerParam.opacity = 0; | 		_inLayerParam.opacity = 0; | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::BoxTransition::_updateCustom() | void e2d::BoxTransition::update() | ||||||
| { | { | ||||||
|  | 	Transition::update(); | ||||||
|  | 
 | ||||||
| 	if (_delta <= 0.5) | 	if (_delta <= 0.5) | ||||||
| 	{ | 	{ | ||||||
| 		_outLayerParam.contentBounds = D2D1::RectF( | 		_outLayerParam.contentBounds = D2D1::RectF( | ||||||
|  | @ -35,11 +41,11 @@ void e2d::BoxTransition::_updateCustom() | ||||||
| 		); | 		); | ||||||
| 		if (_delta >= 1) | 		if (_delta >= 1) | ||||||
| 		{ | 		{ | ||||||
| 			this->_stop(); | 			this->stop(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::BoxTransition::_reset() | void e2d::BoxTransition::reset() | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -6,24 +6,30 @@ e2d::EmergeTransition::EmergeTransition(float duration) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::EmergeTransition::_init(Scene * prev, Scene * next) | bool e2d::EmergeTransition::init(Scene * prev, Scene * next) | ||||||
| { | { | ||||||
| 	Transition::_init(prev, next); | 	if (Transition::init(prev, next)) | ||||||
|  | 	{ | ||||||
| 		_outLayerParam.opacity = 1; | 		_outLayerParam.opacity = 1; | ||||||
| 		_inLayerParam.opacity = 0; | 		_inLayerParam.opacity = 0; | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::EmergeTransition::_updateCustom() | void e2d::EmergeTransition::update() | ||||||
| { | { | ||||||
|  | 	Transition::update(); | ||||||
|  | 
 | ||||||
| 	_outLayerParam.opacity = 1 - _delta; | 	_outLayerParam.opacity = 1 - _delta; | ||||||
| 	_inLayerParam.opacity = _delta; | 	_inLayerParam.opacity = _delta; | ||||||
| 
 | 
 | ||||||
| 	if (_delta >= 1) | 	if (_delta >= 1) | ||||||
| 	{ | 	{ | ||||||
| 		this->_stop(); | 		this->stop(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::EmergeTransition::_reset() | void e2d::EmergeTransition::reset() | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -6,15 +6,21 @@ e2d::FadeTransition::FadeTransition(float duration) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::FadeTransition::_init(Scene * prev, Scene * next) | bool e2d::FadeTransition::init(Scene * prev, Scene * next) | ||||||
| { | { | ||||||
| 	Transition::_init(prev, next); | 	if (Transition::init(prev, next)) | ||||||
|  | 	{ | ||||||
| 		_outLayerParam.opacity = 1; | 		_outLayerParam.opacity = 1; | ||||||
| 		_inLayerParam.opacity = 0; | 		_inLayerParam.opacity = 0; | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::FadeTransition::_updateCustom() | void e2d::FadeTransition::update() | ||||||
| { | { | ||||||
|  | 	Transition::update(); | ||||||
|  | 
 | ||||||
| 	if (_delta < 0.5) | 	if (_delta < 0.5) | ||||||
| 	{ | 	{ | ||||||
| 		_outLayerParam.opacity = 1 - _delta * 2; | 		_outLayerParam.opacity = 1 - _delta * 2; | ||||||
|  | @ -26,11 +32,11 @@ void e2d::FadeTransition::_updateCustom() | ||||||
| 		_inLayerParam.opacity = (_delta - 0.5f) * 2; | 		_inLayerParam.opacity = (_delta - 0.5f) * 2; | ||||||
| 		if (_delta >= 1) | 		if (_delta >= 1) | ||||||
| 		{ | 		{ | ||||||
| 			this->_stop(); | 			this->stop(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::FadeTransition::_reset() | void e2d::FadeTransition::reset() | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -7,10 +7,10 @@ e2d::MoveTransition::MoveTransition(float duration, Direction direction) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::MoveTransition::_init(Scene * prev, Scene * next) | bool e2d::MoveTransition::init(Scene * prev, Scene * next) | ||||||
| { | { | ||||||
| 	Transition::_init(prev, next); | 	if (Transition::init(prev, next)) | ||||||
| 
 | 	{ | ||||||
| 		float width = _windowSize.width; | 		float width = _windowSize.width; | ||||||
| 		float height = _windowSize.height; | 		float height = _windowSize.height; | ||||||
| 		if (_direction == Direction::Up) | 		if (_direction == Direction::Up) | ||||||
|  | @ -36,10 +36,15 @@ void e2d::MoveTransition::_init(Scene * prev, Scene * next) | ||||||
| 
 | 
 | ||||||
| 		if (_outScene) _outScene->getRoot()->setPos(0, 0); | 		if (_outScene) _outScene->getRoot()->setPos(0, 0); | ||||||
| 		_inScene->getRoot()->setPos(_startPos); | 		_inScene->getRoot()->setPos(_startPos); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::MoveTransition::_updateCustom() | void e2d::MoveTransition::update() | ||||||
| { | { | ||||||
|  | 	Transition::update(); | ||||||
|  | 
 | ||||||
| 	if (_outScene) | 	if (_outScene) | ||||||
| 	{ | 	{ | ||||||
| 		_outScene->getRoot()->setPos(_posDelta * _delta); | 		_outScene->getRoot()->setPos(_posDelta * _delta); | ||||||
|  | @ -51,11 +56,11 @@ void e2d::MoveTransition::_updateCustom() | ||||||
| 
 | 
 | ||||||
| 	if (_delta >= 1) | 	if (_delta >= 1) | ||||||
| 	{ | 	{ | ||||||
| 		this->_stop(); | 		this->stop(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::MoveTransition::_reset() | void e2d::MoveTransition::reset() | ||||||
| { | { | ||||||
| 	if (_outScene) _outScene->getRoot()->setPos(0, 0); | 	if (_outScene) _outScene->getRoot()->setPos(0, 0); | ||||||
| 	_inScene->getRoot()->setPos(0, 0); | 	_inScene->getRoot()->setPos(0, 0); | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| e2d::Transition::Transition(float duration) | e2d::Transition::Transition(float duration) | ||||||
| 	: _end(false) | 	: _end(false) | ||||||
| 	, _last() | 	, _started() | ||||||
| 	, _delta(0) | 	, _delta(0) | ||||||
| 	, _outScene(nullptr) | 	, _outScene(nullptr) | ||||||
| 	, _inScene(nullptr) | 	, _inScene(nullptr) | ||||||
|  | @ -29,7 +29,7 @@ bool e2d::Transition::isDone() | ||||||
| 	return _end; | 	return _end; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Transition::_init(Scene * prev, Scene * next) | bool e2d::Transition::init(Scene * prev, Scene * next) | ||||||
| { | { | ||||||
| 	auto renderer = Renderer::getInstance(); | 	auto renderer = Renderer::getInstance(); | ||||||
| 	// ´´½¨Í¼²ã
 | 	// ´´½¨Í¼²ã
 | ||||||
|  | @ -42,10 +42,10 @@ void e2d::Transition::_init(Scene * prev, Scene * next) | ||||||
| 
 | 
 | ||||||
| 	if (FAILED(hr)) | 	if (FAILED(hr)) | ||||||
| 	{ | 	{ | ||||||
| 		throw SystemException(L"场景过渡动画图层创建失败"); | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	_last = Game::getInstance()->getTotalDuration(); | 	_started = Time::now(); | ||||||
| 	_outScene = prev; | 	_outScene = prev; | ||||||
| 	_inScene = next; | 	_inScene = next; | ||||||
| 	if (_outScene) _outScene->retain(); | 	if (_outScene) _outScene->retain(); | ||||||
|  | @ -61,35 +61,24 @@ void e2d::Transition::_init(Scene * prev, Scene * next) | ||||||
| 		renderer->getSolidColorBrush(), | 		renderer->getSolidColorBrush(), | ||||||
| 		D2D1_LAYER_OPTIONS_NONE | 		D2D1_LAYER_OPTIONS_NONE | ||||||
| 	); | 	); | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Transition::_update() | void e2d::Transition::update() | ||||||
| { | { | ||||||
| 	// 计算动作进度
 |  | ||||||
| 	if (_duration == 0) | 	if (_duration == 0) | ||||||
| 	{ | 	{ | ||||||
| 		_delta = 1; | 		_delta = 1; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		_delta = (Game::getInstance()->getTotalDuration() - _last).seconds() / _duration; | 		_delta = (Time::now() - _started).seconds() / _duration; | ||||||
| 		_delta = std::min(_delta, 1.f); | 		_delta = std::min(_delta, 1.f); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	this->_updateCustom(); |  | ||||||
| 
 |  | ||||||
| 	// 更新场景内容
 |  | ||||||
| 	if (_outScene) |  | ||||||
| 	{ |  | ||||||
| 		_outScene->update(); |  | ||||||
| 	} |  | ||||||
| 	if (_inScene) |  | ||||||
| 	{ |  | ||||||
| 		_inScene->update(); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Transition::_render() | void e2d::Transition::render() | ||||||
| { | { | ||||||
| 	auto pRT = Renderer::getInstance()->getRenderTarget(); | 	auto pRT = Renderer::getInstance()->getRenderTarget(); | ||||||
| 
 | 
 | ||||||
|  | @ -132,8 +121,8 @@ void e2d::Transition::_render() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void e2d::Transition::_stop() | void e2d::Transition::stop() | ||||||
| { | { | ||||||
| 	_end = true; | 	_end = true; | ||||||
| 	_reset(); | 	reset(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ protected: | ||||||
| 	bool	_done; | 	bool	_done; | ||||||
| 	bool	_initialized; | 	bool	_initialized; | ||||||
| 	Node *	_target; | 	Node *	_target; | ||||||
| 	float	_last; | 	Time	_started; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -118,9 +118,6 @@ public: | ||||||
| 	// 获取游戏配置
 | 	// 获取游戏配置
 | ||||||
| 	const Config& getConfig(); | 	const Config& getConfig(); | ||||||
| 
 | 
 | ||||||
| 	// 获取游戏总时长
 |  | ||||||
| 	Duration getTotalDuration() const; |  | ||||||
| 
 |  | ||||||
| private: | private: | ||||||
| 	Game(); | 	Game(); | ||||||
| 
 | 
 | ||||||
|  | @ -132,9 +129,6 @@ private: | ||||||
| 	bool		_quit; | 	bool		_quit; | ||||||
| 	bool		_paused; | 	bool		_paused; | ||||||
| 	Config		_config; | 	Config		_config; | ||||||
| 	Time		_start; |  | ||||||
| 	Time		_now; |  | ||||||
| 	Time		_last; |  | ||||||
| 
 | 
 | ||||||
| 	static Game * _instance; | 	static Game * _instance; | ||||||
| }; | }; | ||||||
|  | @ -243,7 +237,13 @@ private: | ||||||
| 	E2D_DISABLE_COPY(Window); | 	E2D_DISABLE_COPY(Window); | ||||||
| 
 | 
 | ||||||
| 	// 注册窗口
 | 	// 注册窗口
 | ||||||
| 	HWND __create(); | 	HWND __registerWindow(); | ||||||
|  | 
 | ||||||
|  | 	// 根据客户区大小计算合适的窗口区域
 | ||||||
|  | 	Rect __adjustWindow( | ||||||
|  | 		int width, | ||||||
|  | 		int height | ||||||
|  | 	); | ||||||
| 
 | 
 | ||||||
| 	// Win32 窗口消息回调程序
 | 	// Win32 窗口消息回调程序
 | ||||||
| 	static LRESULT CALLBACK WndProc( | 	static LRESULT CALLBACK WndProc( | ||||||
|  | @ -342,12 +342,6 @@ public: | ||||||
| 		Color color | 		Color color | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	// 渲染游戏画面
 |  | ||||||
| 	void render(); |  | ||||||
| 
 |  | ||||||
| 	// 删除设备相关资源
 |  | ||||||
| 	void discardDeviceResources(); |  | ||||||
| 
 |  | ||||||
| 	// 获取文字渲染器
 | 	// 获取文字渲染器
 | ||||||
| 	TextRenderer * getTextRenderer(); | 	TextRenderer * getTextRenderer(); | ||||||
| 
 | 
 | ||||||
|  | @ -357,6 +351,12 @@ public: | ||||||
| 	// 获取 ID2D1SolidColorBrush 对象
 | 	// 获取 ID2D1SolidColorBrush 对象
 | ||||||
| 	ID2D1SolidColorBrush * getSolidColorBrush(); | 	ID2D1SolidColorBrush * getSolidColorBrush(); | ||||||
| 
 | 
 | ||||||
|  | 	// 渲染游戏画面
 | ||||||
|  | 	void render(); | ||||||
|  | 
 | ||||||
|  | 	// 删除设备相关资源
 | ||||||
|  | 	void discardDeviceResources(); | ||||||
|  | 
 | ||||||
| 	// 获取 ID2D1Factory 对象
 | 	// 获取 ID2D1Factory 对象
 | ||||||
| 	static ID2D1Factory * getFactory(); | 	static ID2D1Factory * getFactory(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -414,11 +414,7 @@ public: | ||||||
| 	Duration(); | 	Duration(); | ||||||
| 
 | 
 | ||||||
| 	explicit Duration( | 	explicit Duration( | ||||||
| 		int ms | 		float seconds | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	explicit Duration( |  | ||||||
| 		const std::chrono::milliseconds& ms |  | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	// 获取毫秒数
 | 	// 获取毫秒数
 | ||||||
|  | @ -451,10 +447,6 @@ class Time | ||||||
| public: | public: | ||||||
| 	Time(); | 	Time(); | ||||||
| 
 | 
 | ||||||
| 	explicit Time( |  | ||||||
| 		const std::chrono::steady_clock::time_point& time |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	// 获取时间戳
 | 	// 获取时间戳
 | ||||||
| 	time_t getTimeStamp() const; | 	time_t getTimeStamp() const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,13 +25,15 @@ public: | ||||||
| 	// 场景入栈
 | 	// 场景入栈
 | ||||||
| 	void push( | 	void push( | ||||||
| 		Scene * scene,						/* 下一个场景的指针 */ | 		Scene * scene,						/* 下一个场景的指针 */ | ||||||
| 		Transition * transition = nullptr,	/* 场景切换动作 */ |  | ||||||
| 		bool saveCurrentScene = true		/* 是否保存当前场景 */ | 		bool saveCurrentScene = true		/* 是否保存当前场景 */ | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	// 场景出栈
 | 	// 场景出栈
 | ||||||
| 	void pop( | 	Scene* pop(); | ||||||
| 		Transition * transition = nullptr	/* 场景切换动作 */ | 
 | ||||||
|  | 	// 设置场景切换动作
 | ||||||
|  | 	void setTransition( | ||||||
|  | 		Transition * transition	/* 场景切换动作 */ | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	// 清空保存的所有场景
 | 	// 清空保存的所有场景
 | ||||||
|  | @ -41,7 +43,7 @@ public: | ||||||
| 	Scene * getCurrentScene(); | 	Scene * getCurrentScene(); | ||||||
| 
 | 
 | ||||||
| 	// 获取场景栈
 | 	// 获取场景栈
 | ||||||
| 	std::stack<Scene*> getSceneStack(); | 	const std::stack<Scene*>& getSceneStack(); | ||||||
| 
 | 
 | ||||||
| 	// 是否正在进行转场动作
 | 	// 是否正在进行转场动作
 | ||||||
| 	bool isTransitioning(); | 	bool isTransitioning(); | ||||||
|  | @ -70,7 +72,6 @@ private: | ||||||
| 	E2D_DISABLE_COPY(SceneManager); | 	E2D_DISABLE_COPY(SceneManager); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	bool				_saveCurrScene; |  | ||||||
| 	Scene *				_currScene; | 	Scene *				_currScene; | ||||||
| 	Scene *				_nextScene; | 	Scene *				_nextScene; | ||||||
| 	Transition *		_transition; | 	Transition *		_transition; | ||||||
|  |  | ||||||
|  | @ -308,8 +308,8 @@ private: | ||||||
| 	bool		_stopped; | 	bool		_stopped; | ||||||
| 	int			_runTimes; | 	int			_runTimes; | ||||||
| 	int			_totalTimes; | 	int			_totalTimes; | ||||||
| 	float		_delay; | 	Duration	_delay; | ||||||
| 	float		_lastTime; | 	Time		_lastTime; | ||||||
| 	String		_name; | 	String		_name; | ||||||
| 	Function	_callback; | 	Function	_callback; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -5,15 +5,10 @@ namespace e2d | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SceneManager; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // 场景过渡
 | // 场景过渡
 | ||||||
| class Transition : | class Transition : | ||||||
| 	public Ref | 	public Ref | ||||||
| { | { | ||||||
| 	friend class SceneManager; |  | ||||||
| 
 |  | ||||||
| public: | public: | ||||||
| 	explicit Transition(float duration); | 	explicit Transition(float duration); | ||||||
| 
 | 
 | ||||||
|  | @ -22,36 +17,32 @@ public: | ||||||
| 	// 场景过渡动画是否结束
 | 	// 场景过渡动画是否结束
 | ||||||
| 	bool isDone(); | 	bool isDone(); | ||||||
| 
 | 
 | ||||||
| protected: |  | ||||||
| 	// 初始化场景过渡动画
 | 	// 初始化场景过渡动画
 | ||||||
| 	virtual void _init( | 	virtual bool init( | ||||||
| 		Scene * prev, | 		Scene * prev, | ||||||
| 		Scene * next | 		Scene * next | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	// 更新场景过渡动画
 | 	// 更新场景过渡动画
 | ||||||
| 	virtual void _update(); | 	virtual void update(); | ||||||
| 
 |  | ||||||
| 	// 更新场景过渡动画
 |  | ||||||
| 	virtual void _updateCustom() = 0; |  | ||||||
| 
 | 
 | ||||||
| 	// 渲染场景过渡动画
 | 	// 渲染场景过渡动画
 | ||||||
| 	virtual void _render(); | 	virtual void render(); | ||||||
| 
 |  | ||||||
| 	// 重置场景过渡动画
 |  | ||||||
| 	virtual void _reset() = 0; |  | ||||||
| 
 | 
 | ||||||
| 	// 停止场景过渡动画
 | 	// 停止场景过渡动画
 | ||||||
| 	virtual void _stop(); | 	virtual void stop(); | ||||||
|  | 
 | ||||||
|  | 	// ÖØÖó¡¾°¹ý¶É¶¯»
 | ||||||
|  | 	virtual void reset() = 0; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
| 	bool	_end; | 	bool	_end; | ||||||
| 	float	_duration; | 	float	_duration; | ||||||
| 	float	_delta; | 	float	_delta; | ||||||
| 	Duration _last; | 	Time	_started; | ||||||
| 	Size	_windowSize; | 	Size	_windowSize; | ||||||
| 	Scene * _outScene; | 	Scene*	_outScene; | ||||||
| 	Scene * _inScene; | 	Scene*	_inScene; | ||||||
| 	ID2D1Layer * _outLayer; | 	ID2D1Layer * _outLayer; | ||||||
| 	ID2D1Layer * _inLayer; | 	ID2D1Layer * _inLayer; | ||||||
| 	D2D1_LAYER_PARAMETERS _outLayerParam; | 	D2D1_LAYER_PARAMETERS _outLayerParam; | ||||||
|  | @ -68,16 +59,15 @@ public: | ||||||
| 		float duration	/* 动画持续时长 */ | 		float duration	/* 动画持续时长 */ | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| protected: |  | ||||||
| 	// 更新动画
 | 	// 更新动画
 | ||||||
| 	virtual void _updateCustom() override; | 	virtual void update() override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _init( | 	virtual bool init( | ||||||
| 		Scene * prev, | 		Scene * prev, | ||||||
| 		Scene * next | 		Scene * next | ||||||
| 	) override; | 	) override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _reset() override; | 	virtual void reset() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -90,16 +80,15 @@ public: | ||||||
| 		float duration	/* 浮现动画持续时长 */ | 		float duration	/* 浮现动画持续时长 */ | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| protected: |  | ||||||
| 	// 更新动画
 | 	// 更新动画
 | ||||||
| 	virtual void _updateCustom() override; | 	virtual void update() override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _init( | 	virtual bool init( | ||||||
| 		Scene * prev, | 		Scene * prev, | ||||||
| 		Scene * next | 		Scene * next | ||||||
| 	) override; | 	) override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _reset() override; | 	virtual void reset() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -112,16 +101,15 @@ public: | ||||||
| 		float duration	/* 动画持续时长 */ | 		float duration	/* 动画持续时长 */ | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| protected: |  | ||||||
| 	// 更新动画
 | 	// 更新动画
 | ||||||
| 	virtual void _updateCustom() override; | 	virtual void update() override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _init( | 	virtual bool init( | ||||||
| 		Scene * prev, | 		Scene * prev, | ||||||
| 		Scene * next | 		Scene * next | ||||||
| 	) override; | 	) override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _reset() override; | 	virtual void reset() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -135,16 +123,15 @@ public: | ||||||
| 		Direction direction = Direction::Left	/* 场景移动方向 */ | 		Direction direction = Direction::Left	/* 场景移动方向 */ | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| protected: |  | ||||||
| 	// 更新动画
 | 	// 更新动画
 | ||||||
| 	virtual void _updateCustom() override; | 	virtual void update() override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _init( | 	virtual bool init( | ||||||
| 		Scene * prev, | 		Scene * prev, | ||||||
| 		Scene * next | 		Scene * next | ||||||
| 	) override; | 	) override; | ||||||
| 
 | 
 | ||||||
| 	virtual void _reset() override; | 	virtual void reset() override; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
| 	Direction _direction; | 	Direction _direction; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue