From 0cf402e6e0ef3279d0580c9869ec27bd469b6c20 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Tue, 3 Jul 2018 01:49:20 +0800 Subject: [PATCH] =?UTF-8?q?Game=E7=B1=BB=E5=8D=95=E4=BE=8B=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E9=87=8D=E5=81=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/Game.cpp | 84 +++++++++++++++++++--------------- core/Base/Input.cpp | 2 +- core/Base/Window.cpp | 8 ++-- core/Collider/Collision.cpp | 2 +- core/Manager/ActionManager.cpp | 2 +- core/Node/Node.cpp | 4 +- core/Tool/Path.cpp | 54 ++++++++++------------ core/Tool/Timer.cpp | 2 +- core/e2dbase.h | 39 ++++++++++------ core/e2dmacros.h | 12 ++++- core/e2dtool.h | 9 ++-- 11 files changed, 122 insertions(+), 96 deletions(-) diff --git a/core/Base/Game.cpp b/core/Base/Game.cpp index 1b8da3c9..f6161881 100644 --- a/core/Base/Game.cpp +++ b/core/Base/Game.cpp @@ -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; + } } diff --git a/core/Base/Input.cpp b/core/Base/Input.cpp index e9657d5f..5b19a592 100644 --- a/core/Base/Input.cpp +++ b/core/Base/Input.cpp @@ -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) diff --git a/core/Base/Window.cpp b/core/Base/Window.cpp index 111680e1..7e885ec8 100644 --- a/core/Base/Window.cpp +++ b/core/Base/Window.cpp @@ -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; diff --git a/core/Collider/Collision.cpp b/core/Collider/Collision.cpp index 777ce69c..0cec25ec 100644 --- a/core/Collider/Collision.cpp +++ b/core/Collider/Collision.cpp @@ -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; diff --git a/core/Manager/ActionManager.cpp b/core/Manager/ActionManager.cpp index 57dfcf45..8e68eead 100644 --- a/core/Manager/ActionManager.cpp +++ b/core/Manager/ActionManager.cpp @@ -8,7 +8,7 @@ static std::vector s_vRunningActions; void e2d::ActionManager::__update() { - if (s_vRunningActions.empty() || Game::isPaused()) + if (s_vRunningActions.empty() || Game::getInstance()->isPaused()) return; // 循环遍历所有正在运行的动作 diff --git a/core/Node/Node.cpp b/core/Node/Node.cpp index bdde3eaf..c12e3904 100644 --- a/core/Node/Node.cpp +++ b/core/Node/Node.cpp @@ -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(); } diff --git a/core/Tool/Path.cpp b/core/Tool/Path.cpp index e6c2a706..8bbf9372 100644 --- a/core/Tool/Path.cpp +++ b/core/Tool/Path.cpp @@ -15,7 +15,7 @@ static e2d::String s_sTempPath; static e2d::String s_sDataSavePath; static std::list 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); @@ -35,44 +35,38 @@ bool e2d::Path::__init(const String& gameName) WARN("Get local AppData path failed!"); return false; } - + + return true; +} + +void e2d::Path::setGameFolderName(const String & name) +{ + if (name.isEmpty()) + return; + // 获取数据的默认保存路径 - s_sDataSavePath = s_sLocalAppDataPath + L"\\Easy2DGameData\\"; - if (!gameName.isEmpty()) + if (!s_sLocalAppDataPath.isEmpty()) { - s_sDataSavePath << gameName << L"\\"; - } - if (!Path::exists(s_sDataSavePath)) - { - if (!Path::createFolder(s_sDataSavePath)) + 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"; } - 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) diff --git a/core/Tool/Timer.cpp b/core/Tool/Timer.cpp index fcf0ccba..d94a33c5 100644 --- a/core/Tool/Timer.cpp +++ b/core/Tool/Timer.cpp @@ -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();) diff --git a/core/e2dbase.h b/core/e2dbase.h index 36b6d3e1..21f9535d 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -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; }; diff --git a/core/e2dmacros.h b/core/e2dmacros.h index f2c0bf82..6a9d4b02 100644 --- a/core/e2dmacros.h +++ b/core/e2dmacros.h @@ -78,8 +78,16 @@ # endif #endif + #if _MSC_VER >= 1800 # define E2D_OP_EXPLICIT explicit +# define E2D_DELETE = delete #else -# define E2D_OP_EXPLICIT -#endif \ No newline at end of file +# define E2D_OP_EXPLICIT +# define E2D_DELETE +#endif + + +#define E2D_DISABLE_COPY(ClassName)\ + ClassName(const ClassName &); \ + ClassName & operator= (const ClassName &) E2D_DELETE \ No newline at end of file diff --git a/core/e2dtool.h b/core/e2dtool.h index e73010a5..ec819294 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -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(); }; } \ No newline at end of file