为什么使用clock_gettime不满足游戏循环中的条件

时间:2019-03-23 09:13:18

标签: c clock curses

我已经用C语言编写了一个简单的游戏,snake。我从使用睡眠(nanosleep)的游戏循环开始,但是现在我尝试通过使用计算机时钟(clock_gettime)使其变为软实时。简化的示例使用clock_gettime来获取程序的时间跨度,根据需要工作。但是,当我尝试每秒进行20次更新(移动)时,无法达到此更新/“移动蛇”。此代码没有任何“图形”来显示问题。 clock_gettime()使用 struct timespec ,它具有两个值,以秒为单位的时间和以纳秒为单位的时间。我制作了一个函数timespec_to_ms,将值对(秒/纳秒)转换为单秒级谷值,但它提供了非常高的输出值。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <ncurses.h>

#define BILL 1E9

int is_timespec_b_greater_than_a(struct timespec a, struct timespec b){
    if(b.tv_sec > a.tv_sec){
        return 1;

    }else if(b.tv_sec == a.tv_sec){
        if(b.tv_nsec > a.tv_nsec){
            return 1;
        }
    }
    return 0;
}

//I made this to get a single time-value
long timespec_to_ms(struct timespec tim){
    return tim.tv_sec * 1000 + (tim.tv_nsec / 1000000L);
}

long get_clock_ms(){
    struct timespec temp;
    if (clock_gettime(CLOCK_REALTIME, &temp) == -1) return -1;

    return timespec_to_ms(temp);
}

struct timespec add_ms(struct timespec tim, int milliseconds){

    int sec = tim.tv_sec;
    int ms1 = tim.tv_nsec / 1000000;

    int add_sec = milliseconds / 1000; //if above 1000, > 0
    milliseconds = milliseconds % 1000; //limit to 0-999

    if(ms1 + milliseconds >= 1000){
        sec++;
    }

    sec += add_sec;

    ms1 = (ms1 + milliseconds) % 1000;

    struct timespec new;

    new.tv_sec = sec;
    new.tv_nsec = ms1 * 1000000;

    return new;
}

int kbhit (WINDOW * stds){
    int ch = wgetch(stds);

    if(ch != ERR){
        ungetch(ch);
        return 1;
    } else {
        return 0;
    }
} 

int main(){
    struct timespec start, end, klockan, s_f;
    double accum, comp;
    int count = 0, diff=0, c1, c2, interval_ms = 50;
    long clock, lasttime;

    WINDOW * stds = initscr();
    clear();
    clock_gettime(CLOCK_REALTIME, &start);

    if (clock_gettime(CLOCK_REALTIME, &s_f)== -1) printf("error1");

    lasttime = get_clock_ms();

    while(1){
        clock = get_clock_ms();

        if(clock > lasttime + interval_ms){
            count++;
            lasttime = clock;
        }

        if(kbhit(stds)){
            break;
        }

    }

    clock_gettime(CLOCK_REALTIME, &end);

    accum = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / BILL;

    endwin();
    printf("%lf %d\t%d %ld\t%ld\n", accum, count, interval_ms, lasttime, clock);

    return 0;
}

运行一次(不久后按下键盘)后,我出门了:

1.142959 0    50 1553331597068    1553331597068

因此该程序运行了1.1秒钟,它从未进入“游戏移动”范围,间隔为50,并且“ ms”计时器(上次时间和时钟)非常高。

我在VirtualBox中使用Ubuntu Server 16(在Win 10中),并使用编译程序。

gcc -o rt rt.c -lncurses

0 个答案:

没有答案