相关疑难解决方法(0)

System.currentTimeMillis vs System.nanoTime

精度与 精确

我想知道的是在更新我的对象在游戏中的位置时是否应该使用System.currentTimeMillis()System.nanoTime()?它们的运动变化与自上次呼叫后经过的时间成正比,我希望尽可能精确.

我读过不同的操作系统之间存在一些严重的时间分辨率问题(即Mac/Linux的分辨率几乎为1毫秒,而Windows的分辨率为50毫秒).我主要在Windows上运行我的应用程序,50ms分辨率似乎非常不准确.

有没有比我列出的两个更好的选择?

有什么建议/意见吗?

java timer time-precision

370
推荐指数
7
解决办法
37万
查看次数

如何在使用Android的GLSurfaceView.RENDERMODE_CONTINUOUSLY时限制帧率?

我有一个在Android中运行JNI的C++游戏.由于场景复杂性,帧速率从大约20-45fps变化.任何高于30fps的东西对于游戏都是愚蠢的; 它只是燃烧电池.我想将帧速率限制为30 fps.

  • 我可以切换到RENDERMODE_WHEN_DIRTY,并使用Timer或ScheduledThreadPoolExecutor来requestRender().但这增加了一大堆额外的移动部件,这些部件可能会或可能不会始终正确地工作.
  • 当事情快速运行时,我尝试注入Thread.sleep(),但这对于小时间值似乎根本不起作用.它可能只是将事件支持到队列中,而不是实际上暂停.

是否有隐藏在API中的"capFramerate()"方法?有任何可靠的方法吗?

android opengl-es

21
推荐指数
2
解决办法
3万
查看次数

Android:了解OnDrawFrame,FPS和VSync(OpenGL ES 2.0)

一段时间以来,我经历了一段间歇性的"口吃",即在我的Android游戏中运行的精灵.这是一款非常简单的2D OpenGL ES 2.0游戏.(这是一个持续存在的问题,我多次重访过).

在我的游戏循环中,我有2个'定时器' - 一个用于记录前一秒的帧数,另一个用于计算从当前onDrawFrame迭代结束到下一个开始的时间(以毫秒为单位).

这就是我发现的:

当不渲染任何东西时,我得到60fps(大部分),并且每次调用onDrawFrame时,它报告自己需要更长的16.667ms.现在,如果我渲染一些东西(无论是1个四边形还是100个四边形,结果是相同的),我得到60fps(大部分)但是现在,只有大约20%的onDrawFrame调用报告自己需要更长的时间比上次通话时的16.667毫秒.

我真的不明白为什么会发生这种情况,首先,为什么当onDrawFrame没有做任何事情时,它被称为"慢慢" - 更重要的是,为什么任何GL调用(一个简单的四边形),仍然需要时间onDrawFrame调用超过16.667ms(尽管频率低得多).

我应该说当onDrawFrame报告从最后一次迭代开始超过16.667ms时,它几乎总是伴随着FPS下降(到58或59),但并非所有时间,有时候,FPS保持不变.相反,有时当FPS下降时,onDrawFrame在最后一次迭代完成的16.667ms内被调用.

所以......

我正在尝试修复我的游戏循环并根除这些"口吃" - 其他一些注意事项:

  • 当我进行方法分析时,它会显示glSwapBuffers,有时需要很长时间
  • 当我执行GL跟踪时,大多数场景表示在不到1毫秒内渲染,但有时奇数帧需要3.5-4毫秒 - 相同的场景.除了花费的时间之外没有什么变化
  • 几乎每次丢帧时,或onDrawFrame报告长时间延迟(或两者都有),都会出现视觉故障,但不是每次都有.大视觉故障似乎与多个'延迟'onDrawFrame调用和/或丢帧一致.
  • 我不认为这是一个场景复杂性问题有两个原因:1)即使我渲染我的场景两次,它也不会让问题变得更糟,我仍然在大多数情况下,偶尔会掉落60FPS,只是和以前一样,2),即使我把场景剥光,我仍然会遇到问题.

我显然是在误解某些东西,所以我们将不胜感激.

OnDrawFrame

@Override
public void onDrawFrame(GL10 gl) {

    startTime = System.nanoTime();        
    fps++;                        
    totalTime = System.nanoTime() - timeSinceLastCalled;    

    if (totalTime > 16667000) {     
        Log.v("Logging","Time between onDrawFrame calls: " + (totalTime /(double)1000000));
    }

    //Grab time
    newTime = System.currentTimeMillis() * 0.001;
    frameTime = newTime - currentTime; //Time the last frame took

    if (frameTime > 0.25)
        frameTime = 0.25;

    currentTime = …
Run Code Online (Sandbox Code Playgroud)

performance android game-loop opengl-es-2.0

12
推荐指数
1
解决办法
3200
查看次数

System.currentTimeMillis()方法真的返回当前时间吗?

基于链接中提出的想法,我实现了几种不同的"睡眠方法".其中一种方法是"二进制睡眠",它看起来像这样:

while (System.currentTimeMillis() < nextTimeStamp)
{
sleepTime -= (sleepTime / 2);
sleep(sleepTime);
}
Run Code Online (Sandbox Code Playgroud)

因为检查是否已经到达下一个时间步骤发生在开头I,所以预计该方法运行时间太长.但模拟误差的累积分布(预期时间 - 实时)如下所示:alt text http://img267.imageshack.us/img267/4224/errorvscummulativearran.jpg

有人知道我为什么会得到这个结果吗?也许方法System.currentTimeMillis()没有真正返回当前时间?

BR,

马库斯

@irreputable

当我进行评估时,我还使用德国统计程序创建了钟形曲线.因为无法更改标题,所以这里是所有相关项目的英文翻译:

Häufigkeit=频率

费勒=错误

Mittelwert =平均值

Std-Abw =标准偏差

alt text http://img694.imageshack.us/img694/2254/bellcurve.jpg

java time sleep

6
推荐指数
1
解决办法
5217
查看次数