Game类单例模式重做

This commit is contained in:
Nomango 2018-07-03 01:49:20 +08:00
parent 95e77d6f0d
commit 0cf402e6e0
11 changed files with 122 additions and 96 deletions

View File

@ -4,19 +4,25 @@
#include "..\e2dcollider.h" #include "..\e2dcollider.h"
// 控制游戏终止 e2d::Game * e2d::Game::_instance = nullptr;
static bool s_bEndGame = true;
// 控制游戏暂停
static bool s_bPaused = false;
// 是否进行过初始化
static bool s_bInitialized = false;
// 游戏名称
static e2d::String s_sGameName;
e2d::Game::Game()
bool e2d::Game::init(const String& name, const String& mutexName) : _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!"); WARN("The game has been initialized!");
return false; return false;
@ -101,7 +107,7 @@ bool e2d::Game::init(const String& name, const String& mutexName)
else else
{ {
DestroyResources(); DestroyResources();
throw SystemException(L"初始化 DirectInput 失败"); throw SystemException(L"初始化 DirectInput 组件失败");
} }
// 初始化播放器 // 初始化播放器
@ -112,27 +118,25 @@ bool e2d::Game::init(const String& name, const String& mutexName)
else else
{ {
DestroyResources(); 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"开始游戏前未进行初始化"); throw Exception(L"开始游戏前未进行初始化");
} }
@ -148,9 +152,9 @@ void e2d::Game::start(bool autoRelease/* true */)
// 初始化计时 // 初始化计时
Time::__init(); Time::__init();
s_bEndGame = false; _ended = false;
while (!s_bEndGame) while (!_ended)
{ {
// 处理窗口消息 // 处理窗口消息
Window::__poll(); 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() void e2d::Game::pause()
{ {
s_bPaused = true; _paused = true;
} }
void e2d::Game::resume() void e2d::Game::resume()
{ {
if (s_bInitialized && s_bPaused) if (_initialized && _paused)
{ {
Game::reset(); Game::reset();
} }
s_bPaused = false; _paused = false;
} }
void e2d::Game::reset() void e2d::Game::reset()
{ {
if (s_bInitialized && !s_bEndGame) if (_initialized && !_ended)
{ {
Time::__reset(); Time::__reset();
ActionManager::__resetAll(); ActionManager::__resetAll();
@ -209,17 +213,17 @@ void e2d::Game::reset()
bool e2d::Game::isPaused() bool e2d::Game::isPaused()
{ {
return s_bPaused; return _paused;
} }
void e2d::Game::quit() void e2d::Game::quit()
{ {
s_bEndGame = true; // 这个变量将控制游戏是否结束 _ended = true; // 这个变量将控制游戏是否结束
} }
void e2d::Game::destroy() void e2d::Game::cleanup()
{ {
if (!s_bInitialized) if (!_initialized)
return; return;
// 删除所有场景 // 删除所有场景
@ -249,10 +253,14 @@ void e2d::Game::destroy()
CoUninitialize(); CoUninitialize();
s_bInitialized = false; _initialized = false;
} }
e2d::String e2d::Game::getName() void e2d::Game::destroy()
{ {
return s_sGameName; if (_instance)
{
delete _instance;
_instance = nullptr;
}
} }

View File

@ -322,7 +322,7 @@ void e2d::Input::removeAllListeners()
void e2d::Input::__updateListeners() void e2d::Input::__updateListeners()
{ {
if (s_vListeners.empty() || Game::isPaused()) if (s_vListeners.empty() || Game::getInstance()->isPaused())
return; return;
for (size_t i = 0; i < s_vListeners.size(); ++i) for (size_t i = 0; i < s_vListeners.size(); ++i)

View File

@ -294,19 +294,19 @@ void e2d::Window::setTypewritingEnable(bool enable)
void e2d::Window::info(const String & text, const String & title) void e2d::Window::info(const String & text, const String & title)
{ {
::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONINFORMATION | MB_OK); ::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) void e2d::Window::warning(const String& title, const String& text)
{ {
::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONWARNING | MB_OK); ::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) void e2d::Window::error(const String & text, const String & title)
{ {
::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONERROR | MB_OK); ::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(); e2d::Scene * pCurrentScene = e2d::SceneManager::getCurrentScene();
if (!pCurrentScene || pCurrentScene->onCloseWindow()) if (!pCurrentScene || pCurrentScene->onCloseWindow())
{ {
e2d::Game::quit(); e2d::Game::getInstance()->quit();
} }
} }
result = 0; result = 0;

View File

@ -104,7 +104,7 @@ bool e2d::Collision::isEnable()
void e2d::Collision::__update(Node * active, Node * passive) void e2d::Collision::__update(Node * active, Node * passive)
{ {
if (s_vListeners.empty() || Game::isPaused()) if (s_vListeners.empty() || Game::getInstance()->isPaused())
return; return;
s_pActiveNode = active; s_pActiveNode = active;

View File

@ -8,7 +8,7 @@ static std::vector<e2d::Action*> s_vRunningActions;
void e2d::ActionManager::__update() void e2d::ActionManager::__update()
{ {
if (s_vRunningActions.empty() || Game::isPaused()) if (s_vRunningActions.empty() || Game::getInstance()->isPaused())
return; return;
// 循环遍历所有正在运行的动作 // 循环遍历所有正在运行的动作

View File

@ -52,7 +52,7 @@ void e2d::Node::_update()
if (_children.empty()) if (_children.empty())
{ {
if (_autoUpdate && !Game::isPaused()) if (_autoUpdate && !Game::getInstance()->isPaused())
{ {
this->onUpdate(); this->onUpdate();
} }
@ -80,7 +80,7 @@ void e2d::Node::_update()
} }
} }
if (_autoUpdate && !Game::isPaused()) if (_autoUpdate && !Game::getInstance()->isPaused())
{ {
this->onUpdate(); this->onUpdate();
} }

View File

@ -15,7 +15,7 @@ static e2d::String s_sTempPath;
static e2d::String s_sDataSavePath; static e2d::String s_sDataSavePath;
static std::list<e2d::String> s_vPathList; static std::list<e2d::String> s_vPathList;
bool e2d::Path::__init(const String& gameName) bool e2d::Path::__init()
{ {
// 获取 AppData\Local 文件夹的路径 // 获取 AppData\Local 文件夹的路径
typedef HRESULT(WINAPI* pFunSHGetKnownFolderPath)(const GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); 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; return false;
} }
return true;
}
void e2d::Path::setGameFolderName(const String & name)
{
if (name.isEmpty())
return;
// 获取数据的默认保存路径 // 获取数据的默认保存路径
s_sDataSavePath = s_sLocalAppDataPath + L"\\Easy2DGameData\\"; if (!s_sLocalAppDataPath.isEmpty())
if (!gameName.isEmpty())
{ {
s_sDataSavePath << gameName << L"\\"; s_sDataSavePath = s_sLocalAppDataPath + L"\\Easy2DGameData\\" << name << L"\\";
}
if (!Path::exists(s_sDataSavePath)) if (!Path::exists(s_sDataSavePath) && !Path::createFolder(s_sDataSavePath))
{
if (!Path::createFolder(s_sDataSavePath))
{ {
s_sDataSavePath = L""; s_sDataSavePath = L"";
} }
s_sDataSavePath << L"Data.ini";
} }
s_sDataSavePath << L"Data.ini";
// 获取临时文件目录 // 获取临时文件目录
wchar_t path[_MAX_PATH]; 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 (!Path::exists(s_sTempPath) && !Path::createFolder(s_sTempPath))
if (!gameName.isEmpty())
{
s_sTempPath << gameName << L"\\";
}
if (!Path::exists(s_sTempPath))
{
if (!Path::createFolder(s_sTempPath))
{ {
s_sTempPath = L""; s_sTempPath = L"";
} }
} }
return true;
} }
void e2d::Path::add(String path) void e2d::Path::add(String path)
@ -99,9 +93,9 @@ e2d::String e2d::Path::getExecutableFilePath()
TCHAR szPath[_MAX_PATH] = { 0 }; TCHAR szPath[_MAX_PATH] = { 0 };
if (::GetModuleFileName(nullptr, 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) 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) 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); HANDLE hFile = ::CreateFile((LPCWSTR)destFilePath, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return String(); return std::move(String());
// 查找资源文件中、加载资源到内存、得到资源大小 // 查找资源文件中、加载资源到内存、得到资源大小
HRSRC hRes = ::FindResource(NULL, MAKEINTRESOURCE(resNameId), (LPCWSTR)resType); 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); ::CloseHandle(hFile);
::DeleteFile((LPCWSTR)destFilePath); ::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 strFilename;
} }
return L""; return std::move(String());
} }
bool e2d::Path::createFolder(const String& dirPath) bool e2d::Path::createFolder(const String& dirPath)

View File

@ -144,7 +144,7 @@ void e2d::Timer::removeAll()
void e2d::Timer::__update() void e2d::Timer::__update()
{ {
if (s_vTimers.empty() || Game::isPaused()) if (s_vTimers.empty() || Game::getInstance()->isPaused())
return; return;
for (size_t i = 0; i < s_vTimers.size();) for (size_t i = 0; i < s_vTimers.size();)

View File

@ -14,37 +14,50 @@ namespace e2d
class Game class Game
{ {
public: public:
// 获取游戏单例
static Game * getInstance();
// 初始化游戏 // 初始化游戏
static bool init( bool init(
const String& name = L"", /* 游戏英文名称 */
const String& mutexName = L"" /* 进程互斥体名称 */ const String& mutexName = L"" /* 进程互斥体名称 */
); );
// 启动游戏 // 启动游戏
static void start( void start(
bool autoRelease = true /* 游戏结束时自动回收资源 */ 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();
// 获取游戏名称 private:
static String getName(); Game();
E2D_DISABLE_COPY(Game);
private:
bool _ended;
bool _paused;
bool _initialized;
static Game * _instance;
}; };

View File

@ -78,8 +78,16 @@
# endif # endif
#endif #endif
#if _MSC_VER >= 1800 #if _MSC_VER >= 1800
# define E2D_OP_EXPLICIT explicit # define E2D_OP_EXPLICIT explicit
# define E2D_DELETE = delete
#else #else
# define E2D_OP_EXPLICIT # define E2D_OP_EXPLICIT
# define E2D_DELETE
#endif #endif
#define E2D_DISABLE_COPY(ClassName)\
ClassName(const ClassName &); \
ClassName & operator= (const ClassName &) E2D_DELETE

View File

@ -442,6 +442,11 @@ class Path
friend class Game; friend class Game;
public: public:
// 设置游戏数据和临时文件保存路径名称
static void setGameFolderName(
const String& name
);
// Ìí¼ÓËÑË÷·¾¶ // Ìí¼ÓËÑË÷·¾¶
static void add( static void add(
String path String path
@ -491,9 +496,7 @@ public:
private: private:
// ³õʼ»¯ // ³õʼ»¯
static bool __init( static bool __init();
const String& gameName
);
}; };
} }