动画ASCII艺术在c中闪烁

我正在用c(windows)制作一个ASCII艺术游戏,但由于某种原因,当我玩的时候,它会以明显的随机间隔闪烁,而且大多数时候我什么都看不见。有人能解释为什么或者如何解决这个问题吗

这是我的代码:

const int WIDTH=20,HEIGTH=5;
建筑面积=(宽度)*高度;
常数int gl=高度-2//地面
常量浮点增量=0.1f//帧速率
字符scr[区域]//用于显示内容的字符串
字符输入;
int posx=10,posy=gl-1//球员位置
int-vel=0//球员速度
而(1)
{
//TODO:播放器输入
对于(i=0;i<AREA;i++)//渲染部件
{
如果(i%宽度==0&i!=0)
{
scr[i]='\n';
持续
}
如果(地板(i/宽度)>=gl)//i在地面上
{
scr[i]=';
持续
}
scr[i]='';
}
//设置球员位置
scr[posy*WIDTH+posx+1]='@';
scr[(位置+1)*宽度+posx+1]='@';
系统(“cls”);//清除终端
printf(scr);//打印屏幕
usleep(delta*1000);//睡眠
}

输出:

@
[email protected]
...................►↓@

它工作,但它闪烁

出现问题的一个可能原因是,当您调用sleep函数usleep时,输出缓冲区中可能有输出等待。在这种情况下,您应该始终在睡眠前通过调用函数fflush(stdout)刷新所有输出

此外,使用系统(“cls”)效率极低。通常最好使用Console Functions API,或者,如果您针对的是Windows 10或更高版本的平台,也可以使用Console虚拟终端序列

如果您决定使用Console Functions API,那么您将需要使用主要功能来替换系统(“cls”)GetStdHandle以获取输出句柄,以及SetConsoleCursorPosition。这样,您就不必清除整个屏幕,只需覆盖正在更改的屏幕部分。我还建议您将printf替换为WriteConsole,否则您可能会遇到缓冲问题

如果这不能解决闪烁问题,那么也有可能使用双缓冲。控制台函数API和控制台虚拟终端序列都支持这一点

使用Console Functions API时,可以使用函数CreateConsolesScreenbuffer创建一个新的要写入的缓冲区,而无需立即显示。这将允许您首先完成构建下一个屏幕,而不会在这样做时出现任何闪烁(因为它尚未显示)。构建完下一个屏幕后,可以使用函数SetConsoleActiveScreenBuffer显示它

控制台虚拟终端序列通过支持备用屏幕缓冲区提供类似的功能

发表评论