Вопрос:

JavaFX KeyEvents задерживается при использовании robot.moveMouse ()

java javafx 3d delay keyevent

236 просмотра

1 ответ

21 Репутация автора

Я пытаюсь написать какую-то 3D-игру с видом от первого лица на JavaFX, и пока это работает довольно хорошо.

Я использую встроенную форму JavaFX и классы PerspectiveCamera для рендеринга изображения на сцену.

Но для всех ключевых событий входная задержка составляет около 1-2 секунд.

Лаги появляются только:

  • как только программа переключается в полноэкранный режим (даже если она переключена обратно в оконный режим, они все еще там, но не тогда, когда программа только началась)

  • и камера поворачивается с помощью мыши незадолго до нажатия / отпускания кнопки

Например: я нажимаю W, чтобы двигаться вперед и одновременно перемещаю мышь. Если я отпущу W сейчас, игрок все равно будет двигаться вперед на 1-2 секунды. Без движения мышью этого не происходит.

Вот как отслеживается вход:

scene.setOnKeyPressed(e -> keyPressed(e));
scene.setOnKeyReleased(e -> keyReleased(e));

и (для keyReleased (e) то же самое только с "false")

private void keyPressed(KeyEvent e) {
    if (e.getCode().toString() == "W") w = true;
    if (e.getCode().toString() == "A") a = true;
    if (e.getCode().toString() == "S") s = true;
    if (e.getCode().toString() == "D") d = true;
}

Для движения камеры я использую эту функцию:

private void mouseMovement(){
    if(primaryStage.isFocused()){
        mxdelta = MouseInfo.getPointerInfo().getLocation().getX() - centerx;
        mydelta = MouseInfo.getPointerInfo().getLocation().getY() - centery;

        // Rotate Camera
        cry += mxdelta * sens; // cry = camera rotation around y-axis
        crx -= mydelta * sens; // crx = camera rotation around x-axis

        // move curser back to the center of the screen
        robot.mouseMove(centerx, centery);
    }
}

Если я уберу "robot.mouseMove (centerx, centery);" все отлично работает Также, если я контролирую движение камеры с помощью клавиш со стрелками, то никаких лагов тоже нет.

Весь игровой цикл упакован в JavafX AnimationTimer, который дает стабильную частоту кадров.

Еще одно маленькое замечание: поскольку программа только что запущена, появляется много маленьких заиканий. Как только я переключаюсь в полноэкранный режим, программа запускается без сбоев (конечно, несмотря на задержку ввода. Но у мыши вообще нет задержки ввода).

Я могу опубликовать полный код, если необходимо, или загрузить видео, если проблема недостаточно ясна.

Автор: Ohalama Источник Размещён: 22.08.2016 09:00

Ответы (1)


0 плюса

21 Репутация автора

Итак, я понял, что запуск всего цикла main / game в другом потоке, по- видимому, решает проблему . Больше нет запаздывания на входе и заикания тоже нет.

Если есть кто-то, кто заинтересован в моем решении, вот оно:

Сначала я упаковал весь материал из игрового цикла в функцию "mainloop ()", которая выглядит примерно так:

public void mainloop(){
    mouseMovement(); // <- full function is in the question above
    updatePosition();
    collisionDetection();
}

Затем я создал новый поток и поместил в него только mainloop () :

Thread t = new Thread() {
    public void run() {
        Platform.runLater(new Runnable() {
            public void run() {
                mainloop();}
        });
    }
};
t.setDaemon(true);

Наконец поток вызывается с использованием AnimationTimer :

new AnimationTimer() {
    @Override public void handle(long now) {
        t.run();
    }
}.start();

Я не уверен, является ли это эффективным способом решения этой проблемы, но, похоже, он работает.

Автор: Ohalama Размещён: 23.08.2016 03:39
Вопросы из категории :
32x32