2013-04-21 272 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

它有可能這些遊戲不是作爲Windows控制檯應用程序編寫的,而是作爲DOS應用程序使用各種圖形模式並將像素直接寫入圖形內存。 – 2013-04-21 12:42:52

+0

@Captain重新讀第一句。源代碼不適用於他所看到的「控制檯遊戲」,源代碼就是他所嘗試的。 – 2013-04-22 00:33:28

+0

@CodyGray哎呀;) – 2013-04-22 00:39:01

回答

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 2013-04-21 13:57:11

+1

不確定,我還沒有看過WinAPI特定的ncurses片 – 2013-04-21 14:04:05

+4

這個常見術語是「雙緩衝」。這是消除看到部分渲染屏幕的經典方法,在這種情況下是空白屏幕。 – 2013-04-21 17:52:00