【发布时间】:2016-06-07 09:56:53
【问题描述】:
我目前正在尝试制作这个 Java 动画循环: http://docs.oracle.com/javafx/2/get_started/ColorfulCircles.java.html
总结一下:程序创建圆,这些圆从生成的带有 X 轴和 Y 轴的起点移动到生成的位置,该位置也有 X 和 Y 轴。 现在,在他们完成到达终点的路径后,while 循环中的一个新循环将开始,但这一次圆圈将从他们的最后一个终点(他们的新起点)开始,并且只生成一个新的终点,所以看起来就像他们从过去的目的地徘徊到另一个目的地一样。
我的问题是坐标是正确的,但我的圈子在错误的位置生成。 这是我的程序的一个小输出:
//First loop with only 3 circles as example
0 StartX: 1110.2994232832264 StartY: 196.5353444146038
0 StartX: 1110.2994232832264 StartY: 196.5353444146038 EndeX: 77.09550167412587 EndeY: 781.9152623844685
1 StartX: 1026.967733288605 StartY: 228.60184379870438
1 StartX: 1026.967733288605 StartY: 228.60184379870438 EndeX: 1495.5868225131878 EndeY: 43.10288101605459
2 StartX: 909.8816160887294 StartY: 599.8395576620894
2 StartX: 909.8816160887294 StartY: 599.8395576620894 EndeX: 739.8188739717103 EndeY: 748.576558089626
3 StartX: 546.8538353648784 StartY: 211.33686550731284
3 StartX: 546.8538353648784 StartY: 211.33686550731284 EndeX: 465.06241304615554 EndeY: 676.2487115928532
//Second loop with the same 3 circles as before
0 StartX: 77.09550167412587 StartY: 781.9152623844685
0 StartX: 77.09550167412587 StartY: 781.9152623844685 EndeX: 609.5200149154447 EndeY: 600.3577965697156
1 StartX: 1495.5868225131878 StartY: 43.10288101605459
1 StartX: 1495.5868225131878 StartY: 43.10288101605459 EndeX: 727.4914318763049 EndeY: 609.0004943773514
2 StartX: 739.8188739717103 StartY: 748.576558089626
2 StartX: 739.8188739717103 StartY: 748.576558089626 EndeX: 435.20715512004284 EndeY: 491.23845197656414
3 StartX: 465.06241304615554 StartY: 676.2487115928532
3 StartX: 465.06241304615554 StartY: 676.2487115928532 EndeX: 1241.2695042799824 EndeY: 400.8279035402024
每行开头的数字是圆的标识符,StartX和StartY是这些圆开始的坐标,EndeX和EndeY是这些圆游动到的坐标。
如您所见,圆“0”在坐标EndeX: 77.09550167412587 EndeY: 781.9152623844685 处停止,并在下一个循环中从坐标0 StartX: 77.09550167412587 StartY: 781.9152623844685 开始,所以基本上动画应该完美循环,但事实并非如此,看起来圆仍然在随机位置生成...
这是我的起始课程:
import static java.lang.Math.random;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.effect.BlendMode;
import javafx.scene.effect.BoxBlur;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.StrokeType;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application
{
public static void main(String[] args)
{
launch(args);
}
public static Timeline timeline = new Timeline();
public static Group circles = new Group();
@Override
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root, 1500, 850, Color.BLACK);
primaryStage.setScene(scene);
for (int i = 0; i < 15; i++) {
Circle circle = new Circle(150, Color.web("white", 0.05));
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("white", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
}
Thread t1 = new Thread(new Random());
Rectangle colors = new Rectangle(scene.getWidth(), scene.getHeight(),
new LinearGradient(0f, 1f, 1f, 0f, true, CycleMethod.NO_CYCLE, new Stop[]{
new Stop(0, Color.web("#f8bd55")),
new Stop(0.14, Color.web("#c0fe56")),
new Stop(0.28, Color.web("#5dfbc1")),
new Stop(0.43, Color.web("#64c2f8")),
new Stop(0.57, Color.web("#be4af7")),
new Stop(0.71, Color.web("#ed5fc2")),
new Stop(0.85, Color.web("#ef504c")),
new Stop(1, Color.web("#f2660f")),}));
colors.widthProperty().bind(scene.widthProperty());
colors.heightProperty().bind(scene.heightProperty());
Group blendModeGroup =
new Group(new Group(new Rectangle(scene.getWidth(), scene.getHeight(),
Color.BLACK), circles), colors);
colors.setBlendMode(BlendMode.OVERLAY);
root.getChildren().add(blendModeGroup);
circles.setEffect(new BoxBlur(10, 10, 3));
t1.start();
// play 40s of animation
primaryStage.show();
}
}
和我在其中生成圆圈运动的班级:
import static java.lang.Math.random;
import java.util.ArrayList;
import java.util.List;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.scene.Node;
import javafx.util.Duration;
public class Random implements Runnable
{
public void run()
{
Main main = new Main();
Double[] startingPositionX = new Double[15];
Double[] startingPositionY = new Double[15];
boolean firstRun = true;
while(true)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e1)
{
System.out.println("Exception");
}
int i = 0;
for (Node circle : main.circles.getChildren()) {
Double startingPositionXNumber = 0.00;
Double startingPositionYNumber = 0.00;
if(firstRun)
{
startingPositionXNumber = random() * 1500;
startingPositionYNumber = random() * 850;
}
else
{
startingPositionXNumber = startingPositionX[i];
startingPositionYNumber = startingPositionY[i];
System.out.println(i + " StartX: " + startingPositionXNumber + " StartY: " + startingPositionYNumber);
}
Double endingPositionXNumber = random() * 1500;
Double endingPositionYNumber = random() * 850;
main.timeline.getKeyFrames().addAll(
new KeyFrame(Duration.ZERO, // set start position at 0
new KeyValue(circle.translateXProperty(), startingPositionXNumber),
new KeyValue(circle.translateYProperty(), startingPositionYNumber)),
new KeyFrame(new Duration(10000), // set end position at 10s
new KeyValue(circle.translateXProperty(), endingPositionXNumber),
new KeyValue(circle.translateYProperty(), endingPositionYNumber)));
startingPositionX[i] = endingPositionXNumber;
startingPositionY[i] = endingPositionYNumber;
System.out.println(i + " StartX: " + startingPositionXNumber + " StartY: " + startingPositionYNumber + " EndeX: " + endingPositionXNumber + " EndeY: " + endingPositionYNumber);
i++;
}
System.out.println("For each was completed.");
firstRun = false;
main.timeline.play();
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
【问题讨论】:
-
不要在另一个线程中使用
while循环,只需在时间轴上使用onFinishedhandler 即可在完成后立即重新启动它。