加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

使用robot.moveMouse()时,JavaFX KeyEvents被延迟

发布时间:2020-12-15 02:16:20 所属栏目:Java 来源:网络整理
导读:我正在尝试在 JavaFX中编写某种第一人称视图3D游戏,到目前为止该运动效果还不错. 我正在使用JavaFX的内置形状和PerspectiveCamera类将图像渲染到场景中. 但是所有关键事件的输入延迟大约为1-2秒. 仅出现滞后: 一旦程序切换到全屏(即使切换回窗口,它们仍然存
我正在尝试在 JavaFX中编写某种第一人称视图3D游戏,到目前为止该运动效果还不错.

我正在使用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中,它提供了稳定的帧速率.

另一个小观察:由于该计划刚刚推出,有许多小口吃.一旦我切换到全屏程序,程序运行黄油顺利(尽管输入滞后当然.但鼠标根本没有输入延迟).

如果需要,我可以发布完整的代码,如果问题不够清楚,我可以上传视频.

解决方法

所以我发现在另一个线程中运行整个主/游戏循环显然可以解决问题.没有输入滞后,口吃也消失了.

如果有人对我的解决方案感兴趣,那么它是:

首先,我在游戏循环中打包了函数“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();

我不确定这是否是解决此问题的有效方法,但它似乎正在起作用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读