我正在尝试用 C 和 ncurses 做一个小贪吃蛇游戏,我发现目前最困难的部分是等待。我以为我的代码会让主循环每秒(至少)进行一次,但它非常不规则,当 getch() 记录或不记录某些内容时会更快/更慢。
...
timeout(1000);
...
while(1)
{
if(!prey)
{
prey = TRUE;
create_prey(s, map);
}
clear();
draw_map(map, s);
refresh();
clock_gettime(CLOCK_REALTIME, &start);
flushinp();
c = getch();
clock_gettime(CLOCK_REALTIME, &end);
if(end.tv_nsec - start.tv_nsec < 1E9)
{
wait.tv_sec = end.tv_sec - start.tv_sec;
wait.tv_nsec = 1E9 - (end.tv_nsec - start.tv_nsec);
nanosleep(&wait, &wait);
}
move_snake(s, c);
}
我不会详细介绍游戏功能,因为这些功能很好用。唯一有问题的一点是 sleep 部分。我看不出哪里会失败。
感谢您的关注。
最佳答案
这个版本采用了稍微不同的方法:
- 它通过从整数时钟秒开始执行游戏刻度来简化计时计算。这将非常可靠地为您提供每秒一次更新,直到且除非更新开始需要超过一秒的时间来计算。
- 因此,它通过非阻塞读取来读取用户击键。因此,它会在获取输入之后而不是之前刷新输入缓冲区。
请注意,move_snake()
必须准备好 c
为 ERR
,表示没有输入,但这实际上并不是一个新约束。另请注意,nanosleep() 只保证 sleep 的最小持续时间,而不是确切的持续时间;这将使基于该函数(或 sleep()
)的任何实现都可能有点不规则。
timeout(0);
wait.tv_sec = 0;
while(1)
{
clock_gettime(CLOCK_REALTIME, &start);
wait.tv_nsec = 1000000000 - start.tv_nsec;
nanosleep(&wait, &wait);
if(!prey)
{
prey = TRUE;
create_prey(s, map);
}
clear();
draw_map(map, s);
refresh();
c = getch();
flushinp();
move_snake(s, c);
}
关于c - Ncurses 蛇等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27159982/