c++ - C ++如何在不擦除屏幕的情况下闪烁单行文本?
问题描述
操作系统:Windows 10 编译器: Visual Studio 2017 C++ 版本: 14,显然
我正在为学校制作文字冒险游戏。在某些屏幕上,我希望文本段落以闪烁的文本行结束,上面写着“按“ENTER”继续”,带有动画省略号,当用户按“Enter”时,该行被清除,下一段跟随。我写了一些我认为可以工作的代码,但是那条特定的行并没有从
Press ENTER to continue
随着时间的推移。这是最小的“工作”示例:
#include <iostream>
#include <string>
#include <chrono>
#include <thread>;
using namespace std;
using namespace this_thread; // sleep_for, sleep_until
using namespace chrono_literals; // ns, us, ms, s, h, etc.
using chrono::system_clock;
//class to implement UI methods
class UI {
public:
UI() {}
void printTitleCard() {
cout << "+---------------------------+" << endl;
cout << "| \"A Text Adventure\" |" << endl;
cout << "| by |" << endl;
cout << "| Me |" << endl;
cout << "+---------------------------+" << endl << endl;
}
void intro() {
cout << "Your mother warned you about getting into cars with strangers." << endl;
cout << "She didn't say anything about vans, true, and it did have a" << endl;
cout << "friendly moustache on the front bumper, but you knew the risks." << endl;
cout << "Now you're waking up in the wilderness with no wallet and no clues..." << endl;
pressEnterToContinue();
cout << "...and there's something on your shoes." << endl;
}
void pressEnterToContinue() {
//This prompts the user to press "ENTER" to continue
while (1) {
string str = "Press ENTER to continue";
cout << str;
sleep_until(system_clock::now() + 0.25s); // wait a quarter-second
cout << string(str.length(), '\b'); // delete printed line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.25s); // wait a quarter-second
cout << string(str.length(), '\b'); // delete printed line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.25s); // wait a quarter-second
cout << string(str.length(), '\b'); // delete printed line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.25s); // wait a quarter-second
cout << string(str.length(), '\b'); // delete printed line
if (cin.get()) break;
}
cin.ignore();
}
};
void main()
{
UI ui;
//Title Card
ui.printTitleCard();
//Intro
ui.intro();
}
不仅文本没有“动画”,我还必须按两次 ENTER 才能继续下一行。
我在这里问这个问题是因为我已经做了将近一个小时的研究,知道我之前已经尝试过解决这个问题,并且提供的唯一解决方案是
- 不是我的语言
- 不管怎样,抹掉整个屏幕,而不仅仅是我所在的行,这会将整个控制台变成一个“明亮的”,没有其他内容的空间。
- 似乎正在使用古老的编译器或操作系统。
有人可以帮我(也许是互联网的其他人)关闭关于这个主题的书吗?在这种情况下工作的解决方案可以在许多其他情况下工作。永远感谢您的时间。
还:请记住,这是我的项目的一个彻底精简的版本,用于隔离这个问题。
更新:我已成功使其“闪烁”。我只需要 break 条件来工作,因为现在它只是阻止 while 循环重新开始(莫名其妙):
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
using namespace std;
using namespace this_thread; // sleep_for, sleep_until
using namespace chrono_literals; // ns, us, ms, s, h, etc.
using chrono::system_clock;
//class to implement UI methods
class UI {
public:
UI() {}
void printTitleCard() {
cout << "+---------------------------+" << endl;
cout << "| \"A Text Adventure\" |" << endl;
cout << "| by |" << endl;
cout << "| Me |" << endl;
cout << "+---------------------------+" << endl << endl;
}
void intro() {
cout << "Your mother warned you about getting into cars with strangers." << endl;
cout << "She didn't say anything about vans, true, and it did have a" << endl;
cout << "friendly moustache on the front bumper, but you knew the risks." << endl;
cout << "Now you're waking up in the wilderness with no wallet and no clues..." << endl;
pressEnterToContinue();
cout << "...and there's something on your shoes." << endl;
}
void pressEnterToContinue() {
//This prompts the user to press "ENTER" to continue
while (1) {
string str = "Press ENTER to continue";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
cout << string(str.length(), ' ');; //print spaces
cout << string(str.length(), '\b'); // go to front of line
sleep_until(system_clock::now() + 0.5s); // wait a half-second
//if (cin.get()) break;
}
cin.ignore();
}
};
void main()
{
UI ui;
//Title Card
ui.printTitleCard();
//Intro
ui.intro();
}
UPDATE2:我现在有异步方法,但我无法获得“ENTER”键来一致地注册。退出 while 循环总是需要至少 2 次尝试,我不知道这是否是因为内存问题(那不是很可悲)、 的固有缺陷或我的逻辑错误。这是我的最小工作示例。我是如此接近,请提供完整的解决方案!
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
//#include <C:/Program Files/boost/boost_1_71_0/boost/atomic.hpp>
using namespace std;
using namespace this_thread; // sleep_for, sleep_until
using namespace chrono_literals; // ns, us, ms, s, h, etc.
using chrono::system_clock;
//class to implement UI methods
class UI {
public:
UI() {}
void printTitleCard() {
cout << "+---------------------------+" << endl;
cout << "| \"A Text Adventure\" |" << endl;
cout << "| by |" << endl;
cout << "| Me |" << endl;
cout << "+---------------------------+" << endl << endl;
}
void intro() {
cout << "Your mother warned you about getting into cars with strangers." << endl;
cout << "She didn't say anything about vans, true, and it did have a" << endl;
cout << "friendly moustache on the front bumper, but you knew the risks." << endl;
cout << "Now you're waking up in the wilderness with no wallet and no clues..." << endl;
pressEnterToContinue();
cout << "...and there's something on your shoes." << endl;
}
void pressEnterToContinue() {
using namespace std::literals;
string str;
auto f = std::async(std::launch::async, [str] {
string userStr;
getline(cin, userStr);
if (userStr == "") {
cout << string(str.length(), '\b'); // go to front of line
cout << string(str.length(), ' ');; //print spaces
cout << string(str.length(), '\b'); // go to front of line
cin.ignore();
return;}
});
while (f._Is_ready()==false/*f.wait_for(1s) != std::future_status::ready*/) {
str = "Press ENTER to continue";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
cout << string(str.length(), ' ');; //print spaces
cout << string(str.length(), '\b'); // go to front of line
sleep_until(system_clock::now() + 0.5s); // wait a half-second
}
}
};
void main()
{
UI ui;
//Title Card
ui.printTitleCard();
//Intro
ui.intro();
}
解决方案
我知道了。这解决了 Windows 平台上 C++ 的 3 个常见问题解答(我不认为第二个是新颖或需要的解决方案):
- 如何在不清除屏幕的情况下使一行文本“闪烁”
- 如何删除和覆盖控制台行
- 如何从连续运行的异步循环中运行和逃脱。
这是我最小的实际工作示例:
编辑:好的,所以仍然存在一个缺陷:如果您尝试再次运行 pressEnterToContinue() 函数,则循环仅运行一次。这可能与我如何设置循环条件有关。将不胜感激反馈。
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>
using namespace std;
using namespace this_thread; // sleep_for, sleep_until
using namespace chrono_literals; // ns, us, ms, s, h, etc.
using chrono::system_clock;
//class to implement UI methods
class UI {
public:
UI() {}
void printTitleCard() {
cout << "+---------------------------+" << endl;
cout << "| \"A Text Adventure\" |" << endl;
cout << "| by |" << endl;
cout << "| Me |" << endl;
cout << "+---------------------------+" << endl << endl;
}
void intro() {
cout << "Your mother warned you about getting into cars with strangers." << endl;
cout << "She didn't say anything about vans, true, and it did have a" << endl;
cout << "friendly moustache on the front bumper, but you knew the risks." << endl;
cout << "Now you're waking up in the wilderness with no wallet and no clues..." << endl;
pressEnterToContinue();
cout << "...and there's something on your shoes." << endl;
}
void pressEnterToContinue() {
using namespace std::literals;
string str;
auto f = std::async(std::launch::async, [str] {
string userStr;
getline(cin, userStr);
if (userStr == "\r") {
cout << string(str.length(), '\b'); // go to front of line
cout << string(str.length(), ' ');; //print spaces
cout << string(str.length(), '\b'); // go to front of line
return;}
});
while (f._Is_ready()==false/*f.wait_for(1s) != std::future_status::ready*/) {
str = "Press ENTER to continue";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
//repeat
str += ".";
cout << str;
sleep_until(system_clock::now() + 0.5s); // wait a half-second
cout << string(str.length(), '\b'); // go to front of line
cout << string(str.length(), ' ');; //print spaces
cout << string(str.length(), '\b'); // go to front of line
sleep_until(system_clock::now() + 0.5s); // wait a half-second
}
}
};
int main()
{
UI ui;
//Title Card
ui.printTitleCard();
//Intro
ui.intro();
return 0;
}
推荐阅读
- angular - 找不到可监视的对象以进行 navigateBackToLanding
- python - 计算 x1 ^ (x2 ^ (x3 ^ (... ^ xn))) 的最后一位(十进制)
- angular - HTTP 服务调用绑定到 HTML 元素
- node.js - AWS NodeJS Lambda 函数中的缓存内存
- github - !git push:-- 致命:无法读取“https://github.com”的用户名:没有这样的设备或地址||google colaboratory
- javascript - 是否可以使用摊牌解析 Markdown 文件中的标题?
- android - 离子图标不能与 Android 上的离子日期时间一起点击
- javascript - 如何在画布中创建撤消功能?
- fluentd - fluentd:多个过滤器和匹配的一个来源
- javascript - 如何在 for 循环中使用变量递增或递减?