圆动画-JavaFX

时间:2018-12-02 18:45:50

标签: java animation javafx fxml

我要创建的动画很简单:我只希望我的Circle扩展到一定半径,然后按照S型函数增长速度即可。

我的问题是有时圈子会停止增长,而其他时候我收到“线程'JavaFX Application Thread'java.lang.NullPointerException中的异常”。这是一些代码,有人可以帮助我吗? 下面的类是我用来处理动画的类:

package application;

import javafx.scene.control.Label;
import javafx.scene.shape.*;

public class GameAnimation{

    public void beatCircleAnimation(Circle beatCircle, int bestKick) {
        Cronometro crono = new Cronometro();

        new Thread() {
            public void run() {

                setPriority(Thread.MAX_PRIORITY);

                double i = 1;
                int ratio = 30000;
                crono.start();

                beatCircle.setRadius(1);

                while(crono.current(false) < 2000) {
                    beatCircle.setRadius(beatCircle.getRadius() + sig(crono.current(false) - bestKick));
                    try {
                        sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(crono.current(false) > 1499) {
                        beatCircle.setOpacity(1 - ((double)crono.current(false) - 1499)/499);
                        System.out.println(beatCircle.getOpacity());
                    }
                    if(crono.current(false) >= 2000) {
                        crono.interrupt();
                        interrupt();
                    }
                }
            }
        }.start();
    }

    private double sig(double x) {
        return 1/(1 + (Math.pow(Math.E, -x)));
    }
}

这是我的控制器:

package application;

import java.util.concurrent.TimeUnit;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.fxml.FXML;
import javafx.scene.Group;
import javafx.scene.control.Label;
import javafx.scene.effect.BlendMode;
import javafx.scene.layout.Background;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.stage.StageStyle;
import javafx.util.Duration;

public class SampleController {

    @FXML
    StackPane rootPane;

    GameAnimation anim = new GameAnimation();

    Circle circle = new Circle(100);
    Label label = new Label("Start");

    public void initialize() {
        rootPane.setBackground(Background.EMPTY);
        label.setFont(Font.font("AvidOmnes Light", 30));

        rootPane.setOnMouseClicked((e) ->{
            Circle beatCircle = new Circle(0);
            rootPane.getChildren().add(beatCircle);
            anim.beatCircleAnimation(beatCircle, 800);
        });
    }
}

主要内容:

package application;

import javafx.application.Application;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            StackPane root = (StackPane)FXMLLoader.load(getClass().getResource("Sample.fxml"));
            Scene scene = new Scene(root, Screen.getPrimary().getBounds().getMaxX(), Screen.getPrimary().getBounds().getMaxY());
            scene.setFill(Color.TRANSPARENT);
            primaryStage.initStyle(StageStyle.TRANSPARENT);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这是我的班级Cronometro:

package application;

public class Cronometro extends Thread{

    public long lastCheck = 0;

    public void start() {
        lastCheck = System.currentTimeMillis();
    }

    public long current(boolean resetFlag) {
        long temp = System.currentTimeMillis() - lastCheck;

        if(resetFlag) {
            lastCheck = System.currentTimeMillis();
        }

        return temp;
    }

    public void reset() {
        lastCheck = 0;
    }
}

我的Sample.fxml文件仅包含一个StackPane。

我试图用AnimationTimer做同样的事情。问题是动画不是那么平滑,所以我尝试了另一种方法,但是我实际上不知道这是否是最好的方法。

0 个答案:

没有答案