Search code examples
c++windowsc++-chrono

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.


Solution

  • 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");
    }