2012-05-07 67 views
1

我想動畫一個40x20的字符塊,我是cout -ing。我想用system("cls");清除控制檯,然後立即出現下一個字符塊。目前下一個街區是打字機風格。控制檯cout動畫 - C++

對我的問題最簡單的答案只是一次有20行40字符oss流cout,而不是打字機的風格。

Main.cpp的:

mazeCreator.cout(); 
    Sleep(5000); 
    system("cls"); 

COUT()

void MazeCreator::cout() { 
    char wallChar = (char) 219; 
    char pavedChar = (char) 176; 
    char lightChar = ' '; 
    char startChar = 'S'; 
    char finishChar = 'F'; 
    char errorChar = '!'; 
    char removedWallChar = 'R'; 
    char landmarkLocationChar = 'L'; 

    ostringstream oss; 
    for (int row = 0; row < rows; row++) { 
     oss << " "; 
     for (int col = 0; col < columns; col++) { 
      if (mazeArray[row][col] == wall) 
       oss << wallChar; 
      else if (mazeArray[row][col] == paved) 
       oss << pavedChar; 
      else if (mazeArray[row][col] == light) 
       oss << lightChar; 
      else if (mazeArray[row][col] == start) 
       oss << startChar; 
      else if (mazeArray[row][col] == finish) 
       oss << finishChar; 
      else if (mazeArray[row][col] == removedWall) 
       oss << removedWallChar; 
      else if (mazeArray[row][col] == landmarkLocation) 
       oss << landmarkLocationChar; 
      else 
       oss << errorChar; 
     } 
     oss << "\n"; 
    } 
    oss << "\n\n"; 

    cout << oss.str(); 
} 
+0

我認爲這是爲Windows? –

+0

你需要提供更多的細節。 –

+0

你的意思是你可以看到它被繪製?您可以使用緩衝區:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682122(v=vs.85).aspx – chris

回答

2

你可以保持您的代碼中2個二維陣列,一個用文字在屏幕上當前塊(姑且稱之爲cur)和一個與下一個塊(姑且稱之爲next)。

假設cur現在存儲在屏幕上的塊。通過寫入next陣列來設置下一個塊。當您準備將其放置在屏幕上時,請同時循環使用curnext,並且僅適用於不同的字符,請使用SetConsoleCursorPosition跳轉到該位置並寫入新字符。

完成之後,將next的內容複製到cur並轉到下一個塊。

UPDATE:下面是一個例子:

class console_buffer 
{ 
public: 
    console_buffer(int rows, int columns) 
        // start out with spaces 
       : cur(rows, vector<char>(columns, ' ')), 
        next(rows, vector<char>(columns, ' ')) 
    { 
    } 

    void sync() 
    { 
     // Loop over all positions 
     for (int row = 0; row < cur.size(); ++row) 
      for (int col = 0; col < cur[row].size(); ++col) 

       // If the character at this position has changed 
       if (cur[row][col] != next[row][col]) 
       { 
        // Move cursor to position 
        COORD c = {row, col}; 
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); 

        // Overwrite character 
        cout.put(next[row][col]); 
       } 

     // 'next' is the new 'cur' 
     cur = next; 
    } 

    void put(char c, int row, int col) 
    { 
     next[row][col] = c; 
    } 
private: 
    vector<vector<char> > cur; 
    vector<vector<char> > next; 
}; 

... 

int main() 
{ 
    console_buffer buf(40, 20); 

    // set up first block 
    ... some calls to buf.put() ... 

    // make first block appear on screen 
    buf.sync(); 

    // set up next block 
    ... some calls to buf.put() 

    // make next block appear on screen 
    buf.sync(); 

    // etc. 
} 
+0

我寧願不維護兩個二維數組。我寧願有一種方法來立即制定ostringstream。 – michaellindahl

+1

@michaellindahl:我寧願*只爲自己寫代碼,但嘿,我們都時不時地面對失望。在一天結束的時候,你要麼有可用的代碼,要麼避免做你不願意做的事情的滿意度;) – HighCommander4

+0

Touche。我不太確定你的意思是我維護兩個二維陣列......你想給我一些示例代碼嗎?我是C++的新手 – michaellindahl

0

可以使用CreateConsoleScreenBuffer實現雙緩衝。沿着這些線應該工作。一段時間以前,我曾經用過這個,所以它可能不完美。

HANDLE current = GetStdHandle (STD_OUTPUT_HANDLE); 

HANDLE buffer = CreateConsoleScreenBuffer (
    GENERIC_WRITE, 
    0, 
    NULL, 
    CONSOLE_TEXTMODE_BUFFER, 
    NULL 
); 

WriteConsole (/*fill with what you're drawing*/); 

system ("cls"); //clear this screen before swapping  
SetConsoleActiveScreenBuffer (buffer); 

WriteConsole (/*do it to the other one now*/); 

system ("cls");  
SetConsoleActiveScreenBuffer (current); //swap again 

//repeat as needed 

CloseHandle (buffer); //clean up 
+0

如何在WriteConsole中使用os流?我正在尋找的最簡單的方法就是立即打印一個oss流。 – michaellindahl

+0

呃,即使'cout'也不能一下子把它全部弄清楚。如果您在輸出之間重複執行操作,它會開始閃爍。要從stringstream獲取C樣式數據,可以使用'os.str()。c_str()'。 – chris

+0

這是給我一個錯誤。是的,我是一個白癡。強烈建議手持。 – michaellindahl