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"
// 控制游戏终止
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;
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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;
// 循环遍历所有正在运行的动作

View File

@ -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();
}

View File

@ -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);
@ -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)

View File

@ -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();)

View File

@ -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;
};

View File

@ -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
# define E2D_OP_EXPLICIT
# define E2D_DELETE
#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;
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();
};
}