JavaFX Animation Timer类未以60 fps的速度上限

时间:2019-10-02 19:42:48

标签: java javafx

所以我一直在用JavaFX制作游戏,我想将fps始终保持在60。但是,尽管通常JavaFX中的Animation Timer类将fps的上限设置为60,但就我而言不是这样。我已经尝试了很多不同的解决方案,这些解决方案显示在各行中:

    System.setProperty("quantum.multithreading", "false");
    System.setProperty("javafx.animation.fullspeed", "true");
    System.setProperty("javafx.animation.pulse", "60");
    System.setProperty("javafx.animation.framerate", "60");

但是,这些解决方案不起作用。我做了更多的错误检查,并认为我的错误是由屏幕刷新率更改了JavaFX中的上限fps引起的,即,当屏幕刷新率为60Hz时fps为60fps,但是当屏幕刷新率为48Hz时fps为48fps。我想知道如何停止基于屏幕刷新率的fps更改并将其保持在恒定的60fps。这是我的下面的代码,任何帮助将不胜感激:

package battlegame;

import java.io.IOException;

import battlegame.graphics.Assets;
import battlegame.input.KeyboardController;
import battlegame.world.World;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;

public class Game extends Application{

    public static int screenWidth = 960;
    public static int screenHeight = 540;

     private final long[] frameTimes = new long[100];
     private int frameTimeIndex = 0 ;
     private boolean arrayFilled = false ;

    private Canvas canvas;
    private boolean upTyped = true;
    private Stage stage;
    private Scene scene;
    private Group group;
    private GraphicsContext g;
    private final LongProperty lastUpdateTime = new SimpleLongProperty(0);
    private static World currentWorld;
    private static KeyboardController keyController;

    public Game() {
        keyController = new KeyboardController();
    }

    public void begin(String args[]) {
        launch(args);
    }

    public void initialise() throws IOException {
        canvas = new Canvas(screenWidth, screenHeight);
        group = new Group(canvas);
        scene = new Scene(group);
        g = canvas.getGraphicsContext2D();
        Assets.init();
        currentWorld = new World("/testlvl.txt");
        currentWorld.init();

        System.setProperty("quantum.multithreading", "false");
        System.setProperty("javafx.animation.fullspeed", "true");
        System.setProperty("javafx.animation.pulse", "60");
        System.setProperty("javafx.animation.framerate", "60");

    }

    @Override
    public void start(Stage primaryStage)throws Exception {
        initialise();

        final AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long timestamp) {
                long oldFrameTime = frameTimes[frameTimeIndex] ;
                frameTimes[frameTimeIndex] = timestamp ;
                frameTimeIndex = (frameTimeIndex + 1) % frameTimes.length ;
                if (frameTimeIndex == 0) {
                    arrayFilled = true ;
                }
                if (arrayFilled) {
                    long elapsedNanos = timestamp - oldFrameTime ;
                    long elapsedNanosPerFrame = elapsedNanos / frameTimes.length ;
                    double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame ;
                    System.out.println(frameRate);
                }

                if (lastUpdateTime.get() > 0) {
                    tick();
                    render();
                }
                lastUpdateTime.set(timestamp);
            }
        };
        stage = primaryStage;
        stage.getIcons().add(new Image(Game.class.getResourceAsStream("/GameIcon.png")));
        stage.setScene(scene);
        stage.setResizable(true);
        stage.setOnCloseRequest(event -> {
            timer.stop();
        });
        stage.show();
        scene.addEventHandler(KeyEvent.KEY_PRESSED, (key) -> {
              if(upTyped && (key.getCode() == KeyCode.W || key.getCode() == KeyCode.UP || key.getCode() == KeyCode.SPACE)) {
                  keyController.up = true;
                  upTyped = false;
              }
              if(key.getCode() == KeyCode.A || key.getCode() == KeyCode.LEFT) {
                  keyController.left = true;
              }
              if(key.getCode() == KeyCode.S || key.getCode() == KeyCode.DOWN) {
                  keyController.down = true;
              }
              if(key.getCode() == KeyCode.D || key.getCode() == KeyCode.RIGHT) {
                  keyController.right = true;
              }
              if(key.getCode() == KeyCode.Z || key.getCode() == KeyCode.O || key.getCode() == KeyCode.ENTER) {
                  keyController.select = true;
              }
              if(key.getCode() == KeyCode.P || key.getCode() == KeyCode.X) {
                  keyController.action = true;
              }

        });
        /*scene.addEventHandler(KeyEvent.KEY_TYPED, (key) -> {
              if(key.getCode() == KeyCode.W || key.getCode() == KeyCode.UP || key.getCode() == KeyCode.SPACE) {
                  keyController.up = true;
                  System.out.println("YoIghtL/Kkjkjas");
              }
        });*/

        scene.addEventHandler(KeyEvent.KEY_RELEASED, (key) -> {
              if(key.getCode() == KeyCode.W || key.getCode() == KeyCode.UP || key.getCode() == KeyCode.SPACE) {
                  keyController.up = false;
                  upTyped = true;
              }
              if(key.getCode() == KeyCode.A || key.getCode() == KeyCode.LEFT) {
                  keyController.left = false;
              }
              if(key.getCode() == KeyCode.S || key.getCode() == KeyCode.DOWN) {
                  keyController.down = false;
              }
              if(key.getCode() == KeyCode.D || key.getCode() == KeyCode.RIGHT) {
                  keyController.right = false;
              }
              if(key.getCode() == KeyCode.Z || key.getCode() == KeyCode.O || key.getCode() == KeyCode.ENTER) {
                  keyController.select = false;
              }
              if(key.getCode() == KeyCode.P || key.getCode() == KeyCode.X) {
                  keyController.action = false;
              }     });



        timer.start();   
    }


    public void tick() {
        currentWorld.tick();
        keyController.tick();
    }

    public void render() {
        g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        currentWorld.render(g);
    }

    public static void main(String[] args){
        launch();
    }

    public static KeyboardController getKeyController(){
        return keyController;
    }

    public static World getCurrentWorld() {
        return currentWorld;
    }



    }

0 个答案:

没有答案
相关问题