我正在写一个旧式的ASCII DOS-Prompt游戏。老实说,我正试图模仿ZZT,以了解更多关于这个品牌的游戏设计(即使它已经过时)
我做得很好,让我的全屏幕文本模式工作,我可以创建世界并移动而没有问题但是我找不到适合我渲染的计时方法。
我知道我的渲染和预渲染代码很快,因为如果我没有添加任何延迟()或(clock() - renderBegin)/ CLK_TCK从time.h检查渲染速度非常快。
我不想使用delay(),因为它是特定于我的知识平台的,并且在它延迟时我不能运行任何代码(如用户输入和处理)。所以我决定做这样的事情:
do {
if(kbhit()) {
input = getch();
processInput(input);
}
if(clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval) {
renderTimer = clock();
render();
ballLogic();
}
}while(input != 'p');
哪个应该在“理论”中工作得很好。问题是当我运行这段代码(将RenderInterval设置为0.0333或30fps)时,我不会得到接近30fps的任何一个,我最多会得到18个。
我想也许我会尝试将RenderInterval设置为0.0以查看性能是否已经启动......它没有。我(RenderInterval为0.0)的最大值为18-20fps。
我可能因为我不断调用所有这些clock()和“将其除以”这些方法,我正在减慢CPU的速度,但是当我把渲染和ballLogic调用if语句的括号和将RenderInterval设置为0.0我再次获得了极快的渲染效果。
这对我来说没有意义,因为如果我离开了if check,它不应该运行得那么慢吗?我的意思是它仍然需要做所有的计算
BTW我正在使用Borland的Turbo C ++ V1.01进行编译
答案 0 :(得分:2)
通常通过与显示器的垂直回扫同步来实现最佳游戏体验。除了提供计时之外,这还可以让游戏在屏幕上运行更顺畅,至少如果你有一台CRT显示器连接到电脑。
在80x25文本模式下,垂直回扫(在VGA上)发生70次/秒。我不记得EGA / CGA上的频率是否相同,但我很确定Hercules和MDA的频率是50赫兹。通过测量20帧的持续时间,你应该对你正在处理的频率有一个足够好的估计。
让主循环像:
while (playing) {
do whatever needs to be done for this particular frame
VSync();
}
... /* snip */
/* Wait for vertical retrace */
void VSync() {
while((inp(0x3DA) & 0x08));
while(!(inp(0x3DA) & 0x08));
}
答案 1 :(得分:1)
clock()-renderTimer > RenderInterval * CLOCKS_PER_SEC
如果预先计算RenderInterval * CLOCKS_PER_SEC
部分,计算速度会更快,甚至可能更快。
答案 2 :(得分:1)
答案 3 :(得分:0)
这个怎么样:你是从x(= clock())y(= renderTimer)中减去的。 x和y都被CLOCKS_PER_SEC分割:
clock()/CLOCKS_PER_SEC-renderTimer/CLOCKS_PER_SEC > RenderInterval
写作是不是很有效率:
( clock() - renderTimer ) > RenderInterval
我在分部看到的第一个问题是你不会从中得到一个真实的数字,因为它发生在两个长的整数之间。 secons问题是,将RenderInterval * CLOCKS_PER_SEC相乘更有效率,这样就可以摆脱它,简化了操作。
添加括号可使其更易读。也许通过简化这个术语,你会更容易出错。
答案 4 :(得分:0)