Есть ли лучший способ создать этот игровой цикл? (C ++ / Windows)

StackOverflow https://stackoverflow.com/questions/1800250

Вопрос

Я работаю над игрой для 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;
        }
    }
} 

Также обратите внимание на этот (особенно первый ответ)

Другие советы

Вы можете использовать выход . Используйте atexit , чтобы убедиться, что WM_CLOSE получает в очередь сообщений, когда пора выходить.

Я не знаю, каков окончательный дизайн, но это идея.

Вы можете сделать game_cont static в своем главном файле с WinMain / WinProc , но я не не знаю о значительно лучшей структуре.

Нет, не делай этого.

WM_QUIT является вашим флагом. Возвращаемое значение GetMessage указывает, когда WM_QUIT встречается.

Ваше главное окно никогда не получит WM_QUIT , так как оно не отправлено окну. WM_CLOSE будет вызывать DestroyWindow по умолчанию, поэтому вам не требуется никакой специальной обработки для этого. Обработайте WM_DESTROY , вызвав PostQuitMessage , что приведет к WM_QUIT в вашем потоке, специальному возвращаемому значению из GetMessage и останавливает цикл отправки сообщений.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top