Круговая анимация - JavaFX - PullRequest
0 голосов
/ 02 декабря 2018

анимация, которую я пытаюсь создать, проста: я просто хочу, чтобы мой Круг расширялся, пока не достигнет определенного радиуса, со скоростью роста, которая следует сигмоидальной функции.

Моя проблема в том, что иногда круги перестают расти, в то время как в других случаях я получаю «Исключение в потоке« Поток приложения JavaFX »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, чтобы сделать то же самое.Проблема в том, что анимация не была настолько плавной, поэтому я попробовал это по-другому, но на самом деле я не знаю, является ли это лучшим способом.

...