C'è un modo migliore per creare questo loop di gioco? (C ++ / Windows)
-
05-07-2019 - |
Domanda
Sto lavorando a un gioco Windows e ho questo:
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 mi chiedo se esiste un modo migliore per farlo (ignorando i timer e per ora) piuttosto che avere game_cont
globale. In breve, devo essere in grado di uscire da WinMain
da WinProc
, in modo che se l'utente preme il pulsante di chiusura del gioco in un modo diverso da quello del gioco nel menu di gioco, il programma non continuerà a funzionare in memoria. (Come ha fatto quando l'ho provato senza l'istruzione game_cont ..
in WinProc
.
Oh, e su una nota a margine, GameRun
è fondamentalmente un bool che ritorna falso quando il gioco finisce, e vero altrimenti.
Soluzione
Sì, usa PeekMessage , è lo standard nello sviluppo del gioco.
Questo è l'approccio migliore, credo:
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;
}
}
}
Inoltre, guarda questo (specialmente la prima risposta)
Altri suggerimenti
Puoi rendere game_cont
statico
nel tuo file principale che ha WinMain
/ WinProc
, ma io non conoscere una struttura significativamente migliore.
No, non farlo.
WM_QUIT
è la tua bandiera. Il valore restituito GetMessage
indica quando viene rilevato WM_QUIT
.
La tua finestra principale non riceverà mai WM_QUIT
, poiché non viene inviata a una finestra. WM_CLOSE
chiamerà DestroyWindow
per impostazione predefinita, quindi non è necessario alcun trattamento speciale per questo. Gestisci WM_DESTROY
chiamando PostQuitMessage
, che risulta in WM_QUIT
sul tuo thread, lo speciale valore di ritorno da GetMessage
e interrompe il ciclo di invio dei messaggi.