Game类单例模式重做
This commit is contained in:
		
							parent
							
								
									95e77d6f0d
								
							
						
					
					
						commit
						0cf402e6e0
					
				|  | @ -4,19 +4,25 @@ | |||
| #include "..\e2dcollider.h" | ||||
| 
 | ||||
| 
 | ||||
| // 控制游戏终止
 | ||||
| static bool s_bEndGame = true; | ||||
| // 控制游戏暂停
 | ||||
| static bool s_bPaused = false; | ||||
| // 是否进行过初始化
 | ||||
| static bool s_bInitialized = false; | ||||
| // 游戏名称
 | ||||
| static e2d::String s_sGameName; | ||||
| e2d::Game * e2d::Game::_instance = nullptr; | ||||
| 
 | ||||
| 
 | ||||
| bool e2d::Game::init(const String& name, const String& mutexName) | ||||
| e2d::Game::Game() | ||||
| 	: _ended(false) | ||||
| 	, _paused(false) | ||||
| 	, _initialized(false) | ||||
| { | ||||
| 	if (s_bInitialized) | ||||
| } | ||||
| 
 | ||||
| e2d::Game * e2d::Game::getInstance() | ||||
| { | ||||
| 	if (!_instance) | ||||
| 		_instance = new (std::nothrow) Game; | ||||
| 	return _instance; | ||||
| } | ||||
| 
 | ||||
