¿Hay una mejor manera de crear este bucle de juego? (C ++ / Windows)
-
05-07-2019 - |
Pregunta
Estoy trabajando en un juego de Windows y tengo esto:
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;
}
y me pregunto si hay una mejor manera de hacer esto (ignorando los temporizadores & amp; c. por ahora) que hacer que game_cont
sea global. En resumen, necesito poder salir del tiempo en WinMain
de WinProc
, de modo que si el usuario presiona el cierre del juego de una manera diferente a la del juego en el menú del juego, el programa no seguirá ejecutándose en la memoria. (Como lo hice cuando probé esto sin la instrucción game_cont ..
en WinProc
.
Ah, y en una nota al margen, GameRun
es básicamente un bool que devuelve falso cuando el juego termina, y verdadero de lo contrario.
Solución
Sí, use PeekMessage , es El estándar en el desarrollo de juegos.
Este es el mejor enfoque, creo:
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;
}
}
}
También, vea esto (especialmente la primera respuesta)
Otros consejos
Puedes hacer que game_cont
static
en tu archivo principal, que tiene WinMain
/ WinProc
, pero no lo hago. No conozco una estructura significativamente mejor.
No, no hagas eso.
WM_QUIT
es su bandera. El valor devuelto por GetMessage
indica cuando se encuentra WM_QUIT
.
Su ventana principal nunca recibirá WM_QUIT
, ya que no se envía a una ventana. WM_CLOSE
llamará a DestroyWindow
de manera predeterminada, por lo que no necesita ningún tratamiento especial para eso. Maneje WM_DESTROY
llamando a PostQuitMessage
, que da como resultado WM_QUIT
en su hilo, el valor de retorno especial de GetMessage
, y detiene el bucle de envío de mensajes.