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

Я работаю над игрой для 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 быть глобальным. Короче говоря, мне нужно иметь возможность выйти из while в WinMain из WinProc, так что, если пользователь нажимает на закрытие игры не так, как в меню игры, программа не будет продолжать работать в объем памяти. (Как это было, когда я проверял это без оператора game_cont.. в WinProc.

Да, и на заметке: GameRun - это, по сути, bool, который возвращает false, когда игра заканчивается, и true в противном случае.

Ответы [ 4 ]

10 голосов
/ 26 ноября 2009

Да, используйте 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;
        }
    }
} 

Кроме того, посмотрите на это (особенно первый ответ)

1 голос
/ 26 ноября 2009

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

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

0 голосов
/ 06 декабря 2013

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

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

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

0 голосов
/ 26 ноября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...