我要创建的动画很简单:我只希望我的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做同样的事情。问题是动画不是那么平滑,所以我尝试了另一种方法,但是我实际上不知道这是否是最好的方法。