evilhoomans42
evilhoomans42

Reputation: 75

How to make a timer that counts down from 30 by 1 every second?

I want to make a timer that displays 30, 29 etc going down every second and then when there is an input it stops. I know you can do this:

    for (int i = 60; i > 0; i--)
    {
        cout << i << endl;
        Sleep(1000);
    }

This will output 60, 59 etc. But this doesn't allow for any input while the program is running. How do I make it so you can input things while the countdown is running?

Context

This is not a homework assignment. I am making a text adventure game and there is a section where an enemy rushes at you and you have 30 seconds to decide what you are going to do. I don't know how to make the timer able to allow the user to input things while it is running.

Upvotes: 0

Views: 634

Answers (2)

landings
landings

Reputation: 770

Your game is about 1 frame per second, so user input is a problem. Normally games have higher frame rate like this:

#include <Windows.h>
#include <iostream>

int main() {
    // Initialization
    ULARGE_INTEGER initialTime;
    ULARGE_INTEGER currentTime;
    FILETIME ft;
    GetSystemTimeAsFileTime(&ft);
    initialTime.LowPart = ft.dwLowDateTime;
    initialTime.HighPart = ft.dwHighDateTime;
    LONGLONG countdownStartTime = 300000000; // 100 Nano seconds
    LONGLONG displayedNumber = 31; // Prevent 31 to be displayed

    // Game loop
    while (true) {
        GetSystemTimeAsFileTime(&ft); // 100 nano seconds
        currentTime.LowPart = ft.dwLowDateTime;
        currentTime.HighPart = ft.dwHighDateTime;

        //// Read Input ////
        bool stop = false;
        SHORT key = GetKeyState('S');
        if (key & 0x8000)
            stop = true;

        //// Game Logic ////
        LONGLONG elapsedTime = currentTime.QuadPart - initialTime.QuadPart;
        LONGLONG currentNumber_100ns = countdownStartTime - elapsedTime;
        if (currentNumber_100ns <= 0) {
            std::cout << "Boom!" << std::endl;
            break;
        }
        if (stop) {
            std::wcout << "Stopped" << std::endl;
            break;
        }

        //// Render ////
        LONGLONG currentNumber_s = currentNumber_100ns / 10000000 + 1;
        if (currentNumber_s != displayedNumber) {
            std::cout << currentNumber_s << std::endl;
            displayedNumber = currentNumber_s;
        }
    }

    system("pause");
}

Upvotes: 2

El Stepherino
El Stepherino

Reputation: 620

If you're running this on Linux, you can use the classic select() call. When used in a while-loop, you can wait for input on one or more file descriptors, while also providing a timeout after which the select() call must return. Wrap it all in a loop and you'll have both your countdown and your handling of standard input.

https://linux.die.net/man/2/select

Upvotes: 0

Related Questions