| bool e2d::Game::init(const String& mutexName) | ||||
| { | ||||
| 	if (_initialized) | ||||
| 	{ | ||||
| 		WARN("The game has been initialized!"); | ||||
| 		return false; | ||||
|  | @ -101,7 +107,7 @@ bool e2d::Game::init(const String& name, const String& mutexName) | |||
| 	else | ||||
| 	{ | ||||
| 		DestroyResources(); | ||||
| 		throw SystemException(L"初始化 DirectInput 失败"); | ||||
| 		throw SystemException(L"初始化 DirectInput 组件失败"); | ||||
| 	} | ||||
| 
 | ||||
| 	// 初始化播放器
 | ||||
|  | @ -112,27 +118,25 @@ bool e2d::Game::init(const String& name, const String& mutexName) | |||
| 	else | ||||
| 	{ | ||||
| 		DestroyResources(); | ||||
| 		throw SystemException(L"初始化 XAudio2 失败"); | ||||
| 		throw SystemException(L"初始化 XAudio2 组件失败"); | ||||
| 	} | ||||
| 
 | ||||
| 	// 初始化路径
 | ||||
| 	if (!Path::__init(name)) | ||||
| 	if (!Path::__init()) | ||||
| 	{ | ||||
| 		WARN("Path::__init failed!"); | ||||
| 		DestroyResources(); | ||||
| 		throw SystemException(L"必要系统路径访问失败"); | ||||
| 	} | ||||
| 
 | ||||
| 	// 保存游戏名称
 | ||||
| 	s_sGameName = name; | ||||
| 
 | ||||
| 	// 初始化成功
 | ||||
| 	s_bInitialized = true; | ||||
| 	_initialized = true; | ||||
| 
 | ||||
| 	return s_bInitialized; | ||||
| 	return _initialized; | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::start(bool autoRelease/* true */) | ||||
| void e2d::Game::start(bool cleanup) | ||||
| { | ||||
| 	if (!s_bInitialized) | ||||
| 	if (!_initialized) | ||||
| 	{ | ||||
| 		throw Exception(L"开始游戏前未进行初始化"); | ||||
| 	} | ||||
|  | @ -148,9 +152,9 @@ void e2d::Game::start(bool autoRelease/* true */) | |||
| 	// 初始化计时
 | ||||
| 	Time::__init(); | ||||
| 
 | ||||
| 	s_bEndGame = false; | ||||
| 	_ended = false; | ||||
| 
 | ||||
| 	while (!s_bEndGame) | ||||
| 	while (!_ended) | ||||
| 	{ | ||||
| 		// 处理窗口消息
 | ||||
| 		Window::__poll(); | ||||
|  | @ -175,31 +179,31 @@ void e2d::Game::start(bool autoRelease/* true */) | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	s_bEndGame = true; | ||||
| 	_ended = true; | ||||
| 
 | ||||
| 	if (autoRelease) | ||||
| 	if (cleanup) | ||||
| 	{ | ||||
| 		Game::destroy(); | ||||
| 		Game::cleanup(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::pause() | ||||
| { | ||||
| 	s_bPaused = true; | ||||
| 	_paused = true; | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::resume() | ||||
| { | ||||
| 	if (s_bInitialized && s_bPaused) | ||||
| 	if (_initialized && _paused) | ||||
| 	{ | ||||
| 		Game::reset(); | ||||
| 	} | ||||
| 	s_bPaused = false; | ||||
| 	_paused = false; | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::reset() | ||||
| { | ||||
| 	if (s_bInitialized && !s_bEndGame) | ||||
| 	if (_initialized && !_ended) | ||||
| 	{ | ||||
| 		Time::__reset(); | ||||
| 		ActionManager::__resetAll(); | ||||
|  | @ -209,17 +213,17 @@ void e2d::Game::reset() | |||
| 
 | ||||
| bool e2d::Game::isPaused() | ||||
| { | ||||
| 	return s_bPaused; | ||||
| 	return _paused; | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::quit() | ||||
| { | ||||
| 	s_bEndGame = true;	// 这个变量将控制游戏是否结束
 | ||||
| 	_ended = true;	// 这个变量将控制游戏是否结束
 | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::destroy() | ||||
| void e2d::Game::cleanup() | ||||
| { | ||||
| 	if (!s_bInitialized) | ||||
| 	if (!_initialized) | ||||
| 		return; | ||||
| 
 | ||||
| 	// 删除所有场景
 | ||||
|  | @ -249,10 +253,14 @@ void e2d::Game::destroy() | |||
| 
 | ||||
| 	CoUninitialize(); | ||||
| 
 | ||||
| 	s_bInitialized = false; | ||||
| 	_initialized = false; | ||||
| } | ||||
| 
 | ||||
| e2d::String e2d::Game::getName() | ||||
| void e2d::Game::destroy() | ||||
| { | ||||
| 	return s_sGameName; | ||||
| 	if (_instance) | ||||
| 	{ | ||||
| 		delete _instance; | ||||
| 		_instance = nullptr; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -322,7 +322,7 @@ void e2d::Input::removeAllListeners() | |||
| 
 | ||||
| void e2d::Input::__updateListeners() | ||||
| { | ||||
| 	if (s_vListeners.empty() || Game::isPaused()) | ||||
| 	if (s_vListeners.empty() || Game::getInstance()->isPaused()) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < s_vListeners.size(); ++i) | ||||
|  |  | |||
|  | @ -294,19 +294,19 @@ void e2d::Window::setTypewritingEnable(bool enable) | |||
| void e2d::Window::info(const String & text, const String & title) | ||||
| { | ||||
| 	::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONINFORMATION | MB_OK); | ||||
| 	Game::reset(); | ||||
| 	Game::getInstance()->reset(); | ||||
| } | ||||
| 
 | ||||
| void e2d::Window::warning(const String& title, const String& text) | ||||
| { | ||||
| 	::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONWARNING | MB_OK); | ||||
| 	Game::reset(); | ||||
| 	Game::getInstance()->reset(); | ||||
| } | ||||
| 
 | ||||
| void e2d::Window::error(const String & text, const String & title) | ||||
| { | ||||
| 	::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONERROR | MB_OK); | ||||
| 	Game::reset(); | ||||
| 	Game::getInstance()->reset(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -357,7 +357,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar | |||
| 		e2d::Scene * pCurrentScene = e2d::SceneManager::getCurrentScene(); | ||||
| 		if (!pCurrentScene || pCurrentScene->onCloseWindow()) | ||||
| 		{ | ||||
| 			e2d::Game::quit(); | ||||
| 			e2d::Game::getInstance()->quit(); | ||||
| 		} | ||||
| 	} | ||||
| 	result = 0; | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ bool e2d::Collision::isEnable() | |||
| 
 | ||||
| void e2d::Collision::__update(Node * active, Node * passive) | ||||
| { | ||||
| 	if (s_vListeners.empty() || Game::isPaused()) | ||||
| 	if (s_vListeners.empty() || Game::getInstance()->isPaused()) | ||||
| 		return; | ||||
| 
 | ||||
| 	s_pActiveNode = active; | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ static std::vector<e2d::Action*> s_vRunningActions; | |||
| 
 | ||||
| void e2d::ActionManager::__update() | ||||
| { | ||||
| 	if (s_vRunningActions.empty() || Game::isPaused()) | ||||
| 	if (s_vRunningActions.empty() || Game::getInstance()->isPaused()) | ||||
| 		return; | ||||
| 
 | ||||
| 	// 循环遍历所有正在运行的动作
 | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ void e2d::Node::_update() | |||
| 
 | ||||
| 	if (_children.empty()) | ||||
| 	{ | ||||
| 		if (_autoUpdate && !Game::isPaused()) | ||||
| 		if (_autoUpdate && !Game::getInstance()->isPaused()) | ||||
| 		{ | ||||
| 			this->onUpdate(); | ||||
| 		} | ||||
|  | @ -80,7 +80,7 @@ void e2d::Node::_update() | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (_autoUpdate && !Game::isPaused()) | ||||
| 		if (_autoUpdate && !Game::getInstance()->isPaused()) | ||||
| 		{ | ||||
| 			this->onUpdate(); | ||||
| 		} | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ static e2d::String s_sTempPath; | |||
| static e2d::String s_sDataSavePath; | ||||
| static std::list<e2d::String> s_vPathList; | ||||
| 
 | ||||
| bool e2d::Path::__init(const String& gameName) | ||||
| bool e2d::Path::__init() | ||||
| { | ||||
| 	// 获取 AppData\Local 文件夹的路径
 | ||||
| 	typedef HRESULT(WINAPI* pFunSHGetKnownFolderPath)(const GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); | ||||
|  | @ -36,43 +36,37 @@ bool e2d::Path::__init(const String& gameName) | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	// 获取数据的默认保存路径
 | ||||
| 	s_sDataSavePath = s_sLocalAppDataPath + L"\\Easy2DGameData\\"; | ||||
| 	if (!gameName.isEmpty()) | ||||
| 	{ | ||||
| 		s_sDataSavePath << gameName << L"\\"; | ||||
| 	return true; | ||||
| } | ||||
| 	if (!Path::exists(s_sDataSavePath)) | ||||
| 
 | ||||
| void e2d::Path::setGameFolderName(const String & name) | ||||
| { | ||||
| 		if (!Path::createFolder(s_sDataSavePath)) | ||||
| 	if (name.isEmpty()) | ||||
| 		return; | ||||
| 
 | ||||
| 	// 获取数据的默认保存路径
 | ||||
| 	if (!s_sLocalAppDataPath.isEmpty()) | ||||
| 	{ | ||||
| 		s_sDataSavePath = s_sLocalAppDataPath + L"\\Easy2DGameData\\" << name << L"\\"; | ||||
| 		 | ||||
| 		if (!Path::exists(s_sDataSavePath) && !Path::createFolder(s_sDataSavePath)) | ||||
| 		{ | ||||
| 			s_sDataSavePath = L""; | ||||
| 		} | ||||
| 	} | ||||
| 		s_sDataSavePath << L"Data.ini"; | ||||
| 	} | ||||
| 
 | ||||
| 	// 获取临时文件目录
 | ||||
| 	wchar_t path[_MAX_PATH]; | ||||
| 	if (0 == ::GetTempPath(_MAX_PATH, path)) | ||||
| 	if (0 != ::GetTempPath(_MAX_PATH, path)) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 		s_sTempPath << path << L"\\Easy2DGameTemp\\" << name << L"\\"; | ||||
| 
 | ||||
| 	s_sTempPath << path << L"\\Easy2DGameTemp\\"; | ||||
| 	if (!gameName.isEmpty()) | ||||
| 	{ | ||||
| 		s_sTempPath << gameName << L"\\"; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!Path::exists(s_sTempPath)) | ||||
| 	{ | ||||
| 		if (!Path::createFolder(s_sTempPath)) | ||||
| 		if (!Path::exists(s_sTempPath) && !Path::createFolder(s_sTempPath)) | ||||
| 		{ | ||||
| 			s_sTempPath = L""; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| void e2d::Path::add(String path) | ||||
|  | @ -99,9 +93,9 @@ e2d::String e2d::Path::getExecutableFilePath() | |||
| 	TCHAR szPath[_MAX_PATH] = { 0 }; | ||||
| 	if (::GetModuleFileName(nullptr, szPath, _MAX_PATH) != 0) | ||||
| 	{ | ||||
| 		return String(szPath); | ||||
| 		return std::move(String(szPath)); | ||||
| 	} | ||||
| 	return String(); | ||||
| 	return std::move(String()); | ||||
| } | ||||
| 
 | ||||
| e2d::String e2d::Path::searchForFile(const String& path) | ||||
|  | @ -120,7 +114,7 @@ e2d::String e2d::Path::searchForFile(const String& path) | |||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return String(); | ||||
| 	return std::move(String()); | ||||
| } | ||||
| 
 | ||||
| e2d::String e2d::Path::extractResource(int resNameId, const String & resType, const String & destFileName) | ||||
|  | @ -129,7 +123,7 @@ e2d::String e2d::Path::extractResource(int resNameId, const String & resType, co | |||
| 	// 创建文件
 | ||||
| 	HANDLE hFile = ::CreateFile((LPCWSTR)destFilePath, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL); | ||||
| 	if (hFile == INVALID_HANDLE_VALUE) | ||||
| 		return String(); | ||||
| 		return std::move(String()); | ||||
| 
 | ||||
| 	// 查找资源文件中、加载资源到内存、得到资源大小
 | ||||
| 	HRSRC hRes = ::FindResource(NULL, MAKEINTRESOURCE(resNameId), (LPCWSTR)resType); | ||||
|  | @ -148,7 +142,7 @@ e2d::String e2d::Path::extractResource(int resNameId, const String & resType, co | |||
| 	{ | ||||
| 		::CloseHandle(hFile); | ||||
| 		::DeleteFile((LPCWSTR)destFilePath); | ||||
| 		return String(); | ||||
| 		return std::move(String()); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -194,7 +188,7 @@ e2d::String e2d::Path::getSaveFilePath(const String& title, const String& defExt | |||
| 	{ | ||||
| 		return strFilename; | ||||
| 	} | ||||
| 	return L""; | ||||
| 	return std::move(String()); | ||||
| } | ||||
| 
 | ||||
| bool e2d::Path::createFolder(const String& dirPath) | ||||
|  |  | |||
|  | @ -144,7 +144,7 @@ void e2d::Timer::removeAll() | |||
| 
 | ||||
| void e2d::Timer::__update() | ||||
| { | ||||
| 	if (s_vTimers.empty() || Game::isPaused()) | ||||
| 	if (s_vTimers.empty() || Game::getInstance()->isPaused()) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < s_vTimers.size();) | ||||
|  |  | |||
|  | @ -14,37 +14,50 @@ namespace e2d | |||
| class Game | ||||
| { | ||||
| public: | ||||
| 	// 获取游戏单例
 | ||||
| 	static Game * getInstance(); | ||||
| 
 | ||||
| 	// 初始化游戏
 | ||||
| 	static bool init( | ||||
| 		const String& name = L"",		/* 游戏英文名称 */ | ||||
| 	bool init( | ||||
| 		const String& mutexName = L""	/* 进程互斥体名称 */ | ||||
| 	); | ||||
| 
 | ||||
| 	// 启动游戏
 | ||||
| 	static void start( | ||||
| 		bool autoRelease = true			/* 游戏结束时自动回收资源 */ | ||||
| 	void start( | ||||
| 		bool cleanup = true				/* 自动清理资源 */ | ||||
| 	); | ||||
| 
 | ||||
| 	// 暂停游戏
 | ||||
| 	static void pause(); | ||||
| 	void pause(); | ||||
| 
 | ||||
| 	// 继续游戏
 | ||||
| 	static void resume(); | ||||
| 	void resume(); | ||||
| 
 | ||||
| 	// 结束游戏
 | ||||
| 	static void quit(); | ||||
| 	void quit(); | ||||
| 
 | ||||
| 	// 回收游戏资源
 | ||||
| 	static void destroy(); | ||||
| 	// 清理资源
 | ||||
| 	void cleanup(); | ||||
| 
 | ||||
| 	// 销毁实例
 | ||||
| 	void destroy(); | ||||
| 
 | ||||
| 	// 重置游戏内部计时
 | ||||
| 	static void reset(); | ||||
| 	void reset(); | ||||
| 
 | ||||
| 	// 游戏是否暂停
 | ||||
| 	static bool isPaused(); | ||||
| 	bool isPaused(); | ||||
| 
 | ||||
| 	// 获取游戏名称
 | ||||
| 	static String getName(); | ||||
| private: | ||||
| 	Game(); | ||||
| 
 | ||||
| 	E2D_DISABLE_COPY(Game); | ||||
| 
 | ||||
| private: | ||||
| 	bool	_ended; | ||||
| 	bool	_paused; | ||||
| 	bool	_initialized; | ||||
| 	static Game * _instance; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -78,8 +78,16 @@ | |||
| #	endif | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #if _MSC_VER >= 1800 | ||||
| #	define E2D_OP_EXPLICIT explicit | ||||
| #	define E2D_DELETE = delete | ||||
| #else | ||||
| #	define E2D_OP_EXPLICIT | ||||
| #	define E2D_DELETE | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #define E2D_DISABLE_COPY(ClassName)\ | ||||
| 	ClassName(const ClassName &); \ | ||||
| 	ClassName & operator= (const ClassName &) E2D_DELETE | ||||
|  | @ -442,6 +442,11 @@ class Path | |||
| 	friend class Game; | ||||
| 
 | ||||
| public: | ||||
| 	// 设置游戏数据和临时文件保存路径名称
 | ||||
| 	static void setGameFolderName( | ||||
| 		const String& name | ||||
| 	); | ||||
| 
 | ||||
| 	// Ìí¼ÓËÑË÷·¾¶
 | ||||
| 	static void add( | ||||
| 		String path | ||||
|  | @ -491,9 +496,7 @@ public: | |||
| 
 | ||||
| private: | ||||
| 	// ³õʼ»¯
 | ||||
| 	static bool __init( | ||||
| 		const String& gameName | ||||
| 	); | ||||
| 	static bool __init(); | ||||
| }; | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue