当前位置: 首页 > 知识库问答 >
问题:

javaFX-在不创建新线程的情况下创建平滑动画

糜凯泽
2023-03-14

我的javaFX项目中有一辆汽车,当空间被挤压时,汽车(节点)的位置应该改变(汽车应该平滑地跳跃)。所以我使用了一个事件处理程序来调用一个名为< code>moveUp()的方法

scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
            switch (event.getCode())
            {
                case SPACE:
                    moveUp();
                    break;
            }
        }
    });

这创建了一个新的线程,其中汽车的速度以75毫秒的间隔改变10次。

private void moveUp() {
   new Thread(new Runnable() {
       @Override
       public void run() {
           carSpeed = 10;
           for(;carSpeed>=0;carSpeed--)
           {
               try {
                   Thread.currentThread().sleep(75);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               carPosition_X+=carSpeed;
               carPosition_Y-=carSpeed;
               car.relocate(carPosition_X,carPosition_Y);
           }
           for(carSpeed=0;carSpeed<=10;carSpeed++)
           {
               try {
                   Thread.currentThread().sleep(75);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               carPosition_X+=carSpeed;
               carPosition_Y+=carSpeed;
               car.relocate(carPosition_X,carPosition_Y);
           }
       }
   }).start();
}

如果我不使用其他线程,GUI线程将被冻结,如果我不使用Thread.sleep(),汽车将突然跳跃(不顺利)。这段代码做得很好。但是我了解到 thread.start() 并不能保证线程的立即执行。如何保证立即执行?

共有1个答案

范浩宕
2023-03-14

我建议继续使用FX应用程序线程,并使用< code>AnimationTimer类。下面是一个平稳跳跃的简短演示:

private void moveUp() {
        new AnimationTimer() {
            long startTime = -1;
            double initCarPosition_Y;                

            @Override
            public void handle(long now) {
                if(startTime == -1){
                    startTime = now;
                    initCarPosition_Y = carPosition_Y;
                    carSpeedX = 3d;
                    carSpeedY = -15d;                                   
                }                   

                double time = (now - startTime) / 1E9d;
                carPosition_X += carSpeedX * time;  
                carPosition_Y += carSpeedY * time;
                if(carSpeed > 0 && initCarPosition_Y <= carPosition_Y){
                    carPosition_Y = initCarPosition_Y;
                    stop();
                }
                carSpeedY += 0.8d * time; //gravity

                car.relocate(carPosition_X, carPosition_Y);                 
            }
        }.start();
}

这种方法使您可以完全直接地控制每一帧中发生的情况。但是,javaFX 还提供了高级动画类,包括预定义的插值器和过渡。适合替代方法的可以是以下类:

  • PathTranection:允许您定义给定节点动画的点和曲线。
  • TimeLine:允许您根据节点位置等属性定义任意动画关键帧。

请注意,当您想对汽车等用户控制的演员进行动画制作时,通常使用这些高级类可能会变得具有挑战性。这些类都需要一个精确的动画持续时间。例如,当您想在按下特定键时转换节点时,您事先不知道动画的持续时间。

 类似资料:
  • 我即将对我的项目进行一个重大的技术更改,从ANT转移到Gradle。这个项目从来没有发布过--它仍在开发中。我想标记最后的旧技术版本,以便可以找到参考或逆转。但我不想暗示有任何一种释放。 然后 我之前向GitHub提交了一个支持请求,但当时他们有一些支持积压,所以我的请求被关闭了。

  • 我正在遵循Oracle的教程在JavaFX中创建TableView。在这个截图中,我复制并粘贴了代码,发现了几个错误,教程中没有提到这些错误。 TableView上的警告显示: TableView是原始类型。对泛型类型TableView的引用 表列上的警告说: 表列是一个原始类型。对泛型类型TableCol列的引用 addAll方法上的警告是: 类型安全:方法addAll(Object…)属于原始

  • 问题内容: 在XCode 6中创建一个新项目不允许禁用Storyboard。您只能选择Swift或Objective-C,而不能使用Core Data。 我尝试删除情节提要,并从项目中删除主情节提要,然后从didFinishLaunching手动设置窗口 在AppDelegate中,我有以下内容: 但是,XCode给我一个错误: 类“ AppDelegate”没有初始化程序 有人成功吗? 问题答案

  • 本文向大家介绍如何在不使用HTML的情况下创建网站?,包括了如何在不使用HTML的情况下创建网站?的使用技巧和注意事项,需要的朋友参考一下 如果您不了解HTML或CSS,并且想创建一个网站,那么不用担心,您可以轻松创建网站,而无需编写一行HTML代码。 以下是一些无需编写任何HTML或代码行即可构建网站的方法: 网站构造函数 当您购买网站托管计划时,托管公司将为您提供免费的网站构建器选项,以轻松创

  • 我为我的系统创建了一些报告,该报告由许多表组成。为此,我创建了一个带有@Entity注释的域类,并实现了一个JpaRepository存储库,我将本机查询与@query一起使用,如下所示。 我的问题是,对于每个域类,hibernate都在创建一个表,如何停止它? 我的域类: 我的存储库:

  • 我试着去看其他的代码例子,但是它们和我的代码比较相似,但是我的应用程序仍然会因为同样的错误而崩溃。 这是我使用firebase文档的指导方针编写的代码: 上面的代码正在将otp发送到给定的号码,但是它崩溃了,并且cat-log显示了上面提到的错误。