2012-05-07 3 views
1

저는 40x20 블록의 캐릭터를 애니메이션으로 만들고 싶습니다. 나는 cout -ing입니다. system("cls");으로 콘솔을 지우고 캐릭터의 다음 블록을 즉시 표시하고 싶습니다. 현재 다음 블록이 타자기 스타일로 나타납니다.console cout animation - C++

내 질문에 대한 가장 간단한 대답은 타자기 스타일을 사용하는 대신 한 번에 20 줄 40 자의 문자 스트림을 사용하는 것입니다.

하여 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

I은 ​​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

두 개의 2D 배열을 유지하지 않을 것입니다. 나는 오 스트링 스트림 (ostringstream)을 즉시 시전 할 수있는 방법을 가지고 있습니다. – michaellindahl

+1

@michaellindahl : 나는 * 오히려 * 나를 위해 코드를 작성하고 싶지만 이봐, 우리 모두는 때때로 실망에 직면 해있다. 하루가 끝나면 작동하는 코드가 있거나 오히려하지 않을 일을 피한 것에 대한 만족감이 있습니다.) – HighCommander4

+0

Touche. 두 개의 2D 배열을 유지하는 것이 무엇을 의미하는지 모르겠습니다 ... 예제 코드를 알려주시겠습니까? 나는 초심자 인 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