I am writing a game similar to the Fallout shelter part where they explore the wasteland. I would like the game to do something every minute like say some dialogue or find an item etc, but I cant seem to get a decent clock to work, and I havent found anything reliable on the web, at least anything that doesnt use Sleep(), maybe something that uses chrono?. I would like the code to use C++ only. Here's what I have so far, please excuse the bad code, I havent gotten around to cleaning it up yet.
in your Explore() somewhere? This function still seems a bit rough because you still need conditions for stopping. Perhaps you want to explore for 10 seconds at most or so.
But generally to answer your q, start a thread, have it do <action> and have it sleep for the tickrate (don't sleep in main thread), before possibly doing another action.
Only his comment was platform specific (or more technically, unspecified). In fact, technically a time_t value is pretty much opaque. It doesn't necessarily even indicate seconds, but I don't know of any implementations where it doesn't. It's a C function anyway, and C++ has better time functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include <iostream>
#include <chrono>
void wait(double seconds) {
auto start = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff;
do {
diff = std::chrono::high_resolution_clock::now()-start;
} while (diff.count() < seconds);
}
int main() {
std::cout << "Start\n";
wait(5); // wait for 5 seconds
std::cout << "End\n";
}
Note however that this is a "busy wait" loop. icy1's thread idea is better:
1 2 3 4 5 6 7 8 9 10 11 12 13
#include <iostream>
#include <chrono>
#include <thread>
int main() {
usingnamespace std::chrono_literals;
std::cout << "Start" << std::endl; // endl to flush output
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for(5s);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
std::cout << "Done: " << elapsed.count() << " ms\n";
}
Thank you for your correction. I don't know much about Linux os. But the timer still works.
Did I say the timer doesn't work? I was just wondering where you got the Jan 1, 2000 date. Did you just pull it out of your ass or do you have a reference? Linux was just an example. You should run the code on your system and see what it says.
Your eloquent manner of calling it like it is never fails to be refreshing. The example posted here came from some old tutorial I saved but can't remember from where. I refer back to old code but don't save the source for some reason.
When I run your time code it tells me that it is something like 48 and a half years. Which proves conclusively, that the comment about the year 2000, beyond any doubt, came from the depths of my ass.
#include <iostream>
#include <vector>
#include <string>
#include <chrono>
#include <thread>
#include <atomic>
#include <random>
usingnamespace std::chrono_literals;
class Game
{
public:
Game() :
tick_rate_(2),
quotes_{"\"Stay hungry. Stay foolish.\" --Steve Jobs",
"\"Good artists copy; great artists steal.\" --Pablo Picasso",
"\"Argue with idiots, and you become an idiot.\" --Paul Graham",
"\"Be yourself; everyone else is already taken.\" --Oscar Wilde",
"\"Simplicity is the ultimate sophistication.\" --Leonardo Da Vinci"}
{
}
~Game()
{
ticking_.store(false);
}
void Tick()
{
while(ticking_.load())
{
TickAction();
std::this_thread::sleep_for(tick_rate_);
}
}
void TickAction()
{
std::cout << '\n' << quotes_[rd_() % quotes_.size()] << '\n';
}
void Explore(std::chrono::milliseconds millis)
{
auto elapsed = 0ms;
auto interval = 50ms;
ticking_.store(true);
std::thread t(&Game::Tick, this);
t.detach();
while (elapsed < millis)
{
std::cout << '.' << std::flush;
elapsed += interval;
std::this_thread::sleep_for(interval);
}
ticking_.store(false);
std::cout << "\n\nDone exploring!\n";
}
private:
std::chrono::seconds tick_rate_;
std::atomic<bool> ticking_;
std::random_device rd_;
std::vector<std::string> quotes_;
};
int main()
{
Game g;
g.Explore(10'000ms);
return 0;
}
Was thinking something like this. Explore for 10 seconds, outputting some quote every 2 seconds. (I also chose to output right away, so you get a total of 6 quotes). Also outputs "." every interval check, even with a std::flush (expensive operation when done so often) just for demonstration purposes -- this is how often it checks whether it hits that 10 second mark