Есть ли лучший способ создать этот игровой цикл? (C ++ / Windows)
-
05-07-2019 - |
Вопрос
Я работаю над игрой для Windows, и у меня есть это:
bool game_cont;
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_QUIT: case WM_CLOSE: case WM_DESTROY: game_cont = false; break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(/*lots of parameters*/)
{
//tedious initialization
//game loop
while(game_cont)
{
//give message to WinProc
if(!GameRun()) game_cont = false;
}
return 0;
}
и мне интересно, есть ли лучший способ сделать это (игнорируя таймеры и т. д. прямо сейчас), чем сделать game_cont
глобальным. Короче говоря, мне нужно иметь возможность выйти в то время как в WinMain
из WinProc
, так что если пользователь нажимает на закрытие из игры способом, отличным от игры в меню игры программа не будет работать в памяти. (Как это было, когда я проверял это без оператора game_cont ..
в WinProc
.
Да, и на заметку, GameRun
- это, по сути, bool, который возвращает false, когда игра заканчивается, и true в противном случае.
Решение
Да, используйте PeekMessage , это стандарт в разработке игр. Р>
Я считаю, что это лучший подход:
int Run()
{
MSG msg;
while(true)
{
if(::PeekMessage(&msg,0,0,0 PM_REMOVE))
{
if(msg.message == WM_QUIT ||
msg.message == WM_CLOSE ||
msg.message == WM_DESTROY)
break;
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
//Run game code
if(!GameRun())
break;
}
}
}
Также обратите внимание на этот (особенно первый ответ) р>
Другие советы
Вы можете сделать game_cont
static
в своем главном файле с WinMain
/ WinProc
, но я не не знаю о значительно лучшей структуре.
Нет, не делай этого.
WM_QUIT
является вашим флагом. Возвращаемое значение GetMessage
указывает, когда WM_QUIT
встречается.
Ваше главное окно никогда не получит WM_QUIT
, так как оно не отправлено окну. WM_CLOSE
будет вызывать DestroyWindow
по умолчанию, поэтому вам не требуется никакой специальной обработки для этого. Обработайте WM_DESTROY
, вызвав PostQuitMessage
, что приведет к WM_QUIT
в вашем потоке, специальному возвращаемому значению из GetMessage
и останавливает цикл отправки сообщений.