【问题标题】:Limit FPS in Libgdx game with Thread.sleep() doesn't work使用 Thread.sleep() 限制 Libgdx 游戏中的 FPS 不起作用
【发布时间】:2014-01-18 12:44:10
【问题描述】:

我正在使用 libgdx 为 android 开发一个小游戏,并希望将 fps 限制为 30 以节省电池。问题是它不起作用。 fps 刚刚从 60 下降到 56。

这是代码的一部分:(它在渲染部分的末尾)

System.out.print("\nFPS: " + Gdx.graphics.getFramesPerSecond() + "\n");

    if(Gdx.graphics.getDeltaTime() < 1f/30f)
    {
        System.out.print("DeltaTime: " + Gdx.graphics.getDeltaTime() + " s\n");
        float sleep = (1f/30f-Gdx.graphics.getDeltaTime())*1000;
        System.out.print("sleep: " + sleep + " ms\n");
        try
        {
            Thread.sleep((long) sleep);
        }
        catch (InterruptedException e)
        {
            System.out.print("Error...");
            e.printStackTrace();
        }
    }

这是输出:

FPS: 56
DeltaTime: 0.014401722 s
sleep: 18.931612 ms

FPS: 56
DeltaTime: 0.023999143 s
sleep: 9.334191 ms

FPS: 56
DeltaTime: 0.010117603 s
sleep: 23.215733 ms

提前谢谢...

【问题讨论】:

    标签: java android libgdx limit frame-rate


    【解决方案1】:

    我在网上找到了一个解决方案,稍微修改了一下。它完美无缺!只需将此函数添加到您的类:

    private long diff, start = System.currentTimeMillis();
    
    public void sleep(int fps) {
        if(fps>0){
          diff = System.currentTimeMillis() - start;
          long targetDelay = 1000/fps;
          if (diff < targetDelay) {
            try{
                Thread.sleep(targetDelay - diff);
              } catch (InterruptedException e) {}
            }   
          start = System.currentTimeMillis();
        }
    }
    

    然后在你的render 函数中:

    int fps = 30; //limit to 30 fps
    //int fps = 0;//without any limits
    @Override
    public void render() {
       //draw something you need
       sleep(fps); 
    }
    

    【讨论】:

      【解决方案2】:
      import com.badlogic.gdx.utils.TimeUtils;
      
      public class FPSLimiter {
      
          private long previousTime = TimeUtils.nanoTime();
          private long currentTime = TimeUtils.nanoTime();
          private long deltaTime = 0;
          private float fps;
      
          public FPSLimiter(float fps) {
              this.fps = fps;
          }
      
          public void delay() {
              currentTime = TimeUtils.nanoTime();
              deltaTime += currentTime - previousTime;
              while (deltaTime < 1000000000 / fps) {
                  previousTime = currentTime;
                  long diff = (long) (1000000000 / fps - deltaTime);
                  if (diff / 1000000 > 1) {
                      try {
                          Thread.currentThread().sleep(diff / 1000000 - 1);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  currentTime = TimeUtils.nanoTime();
                  deltaTime += currentTime - previousTime;
                  previousTime = currentTime;
              }
              deltaTime -= 1000000000 / fps;
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可能会将Libgdx's "non-continuous rendering" 作为降低 Android 帧速率的替代方法。就目前而言,您的应用的 UI 线程将一直处于休眠状态,因此您的应用的响应速度可能会有所下降(尽管休眠 30 秒并没有那么长)。

        根据您的游戏,非连续渲染支持可能会让您进一步降低帧速率(只要图形没有变化且没有预期的输入,您就不需要绘制新帧)。

        【讨论】:

        • 看起来它不是完全可移植的(iOS仍然不支持这个?)最好不要依赖FPS
        【解决方案4】:

        使用可能会使用这个

        Thread.sleep((long)(1000/30-Gdx.graphics.getDeltaTime()));
        

        将 30 的值更改为所需的 FPS。

        【讨论】:

        • 这个答案是错误的,不要用!! getDeltaTime() 以 SECONDS 为单位返回时间,其余时间以 MILLISECONDS 为单位。此外,除法是基于整数的,所以你会得到过多的舍入。
        • 为什么会被接受? @emyaz,你能不接受吗?
        猜你喜欢
        • 1970-01-01
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 2023-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-14
        相关资源
        最近更新 更多