2013-04-21 2 views
5

Я видел несколько консольных игр, где экран обновляется/очищается без раздражающего мигания. Я пробовал множество решений, вот что я как сейчас:Экран очистки консоли Win32 C++ без мигания

while(true) 
{ 
    if(screenChanged) //if something needs to be drawn on new position 
    { 
    COORD coordScreen = { 0, 0 }; 
    DWORD cCharsWritten; 
    CONSOLE_SCREEN_BUFFER_INFO csbi; 
    DWORD dwConSize; 
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 

    GetConsoleScreenBufferInfo(hConsole, &csbi); 
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y; 
    FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten); 
    GetConsoleScreenBufferInfo(hConsole, &csbi); 
    FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten); 
    SetConsoleCursorPosition(hConsole, coordScreen); 
    } 

    ///printf all the time graphics on their right position with SetConsoleCursorPosition 

    Sleep(33.3f); 
} 

Тем не менее, я получаю некоторое минимальное мерцание. У кого-нибудь есть идеи?

+1

It возможно, что эти игры не написаны как консольные приложения Windows, а как приложение DOS, которые используют различные графические режимы и пишут пиксели непосредственно в графическую память. –

+0

@Captain Перечитайте первое предложение. Исходный код не для «консольных игр», которые он видел, исходный код - это то, что он пытался. –

+0

@CodyGray Oops;) –

ответ

4

Причина, по которой это происходит, заключается в том, что дисплей обновляется между временем, когда вы очищаете экран консоли и на самом деле рисуете его. Обычно это может происходить так быстро, что вы никогда его не видите, но время от времени вы делаете это в нужное время, и вы испытываете мерцание.

Один из лучших вариантов заключается в том, чтобы создать внеэкранный буфер того же размера и ширины, что и экран консоли, сделать весь текст и обновить его, а затем отправить весь буфер на экран консоли с помощью WriteConsoleOutput. Убедитесь, что вы учитываете, что буфер экрана должен содержать как текстовую, так и атрибутную информацию в том же формате, что и консоль.

BOOL WINAPI WriteConsoleOutput(
    _In_  HANDLE hConsoleOutput, 
    _In_  const CHAR_INFO *lpBuffer, 
    _In_  COORD dwBufferSize, 
    _In_  COORD dwBufferCoord, 
    _Inout_ PSMALL_RECT lpWriteRegion 
); 
+0

Разве это не то, что делают ncurses? – user1255410

+1

Не уверен, я не смотрел на отдельные части napurses WinAPI –

+4

Общим термином для этого является «двойная буферизация». Это классический метод, позволяющий устранить видимость частично отображаемого экрана, в данном случае пустого экрана. –

3

Вы хотите сделать эквивалент двойной буферизации. Использование CreateConsoleScreenBuffer и SetConsoleActiveScreenBuffer API вызовов, вы можете изменить закадровый буфер, а затем включите буфера, как мы привыкли в старые времена :) Вот статья, которая объясняет, как: http://msdn.microsoft.com/en-us/library/windows/desktop/ms685032%28v=vs.85%29.aspx

Смежные вопросы