I started writing this game
from scratch yesterday, and I wasn't completely new to C++'s future
library.
I only use the std::async
class to launch asynchronously the conio.h
defined getch
function, to get user's input without stopping the execution of the rest, which has to update the screen each 0.1s (I did it with chrono
).
char choice;
while (choice != 'q') {
auto input = std::async(std::launch::async, getch);
while (input.wait_for(std::chrono::milliseconds(FRAME_DURATION)) != std::future_status::ready) {
if (game::status == PAUSED) // if the game is paused, do nothing
continue; // just wait for the next char
moveAllBullets(); // move all bullets
updateField(); // update the field
printField(); // print the field
for (auto& enemy: game::enemies) {
if (!enemy.alive)
continue;
if (rand()%5 == 0) {
enemy.turn();
enemy.fireBullet();
} else if (rand()%2 == 0) {
enemy.movePlayer(game::random::directionalChar());
}
}
if (rand()%50 == 0)
game::random::addEnemy(rand()%48+1, rand()%18+1);
if (game::player.auto_fire)
game::player.fireBullet();
game::player.points++;
}
printField(); // print the field
choice = input.get();
switch (choice) {
case 'q': case 'Q':
return;
case 'p': case 'P':
game::status = PAUSED;
break;
case 'r': case 'R':
game::status = PLAYING;
break;
case 'w': case 'W': case 'a': case 'A': case 's': case 'S': case 'd': case 'D':
if (game::status == PLAYING)
game::player.movePlayer(choice);
break;
case 'f': case 'F':
if (game::status == PLAYING && game::player.ammunitions > 0 && !game::player.auto_fire)
game::player.fireBullet();
break;
case 'x': case 'X':
game::player.auto_fire = !game::player.auto_fire;
break;
}
}
This is the content of the function mainloop
, which gets called at the beginning of the program.
My doubts were about this two lines:
auto input = std::async(std::launch::async, getch);
while (input.wait_for(std::chrono::milliseconds(FRAME_DURATION)) != std::future_status::ready)
The refresh is quite slow for a 20x50 matrix, so I was wondering if the problem could be that input.wait_for
, since I know that sometimes listening for an event may affect the performance. Also I don't know if it depends on the code or if printing 20×50=1000 characters is slow.
Is wait_for
the "problem"? In this case is there any alternative to wait_for
?
Edit
Would the use of multithreading instead of asynchronous functions improve the performance? Is there any difference in terms of what happens to the I/O?
Edit (1)
The most effective changes were (in this order):
- Inserting
std::ios_base::sync_with_stdio(false)
at the beginning of the program - Replacing all the
system("cls")
as suggested byG. Sliepen
- Replacing
std::endl
with'\n'
(just once, in theprintField
function, I don't need to flush in that case, right?)
I'll anyway follow some of your other suggestions, starting from that ones about multithreading and curses libraries, that I'm sure will be very useful.
Thank you so much, I'm new to this community and I've never recieved such acceptance in a SE community, and I've never learned so much with a single question too.