Класс JavaFX Animation Timer не ограничен скоростью 60 кадров в секунду - PullRequest
0 голосов
/ 02 октября 2019

Итак, я делал игру с JavaFX и хотел, чтобы fps всегда был на 60. Однако, хотя обычно класс таймера анимации в JavaFX ограничивает число кадров в секунду на 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, т. Е. Когда частота обновления экрана составляет 60 Гц, частота кадров составляет 60 кадров в секунду, а когда частота обновления экрана равна 48 Гц, частота кадров составляет 48 кадров в секунду. Мне было интересно, как бы я остановил изменение частоты кадров на основе частоты обновления экрана и держал ее на постоянной скорости 60 кадров в секунду. Вот мой код ниже, любая помощь будет оценена:

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;
    }



    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...