【问题标题】:Limiting FPS for my game限制我的游戏的 FPS
【发布时间】:2011-06-02 17:00:05
【问题描述】:

好的,我正在制作一个小游戏,我需要限制我的 FPS,因为当我在我非常快的计算机上玩时,我有大约 850 FPS,游戏会像,非常快,当我切换到我的旧电脑,速度慢了很多,所以我需要限制我的 FPS 才能做到这一点。如何限制我的 FPS? 我的主要游戏循环:

    public void startGame(){
    initialize();
    while(true){
        drawScreen();
        drawBuffer();
        plyMove();

        //FPS counter
        now=System.currentTimeMillis(); 
        framesCount++; 
        if(now-framesTimer>1000){
            framesTimer=now; 
            framesCountAvg=framesCount; 
            framesCount=0; 
        }

        try{
            Thread.sleep(14);
        }catch(Exception ex){}
    }
}

我如何绘制屏幕,​​以及绘制所有其他事物,球员、球等。 顺便说一句,这款游戏是乒乓球翻拍版。

    public void drawBuffer(){
    Graphics2D g = buffer.createGraphics();
    g.setColor(Color.BLACK);
    g.fillRect(0,0,600,500);
    g.setColor(Color.GREEN);
    g.fillRect(ply1.getX(),ply1.getY(),ply1.getWidth(),ply1.getHeight());
    g.setColor(Color.RED);
    g.fillRect(ply2.getX(),ply2.getY(),ply2.getWidth(),ply2.getHeight());
    g.setColor(Color.WHITE);
    g.fillOval(ball1.getX(),ball1.getY(),ball1.getWidth(),ball1.getHeight());
    g.drawString("" + framesCountAvg,10,10);
}

public void drawScreen(){
    Graphics2D g = (Graphics2D)this.getGraphics();
    g.drawImage(buffer,0,0,this);
    Toolkit.getDefaultToolkit().sync();
    g.dispose();
}

【问题讨论】:

  • 好吧,如果你的游戏速度取决于 FPS 的数量,那么整个设计就相当...糟糕。
  • 除了限制 FPS 之外,您还可以让您的游戏代码真正考虑经过的时间(例如,如果您的 FPS 高,则移动较少,如果 FPS 低,则移动更多)。这可以通过将 System.nanoTime() 从实际帧与前一帧的差异来获得。
  • 我看过了,但这并没有完全解决我的问题,我不知道如何让它工作

标签: java frame-rate


【解决方案1】:

听起来您的显示器与您的游戏引擎相关联。确保两者已断开连接。无论帧率如何,您都希望游戏以相同的速度进行。如果您的快速计算机以更快的速度重新绘制屏幕,​​如果引擎导致游戏以恒定速度运行,则没关系。

【讨论】:

  • 我对如何做到这一点有点困惑。我创建了一个主游戏循环,我将其放入 OP 中。
  • @Stan,您的主游戏循环将根据时间而不是循环进行移动/更改。
  • 我将如何根据循环制作它?如果我删除 Thread.sleep,它会达到大约 850FPS,我不希望这样。
  • 它基于一个循环。而是根据时间进行更改。这样您的游戏引擎计算事物的速度就会比您的绘画更快/更慢。
  • 更重要的是,您可能希望渲染发生在与游戏处理不同的线程中。游戏处理产生用于渲染的内容,然后渲染引擎可以选择渲染多少或多少数据。
【解决方案2】:

与其限制您的 FPS,不如让游戏在 fps 较高时不会变得非常快。

大概你有代码在每一帧都做某些事情,例如如果按下按钮,则将角色向前移动。相反,您要做的是将角色向前移动一定量,具体取决于自上一帧以来经过的时间量。

【讨论】:

    【解决方案3】:

    如前所述,您需要在游戏核心的某处将显示循环与更新循环分开,这可能是这样的

    while (1)
    {
        drawscene();
        update();
    }
    

    并且在更新中,您将时间提前了一个固定的量,例如 0.17 秒。如果您以 60fps 的速度进行绘制,那么动画将实时运行,以 850fps 的速度,一切都将被加速 14 倍(0.17*850)以防止这种情况发生,您应该让更新时间依赖。例如

    elapsed = 0;
    while (1)
    {
       start = time();
       update(elapsed); 
       drawscene();
       sleep(sleeptime);
       end = time();
    
       elapsed = end - start;
    }
    

    【讨论】:

    • 这是非常低效的。更新应该与渲染异步发生。
    【解决方案4】:

    我在评论中的意思的描述。在你的方法plyMove(); 里面我怀疑有类似的东西

    plyMove() {
        ply1.x += amountX;
        ply1.y += amountY;
    }
    

    而是根据经过的时间进行移动

    plyMove(double timeElapsed) {
        ply1.x += amountX * timeElapsed;
        ply1.y += amountY * timeElapsed;
    }
    

    您根据主循环内的时间差计算timeElapsed,并相应地对其进行缩放以获得体面的运动。

    double timePrev = System.currentTimeMillis();
    while(true) {
        double timeNow = System.currentTimeMillis();
        double elapsed = timeNow - timePrev;
    
        drawScreen();
        drawBuffer();
        plyMove(0.001 * elapsed);
    
        timePrev = timeNow;
    }
    

    【讨论】:

      【解决方案5】:

      如果你真的想要一个固定时间框架的游戏,你可以这样做:

      float timer = 0;
      float prevTime= System.currentTimeMillis();
      while(true)
      {
          draw();
      
          float currentTime = System.currentTimeMillis();
          timer += currentTime - prevTime;
      
          while (timer > UPDATE_TIME) // To make sure that it still works properly when drawing takes too long
          {
              timer -= UPDATE_TIME;
              update();
          }
      }
      

      其中 UPDATE_TIME 是您希望更新的时间间隔(以毫秒为单位)。

      【讨论】:

        【解决方案6】:

        一种方法是使用

        try {
            Thread.sleep(20);
        } catch(InterruptedException e) {}
        

        在主循环结束时。根据您的需要调整数字。

        【讨论】:

        • 这会减慢两台机器上的游戏速度。这不是 OP 想要的。
        • 好吧,这解决了游戏运行速度问题,它是 60 FPS,但它不会在我的另一台速度较慢的计算机上运行得更慢吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-08
        • 1970-01-01
        • 1970-01-01
        • 2012-02-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多