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