OS: Windows 10 Compiler: Visual Studio 2017 C++ version: 14, apparently
I am making a text adventure game for school. On some screens, I want paragraphs of text to end with a blinking line of text that says, "Press "ENTER" to continue", with animated ellipses, and when the user presses "Enter", that line is cleared and the next paragraph follows. I wrote some code, that I thought would work, but that particular line doesn't change from
Press ENTER to continue
over time. Here is the minimum "working" example:
#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();
}
Not only does the text not "animate", I have to press ENTER twice to continue to the next line.
I am asking this question here because I have been doing research for almost an hour, knowing that I have tried to figure this out before, and the only solutions offered are
- Not in my language
- Regardless of that, erase the entire screen, not just the line I am on, which turns the entire console into a 'light-bright' with no room for other content.
- Appear to be using ancient compilers or OS.
Can somebody please help me (and maybe the rest of the internet) close the book on this topic? A solution that works in this context can work in many other contexts. Thank you always for your time.
ALSO: Please keep in mind that this is a drastically stripped-down version of my project to isolate this problem.
UPDATE: I have succeeded in making it "blink". I just need the break condition to work, because right now it just prevents the while loop from starting over (inexplicably):
#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: I have asynchronous methods now but I am unable to get the "ENTER" key to register consistently. It always takes at least 2 attempts for the while loop to exit, and I don't know if that's because of memory issues (wouldn't that be pathetic), inherent flaws with , or a logic error on my part. Here is my minimum working example. I am so close, please offer COMPLETE SOLUTIONS!
#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();
}