javafx animation looping

后端 未结 3 1870
误落风尘
误落风尘 2020-12-21 22:46

in c++ or c programming language, we know to change the cordinate we use gotoxy(x,y) and we can use looping and sleep to change the cordinate and making animation. like this

相关标签:
3条回答
  • 2020-12-21 23:24

    Have look at using a Timeline Animation. It is a key component of animation in JavaFX and
    is used to establish when, and in what sequence, key parts of an animation occur.

    Here is an example

    0 讨论(0)
  • 2020-12-21 23:30

    There are three different options in JavaFX, depending on your needs.

    The most basic one is AnimationTimer. It's equivalent to Swing's Timer. It simply contains a handle method which is called on every frame, and passed current time as argument. You probably want some internal bookkeeping so that you do not do expensive calculations every time handle is called.

    Transition has an interpolate(frac) method, which gets called with values of frac between 0.0 and 1.0. It's up to you to do all UI changes you want to, based on the frac value. Both Transition and Timeline extend Animation, so you can set stuff like cycle duration, whether the Transition is reversed at end, etc.

    Timeline is the most complex one. You define arbitrary amount of KeyFrames (think of states) that contain wanted properties of different Nodes, and the Timeline will do all the work for you interpolating how to animate the change between the provided values. For example, you can give a keyframe where x property of a Node is 0, and another where it's 100, and Timeline will do the animating for you.

    0 讨论(0)
  • 2020-12-21 23:34

    Use the JavaFX Animation Package.

    There are numerous examples in the JavaFX Animation Tutorial, as Andy pointed out in his comment.

    And there is a cute example of a running horse animation loop.

    The key is that you don't sleep the JavaFX application thread and you have to release control of the JavaFX thread back to the JavaFX system each time you update something and want it rendered. The JavaFX animation classes take care of these things for you so that you don't have to worry about it. If you just loop like you do in the sample code from your question, JavaFX will just render the scene once after your loop has completed and you will never see anything happen.

    Here is a fairly boring example which uses a Timeline to emulate the c++ code in your question to move a dot a pixel every 400 milliseconds.

    import java.util.Date;
    import javafx.animation.*;
    import javafx.application.Application;
    import javafx.event.*;
    import javafx.scene.*;
    import javafx.scene.shape.Circle;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    
    /** Simple JavaFX Animation Sample. */
    public class AnimationSample extends Application {
      private       int         x        = 20;
      private       String      status   = "";
      private final Circle      dot      = new Circle(20, 20, 3);
      private final TimeCounter counter  = new TimeCounter();
    
      public static void main(String[] args) throws Exception { launch(args); }
      @Override public void start(final Stage stage) throws Exception {
        final Timeline timeline = new Timeline(
          new KeyFrame(Duration.ZERO, new EventHandler() {
            @Override public void handle(Event event) {
              refreshScene();
            }
          }),  
          new KeyFrame(Duration.millis(400))
        );
        timeline.setCycleCount(Timeline.INDEFINITE);
    
        stage.setScene(new Scene(new Group(dot), 50, 50));
        stage.show();
    
        counter.reset();
        timeline.play();
      }
    
      private void refreshScene() {
        gotoxy(x, 20);
    
        status = "*****".equals(status) ? "*" : status + "*";
        System.out.println(String.format("%7d", counter.elapsed()) + " ms " + x + " " + status);
    
        if (x == 24) {
          x = 20;
        } else {
          x++;
        }
      }      
    
      private void gotoxy(int x, int y) {
        dot.setCenterX(x); 
        dot.setCenterY(y);
      }
    
      class TimeCounter {
        private long start = new Date().getTime();
        void reset()   { start = new Date().getTime(); }
        long elapsed() { return new Date().getTime() - start; }
      }
    }
    
    0 讨论(0)
提交回复
热议问题