用户计时器在第一次使用后出错,无论我等待多长时间都会返回零

User timer bugs out after first use and returns zero no matter how long I wait

本文关键字:等待 长时间 返回 第一次 计时器 出错 用户      更新时间:2023-10-16

我试图创建一个测试用户反应速度的游戏,在游戏的第一部分,我使用计时器来随机选择用户何时按下。在那之后,我想计算用户按下所需的时间,但无论我等待按下多长时间,它总是返回"0秒后你按下了1",1是我按下的键。如何使它的时间用户也可取毫秒而不是秒。我对C++真的很陌生,并试图在书籍的帮助下自学,但我真的陷入了困境。有什么帮助吗?

#include <iostream
#include <time.h>
using namespace std;

class timer { 
private:
    unsigned long startTime; 
public:
    void start() {
        startTime = clock(); 
}
unsigned long elapsedTime() { 
    unsigned long t = (clock() - startTime) / CLOCKS_PER_SEC;
    return t;
}
bool isTimeout(unsigned long seconds) {
    return seconds >= elapsedTime();
}


int main() {
    srand(time(NULL)); 
    int keyPressed = (0);
    unsigned long secondsBeforeStart = (rand() % 11);
    timer tBefore;
    timer tAfter;
    bool waitingInput = false;
    bool gameIsFinished = false;
    tBefore.start();
    cout << "timer started . . ." << endl;
    while(true)
    {
        if(tBefore.elapsedTime() >= secondsBeforeStart && !waitingInput && !gameIsFinished) //waiting the game to draw "Tryck nu!"
    {
            waitingInput = true;
            cout << "Tryck nu!" << endl;
            tAfter.start();
    }
        if(waitingInput && !gameIsFinished) // if "Tryck nu" has appeared => waiting the player to press a key
    {
            // cout << "DEBUG : tAfter == " << tAfter.elapsedTime(); << endl;
            cin >> keyPressed;
            if( keyPressed != 0) // if player press the key
            {
            cout << "you have pressed " << keyPressed << " after " << tAfter.elapsedTime() << " seconds" << endl;
            gameIsFinished = true;
        }
    }
        if(gameIsFinished)
    {
            cout << "Well done, you can push a button to restart the game" << endl;
            cin >> keyPressed;
            if( keyPressed != 0) // if player press the key
        {
                cout << "Restarting" << endl;
                waitingInput = false;
                gameIsFinished = false;
                secondsBeforeStart = (rand() % 11);
                tBefore.start();
                cout << "timer started . . ." << endl;
        }
    }
}
}

问题可能是您的elapsedTime((函数:

unsigned long elapsedTime() { 
    unsigned long t = (clock() - startTime) / CLOCKS_PER_SEC;
    return t;
}

如果计数少于CLOCKS_PER_SEC刻度(这是非常可能的(,除法将返回0,因为操作数是整数类型。

试着先显示时钟滴答声,然后再担心将时间转换为秒。

clock()告诉您进程使用的CPU节拍数,但您的进程在输入时被阻止时不会占用任何CPU时间!所以这对这类问题没用。

您应该使用一个不同的函数,它可以为您提供墙时间(即真实世界时间的绝对流逝(,特别是如果您想要毫秒分辨率的话。考虑gettimeofday()

#include <sys/time.h>
class timer
{ 
private:
    double startTime;
    /**
     * This function wraps the call to `gettimeofday()`,
     * so that you may simply use it instead of `clock()`.
     *
     * You will still have to remove your `CLOCKS_PER_SEC`
     * logic and switch from `unsigned long` to `double`,
     * though.
     */
    double getTime()
    {
       timeval tv;
       gettimeofday(&tv, 0);
       return tv.tv_sec + tv.tv_usec/1e9;
    }
public:
    void start()
    {
        startTime = getTime(); 
    }
    double elapsedTime()
    { 
        return getTime() - startTime;
    }
    bool isTimeout(double seconds) {
        return seconds >= elapsedTime();
    }
};

(课堂现场演示(

在实际应用程序中,我实际上会将clock_gettimeCLOCK_MONOTONIC一起使用,以避免本地时间跳跃的影响。不过,在这个简单的学习案例中,这可能太多了。