Existe uma maneira melhor de criar esse loop de jogo? (C ++/Windows)
-
05-07-2019 - |
Pergunta
Estou trabalhando em um jogo do Windows e tenho isso:
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;
}
E estou me perguntando se há uma maneira melhor de fazer isso (ignorando os temporizadores etc. por agora) do que ter game_cont
ser global. Em suma, eu preciso poder sair do tempo WinMain
a partir de WinProc
, de modo que, se o usuário pressionar o fechamento do jogo de uma maneira que o jogo esteja no menu do jogo, o programa não continuará sendo executado na memória. (Como fez quando testei isso sem o game_cont..
declaração em WinProc
.
Ah, e em uma nota lateral, GameRun
é basicamente um bool que retorna falsa quando o jogo termina e é verdadeiro o contrário.
Solução
Sim, use PeekMessage, é o padrão no desenvolvimento de jogos.
Esta é a melhor abordagem, acredito:
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;
}
}
}
Além disso, olhe para isto (especialmente a primeira resposta)
Outras dicas
Você poderia fazer game_cont
static
para o seu arquivo principal que tem WinMain
/WinProc
, mas não conheço uma estrutura significativamente melhor.
Não, não faça isso.
WM_QUIT
é sua bandeira. GetMessage
O valor de retorno indica quando WM_QUIT
é encontrado.
Sua janela principal nunca receberá WM_QUIT
, como não é enviado para uma janela. WM_CLOSE
chamará DestroyWindow
Por padrão, para que você não precise de nenhum manuseio especial para isso. Lidar com WM_DESTROY
ligando PostQuitMessage
, o que resulta em WM_QUIT
em seu tópico, o valor de retorno especial de GetMessage
, e interrompe seu loop de despacho de mensagem.