控制台 cout 动画 - C++
Posted
技术标签:
【中文标题】控制台 cout 动画 - C++【英文标题】:console cout animation - C++ 【发布时间】:2012-05-07 04:11:55 【问题描述】:我想为我cout
-ing 的 40x20 字符块制作动画。我想用system("cls");
清除控制台,然后立即出现下一个字符块。目前下一个区块是打字机风格。
对我的问题最简单的答案就是一次拥有 20 行 x 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();
【问题讨论】:
我认为这是针对 Windows 的? 您需要提供更多详细信息。 你的意思是你可以看到它正在绘制吗?您可以使用缓冲区:msdn.microsoft.com/en-us/library/windows/desktop/… @chris 这看起来像我想要的,但我可能需要一些帮助来实现它 什么是打字机风格? o.ô 【参考方案1】:您可以在代码中维护两个二维数组,一个包含屏幕上的当前字符块(我们称之为cur
),另一个包含下一个块(我们称之为next
)。
假设cur
存储现在屏幕上的块。通过写入next
数组来设置下一个块。当您准备好将其放在屏幕上时,同时循环遍历 cur
和 next
,仅针对它们不同的字符,使用 SetConsoleCursorPosition
跳转到该位置并写入新角色。
完成后,将next
的内容复制到cur
并继续下一个块。
更新:这是一个例子:
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.
【讨论】:
我宁愿不维护两个二维数组。我宁愿有一种方法可以立即找到 ostringstream。 @michaellindahl:我宁愿只为我自己编写代码,但是,嘿,我们都会时不时地面临失望。归根结底,您要么拥有有效的代码,要么因避免做您宁愿不做的事情而感到满足;) 触摸。我不太确定你的意思是我维护两个二维数组......你想给我一些示例代码吗?我是 C++ 的新手 @michaellindahl:你去吧。【参考方案2】:您可以使用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
【讨论】:
我如何才能将操作系统流与 WriteConsole 一起使用?我正在寻找的最简单的方法就是立即打印出一个 oss 流。 好吧,即使cout
也不能一下子把它全部放完。如果您在输出之间的时间很短的情况下重复执行此操作,它将开始闪烁。要从字符串流中获取 C 风格的数据,您可以使用 os.str().c_str()
。
这给了我一个错误。是的,我是个白痴。强烈建议手持。
@michaellindahl,什么样的错误?填写WriteConsole
应该不会太难。
WriteConsole (os.str().c_str());
说没有足够的论据。以上是关于控制台 cout 动画 - C++的主要内容,如果未能解决你的问题,请参考以下文章