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