1

私がしている 40x20 の文字ブロックをアニメーション化したいと思いますcoutsystem("cls");コンソールをクリアしてから、キャラクターの次のブロックをすぐに表示したいと思います。現在、次のブロックはタイプライター スタイルで作成されています。

私の質問に対する最も簡単な答えは、タイプライター スタイルではなく、20 行 x 40 文字の oss ストリーム カウントを一度に作成することです。

Main.cpp:

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

カウト()

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();
}
4

2 に答える 2

2

コード内で2つの2D配列を維持できます。1つは画面上の現在の文字ブロック(それを呼び出しますcur)、もう1つは次のブロック(それを呼び出しますnext)です。

現在画面に表示されているブロックを保存するとcurします。next配列に書き込んで次のブロックを設定します。画面に配置する準備ができたら、ループしcurnext同時に、異なる文字の場合のみ、を使用SetConsoleCursorPositionしてその場所にジャンプし、新しい文字を書き込みます。

それが終わったら、の内容をにコピーnextcurて次のブロックに進みます。

更新:例を次に示します。

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.
}
于 2012-05-07T04:27:07.223 に答える
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
于 2012-05-07T04:26:22.400 に答える