示例一:Game Engine Part 1
更加完善游戏的基本流程
Graphics添加了以下几个方法,beginScene和endScene提高绘图,showBackbuffer去掉了clear方法
// Reset the graphics device. HRESULT reset(); // get functions // Return direct3d. LP_3D get3D() { return direct3d; } // Return device3d. LP_3DDEVICE get3Ddevice() { return device3d; } // Return handle to device context (window). HDC getDC() { return GetDC(hwnd); } // Test for lost device HRESULT getDeviceState(); //============================================================================= // Inline functions for speed. How much more speed? It depends on the game and // computer. Improvements of 3 or 4 percent have been observed. //============================================================================= // Set color used to clear screen void setBackColor(COLOR_ARGB c) {backColor = c;} //============================================================================= // Clear backbuffer and BeginScene() //============================================================================= HRESULT beginScene() { result = E_FAIL; if(device3d == NULL) return result; // clear backbuffer to backColor device3d->Clear(0, NULL, D3DCLEAR_TARGET, backColor, 1.0F, 0); result = device3d->BeginScene(); // begin scene for drawing return result; } //============================================================================= // EndScene() //============================================================================= HRESULT endScene() { result = E_FAIL; if(device3d) result = device3d->EndScene(); return result; }
IDirect3DDevice9::TestCooperativeLevel。因此在设备丢失之后,你应该停止整个游戏循环,而通过反复调用
IDirect3DDevice9::TestCooperativeLevel判断设备是否可用。
//============================================================================= // Test for lost device //============================================================================= HRESULT Graphics::getDeviceState() { result = E_FAIL; // default to fail, replace on success if (device3d == NULL) return result; result = device3d->TestCooperativeLevel(); return result; }
Game类
现在Graphics类属于Game类包装
Game类主要流程:
1.初始化
//============================================================================= // Initializes the game // throws GameError on error //============================================================================= void Game::initialize(HWND hw) { hwnd = hw; // save window handle // initialize graphics graphics = new Graphics(); // throws GameError graphics->initialize(hwnd, GAME_WIDTH, GAME_HEIGHT, FULLSCREEN); // initialize input, do not capture mouse input->initialize(hwnd, false); // throws GameError // attempt to set up high resolution timer if(QueryPerformanceFrequency(&timerFreq) == false) throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing high resolution timer")); QueryPerformanceCounter(&timeStart); // get starting time initialized = true; }
2.messageHandler方法处理消息流程,由Input类接入
3.renderGame
属于Game呈现的主流程,子类重写render方法
//============================================================================= // Render game items //============================================================================= void Game::renderGame() { //start rendering if (SUCCEEDED(graphics->beginScene())) { // render is a pure virtual function that must be provided in the // inheriting class. render(); // call render in derived class //stop rendering graphics->endScene(); } handleLostGraphicsDevice(); //display the back buffer on the screen graphics->showBackbuffer(); }
4.子类Spacewar继承自Game
// Programming 2D Games // Copyright (c) 2011 by: // Charles Kelly // Game Engine Part 1 // Chapter 4 spacewar.cpp v1.0 // Spacewar is the class we create. #include "spaceWar.h" //============================================================================= // Constructor //============================================================================= Spacewar::Spacewar() {} //============================================================================= // Destructor //============================================================================= Spacewar::~Spacewar() { releaseAll(); // call onLostDevice() for every graphics item } //============================================================================= // Initializes the game // Throws GameError on error //============================================================================= void Spacewar::initialize(HWND hwnd) { Game::initialize(hwnd); // throws GameError return; } //============================================================================= // Update all game items //============================================================================= void Spacewar::update() {} //============================================================================= // Artificial Intelligence //============================================================================= void Spacewar::ai() {} //============================================================================= // Handle collisions //============================================================================= void Spacewar::collisions() {} //============================================================================= // Render game items //============================================================================= void Spacewar::render() {} //============================================================================= // The graphics device was lost. // Release all reserved video memory so graphics device may be reset. //============================================================================= void Spacewar::releaseAll() { Game::releaseAll(); return; } //============================================================================= // The grahics device has been reset. // Recreate all surfaces. //============================================================================= void Spacewar::resetAll() { Game::resetAll(); return; }
以上是一个基本游戏的一个主流程
// Game pointer Spacewar *game = NULL; HWND hwnd = NULL; //============================================================================= // Starting point for a Windows application //============================================================================= int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Check for memory leak if debug build #if defined(DEBUG) | defined(_DEBUG) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif MSG msg; // Create the game, sets up message handler game = new Spacewar; // Create the window if (!CreateMainWindow(hwnd, hInstance, nCmdShow)) return 1; try{ game->initialize(hwnd); // throws GameError // main message loop int done = 0; while (!done) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // look for quit message if (msg.message == WM_QUIT) done = 1; // decode and pass messages on to WinProc TranslateMessage(&msg); DispatchMessage(&msg); } else game->run(hwnd); // run the game loop } SAFE_DELETE (game); // free memory before exit return msg.wParam; } catch(const GameError &err) { game->deleteAll(); DestroyWindow(hwnd); MessageBox(NULL, err.getMessage(), "Error", MB_OK); } catch(...) { game->deleteAll(); DestroyWindow(hwnd); MessageBox(NULL, "Unknown error occured in game.", "Error", MB_OK); } SAFE_DELETE (game); // free memory before exit return 0; } //============================================================================= // window event callback function //============================================================================= LRESULT WINAPI WinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { return (game->messageHandler(hwnd, msg, wParam, lParam)); }