214 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| #include "..\e2dbase.h"
 | |
| #include "..\e2dmanager.h"
 | |
| #include "..\e2dtool.h"
 | |
| #include "..\e2dcollider.h"
 | |
| 
 | |
| 
 | |
| e2d::Game * e2d::Game::_instance = nullptr;
 | |
| 
 | |
| e2d::Game::Game()
 | |
| 	: _ended(false)
 | |
| 	, _paused(false)
 | |
| 	, _initialized(false)
 | |
| {
 | |
| }
 | |
| 
 | |
| e2d::Game::~Game()
 | |
| {
 | |
| }
 | |
| 
 | |
| e2d::Game * e2d::Game::getInstance()
 | |
| {
 | |
| 	if (!_instance)
 | |
| 		_instance = new (std::nothrow) Game;
 | |
| 	return _instance;
 | |
| }
 | |
| 
 | |
| void e2d::Game::destroyInstance()
 | |
| {
 | |
| 	if (_instance)
 | |
| 	{
 | |
| 		delete _instance;
 | |
| 		_instance = nullptr;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| bool e2d::Game::init(const String& mutexName)
 | |
| {
 | |
| 	if (_initialized)
 | |
| 	{
 | |
| 		WARN("The game has been initialized!");
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	if (!mutexName.isEmpty())
 | |
| 	{
 | |
| 		// 创建进程互斥体
 | |
| 		String fullMutexName = L"Easy2DApp-" + mutexName;
 | |
| 		HANDLE hMutex = ::CreateMutex(nullptr, TRUE, (LPCWSTR)fullMutexName);
 | |
| 
 | |
| 		if (hMutex == nullptr)
 | |
| 		{
 | |
| 			WARN("CreateMutex Failed!");
 | |
| 		}
 | |
| 		else if (::GetLastError() == ERROR_ALREADY_EXISTS)
 | |
| 		{
 | |
| 			// 如果程序已经存在并且正在运行,弹窗提示
 | |
| 			Window::getInstance()->info(L"游戏已在其他窗口中打开!", L"提示");
 | |
| 			// 关闭进程互斥体
 | |
| 			::CloseHandle(hMutex);
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// 初始化 COM 组件
 | |
| 	CoInitialize(nullptr);
 | |
| 
 | |
| 	bool bInputInit = false;
 | |
| 
 | |
| 	auto DestroyResources = [&]()
 | |
| 	{
 | |
| 		if (bInputInit) Input::__uninit();
 | |
| 	};
 | |
| 
 | |
| 	// 初始化 DirectInput
 | |
| 	if (Input::__init())
 | |
| 	{
 | |
| 		bInputInit = true;
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		DestroyResources();
 | |
| 		throw SystemException(L"初始化 DirectInput 组件失败");
 | |
| 	}
 | |
| 
 | |
| 	// 初始化路径
 | |
| 	if (!Path::__init())
 | |
| 	{
 | |
| 		DestroyResources();
 | |
| 		throw SystemException(L"必要系统路径访问失败");
 | |
| 	}
 | |
| 
 | |
| 	// 初始化成功
 | |
| 	_initialized = true;
 | |
| 
 | |
| 	return _initialized;
 | |
| }
 | |
| 
 | |
| void e2d::Game::start(bool cleanup)
 | |
| {
 | |
| 	if (!_initialized)
 | |
| 	{
 | |
| 		throw Exception(L"开始游戏前未进行初始化");
 | |
| 	}
 | |
| 
 | |
| 	auto window = Window::getInstance();
 | |
| 	auto renderer = Renderer::getInstance();
 | |
| 
 | |
| 	// 初始化场景管理器
 | |
| 	SceneManager::__init();
 | |
| 	// 显示窗口
 | |
| 	::ShowWindow(window->getHWnd(), SW_SHOWNORMAL);
 | |
| 	// 刷新窗口内容
 | |
| 	::UpdateWindow(window->getHWnd());
 | |
| 	// 处理窗口消息
 | |
| 	window->__poll();
 | |
| 	// 初始化计时
 | |
| 	Time::__init();
 | |
| 
 | |
| 	_ended = false;
 | |
| 
 | |
| 	while (!_ended)
 | |
| 	{
 | |
| 		// 处理窗口消息
 | |
| 		window->__poll();
 | |
| 		// 刷新时间
 | |
| 		Time::__updateNow();
 | |
| 
 | |
| 		// 判断是否达到了刷新状态
 | |
| 		if (Time::__isReady())
 | |
| 		{
 | |
| 			Input::__update();			// 获取用户输入
 | |
| 			Timer::__update();			// 更新定时器
 | |
| 			ActionManager::__update();	// 更新动作管理器
 | |
| 			SceneManager::__update();	// 更新场景内容
 | |
| 			renderer->__render();		// 渲染游戏画面
 | |
| 
 | |
| 			Time::__updateLast();		// 刷新时间信息
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			Time::__sleep();				// 挂起线程
 | |
| 			GC::getInstance()->__update();	// 刷新内存池
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	_ended = true;
 | |
| 
 | |
| 	if (cleanup)
 | |
| 	{
 | |
| 		Game::cleanup();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void e2d::Game::pause()
 | |
| {
 | |
| 	_paused = true;
 | |
| }
 | |
| 
 | |
| void e2d::Game::resume()
 | |
| {
 | |
| 	if (_initialized && _paused)
 | |
| 	{
 | |
| 		Game::reset();
 | |
| 	}
 | |
| 	_paused = false;
 | |
| }
 | |
| 
 | |
| void e2d::Game::reset()
 | |
| {
 | |
| 	if (_initialized && !_ended)
 | |
| 	{
 | |
| 		Time::__reset();
 | |
| 		ActionManager::__resetAll();
 | |
| 		Timer::__resetAll();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| bool e2d::Game::isPaused()
 | |
| {
 | |
| 	return _paused;
 | |
| }
 | |
| 
 | |
| void e2d::Game::quit()
 | |
| {
 | |
| 	_ended = true;	// 这个变量将控制游戏是否结束
 | |
| }
 | |
| 
 | |
| void e2d::Game::cleanup()
 | |
| {
 | |
| 	if (!_initialized)
 | |
| 		return;
 | |
| 
 | |
| 	// 删除所有场景
 | |
| 	SceneManager::__uninit();
 | |
| 	// 删除输入监听器
 | |
| 	Input::__clearListeners();
 | |
| 	// 删除碰撞监听器
 | |
| 	Collision::__clearListeners();
 | |
| 	// 删除动作
 | |
| 	ActionManager::__uninit();
 | |
| 	// 清空图片缓存
 | |
| 	Image::clearCache();
 | |
| 	// 清空定时器
 | |
| 	Timer::__uninit();
 | |
| 	// 关闭输入
 | |
| 	Input::__uninit();
 | |
| 	// 删除所有对象
 | |
| 	GC::getInstance()->clear();
 | |
| 
 | |
| 	CoUninitialize();
 | |
| 
 | |
| 	_initialized = false;
 | |
| }
 |