我正试图让我的游戏保持在60fps,但是我的代码变得奇怪,比如“2-8000 fps”为什么这不是60?
public static void main(String[] args) {
joglplat m = new joglplat();
while(true){
long startTime = System.nanoTime() / 1000000;
try
{
// 123456: 6 zeros => 16ms
long nsToSleep = 16000000 - (System.nanoTime() - lastFrame);
System.out.println("ns: " + nsToSleep);
lastFrame = System.nanoTime();
if(nsToSleep > 0)
{
System.out.println("ns2: " + (nsToSleep/1000));
System.out.println("ns3: " + (nsToSleep%1000));
Thread.sleep(nsToSleep/16000000, (int)(nsToSleep % 1000));
}
else
{
Thread.yield(); // Only necessary if you want to guarantee that
// the thread yields the CPU between every frame
}
}
catch(Exception e){
e.printStackTrace();
}
m.controls();
m.update();
m.repaint();
System.out.println("framerate: " + (System.nanoTime() / 1000000 - startTime));
}
}
答案 0 :(得分:1)
我怀疑这是由Thread.sleep()的不准确引起的:
导致当前正在执行的线程 为了睡觉(停止执行) 指定的毫秒数加上 指定的纳秒数, 受精确和准确的影响 系统计时器和调度程序。该 线程不会失去任何所有权 显示器
你有必要像这样保持帧率吗?也许你可以更全面地解释你想要完成的事情?
答案 1 :(得分:1)
您的输出是程序运行的秒数,而不是帧率。你应该将你的帧数(你没有收集的)除以总运行时间。
要获得帧数,只需在游戏循环外添加一个新变量,并在每次递增时增加...
public static void main(String[] args) {
long frames = 0;
joglplat m = new joglplat();
while(true){
frames++;
// other code here
System.out.println("framerate: " + ((System.nanoTime() / 1000000 - startTime) / frames ) );
}
}
但请注意,这将为您提供整个程序执行期间的平均帧速率。另外两个选项是获得瞬时帧率,以及过去N帧的平均帧率。
所有样式合二为一(未经测试/未经编译,因此可能会出现一些错误,但应该让您从正确的方向开始):
public static void main(String[] args) {
long startTime = System.nanoTime();
long lastFrameTime = startTime;
long frames = 0;
int framesToAverage = 10;
long[] frameTimes = new long[framesToAverage];
joglplat m = new joglplat();
while(true){
// logic here
long currentFrameDuration = System.nanoTime() - lastFrame;
lastFrameTime = System.nanoTime();
long instantFramerate = currentFrameDuration / 1000000;
int currentFrameIndex = frames % frameTimes.length;
frameTimes[currentFrameIndex] = currentFrameDuration;
frames++;
long averageFramerate = ( ( lastFrameTime - startTime) / frames ) / 1000000;
long instantFramerate = currentFrameDuration / 1000000;
if( frames > frameTimes.length ) { // if it isn't, we don't have enough data yet
int firstFrameIndex = currentFrameIndex + 1;
if( firstFrameIndex > frameTimes.length ) {
firstFrameIndex = 0;
}
long averageFrameratePerN = ( ( frameTimes[currentFrameIndex] - frameTimes[firstFrameindex] ) / frameTimes.length ) / 1000000;
}
// yield/sleep here
}
}