我是javafx的新手,并且正在使用它来执行Ant Colony Optimization算法的版本。我写了一些代码,它应该显示一个小圆圈作为在平面中随机移动的蚂蚁。这很好。但是我无法修改代码以在场景中显示蚂蚁的路径。基本上我希望蚂蚁的路径在蚂蚁在2D平面上移动时用线突出显示。
以下是代码:
import java.util.ArrayList;
import java.util.Random;
//Line can either be a sound or a shape
import javafx.animation.Animation.Status;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.lang.Object;
import javafx.scene.Node;
import javafx.scene.shape.Shape;
import javafx.scene.shape.Line;
public class TestMotion extends Application {
int N = 10;
static ArrayList<Integer> move = new ArrayList<Integer>();
private double sceneWidth = 512;
private double sceneHeight = 512;
MyNode node = new MyNode(0,0,5);
Path pathA = new Path();
int n = 10;
@Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
root.getChildren().addAll(node, pathA);
Scene scene = new Scene( root, sceneWidth, sceneHeight);
primaryStage.setScene( scene);
primaryStage.show();
animate();
}
//convention conversion (i,j) to node number x
public static int convert(int i, int j, int N)
{
return (j*N +i+1);
}
//convention conversion node number x to (i,j)
//implement in order of definition
public static int reconvertY(int x, int N)
{
return (int) java.lang.Math.floor((x-1)/N);
}
public static int reconvertX(int x, int N, int j)
{
return (x-j*N-1);
}
private void animate() {
nextPos(move, N);
int y1 = reconvertY(move.get(move.size()-1), N);
int x1 = reconvertX(move.get(move.size()-1), N, y1);
MyNode here = new MyNode(10*x1, 10*y1, 1);
System.out.println(move.get(move.size()-1));
pathA.getElements().add (new MoveTo ( node.getTranslateX() + node.getBoundsInParent().getWidth() / 2.0, node.getTranslateY() + node.getBoundsInParent().getHeight() / 2.0));
pathA.getElements().add (new LineTo( here.getTranslateX() + here.getBoundsInParent().getWidth() / 2.0, here.getTranslateY() + here.getBoundsInParent().getHeight() / 2.0));
pathA.setStroke(Color.RED);
pathA.setStrokeWidth(1.0);
PathTransition pathTransitionA = new PathTransition();
pathTransitionA.setDuration(Duration.millis(1000));
pathTransitionA.setNode(node);
pathTransitionA.setPath(pathA);
pathTransitionA.play();
pathA = new Path();
pathTransitionA.setOnFinished( new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if( pathTransitionA.getStatus() == Status.RUNNING)
{return;}
animate();
}
});
}
//allot new node to the arraylist such that it is adjacent to the previously assigned node
private void nextPos(ArrayList<Integer> array, int N)
{
//I removed this part to save space because it is probably irrelevant the the problem at hand
}
public static void main(String[] args) {
move.add(1);
launch(args);
}
public static class MyNode extends StackPane {
public MyNode(double x, double y, double r) {
// create circle
Circle circle = new Circle();
circle.setRadius(r);
circle.setFill(Color.BLUE);
// set position
setTranslateX( x);
setTranslateY( y);
getChildren().add(circle);
}
}
}
执行时,场景仅显示第一步的路径,然后完全停止显示路径。我无法弄清楚为什么。每次path
函数运行时都会更新animate()
,并且应定期更新node
和here
。那么每次迭代都不应该显示蚂蚁的最新路径段吗?
有人可以解释一下这个问题吗?是否无法利用Path()
和PathTransition()
来显示这些细分受众群并避免使用Line()
?
答案 0 :(得分:0)
你的做法没有错。只有问题在于,无论何时调用animate()
,所形成的路径都具有以前的坐标。路径坐标始终返回以下
1.0, 1.0 for moveTo and 5.0,5.0 for LineTo
每次path
成为新坐标时,您需要传递新的坐标。另外,为了继续显示旧路径以及新路径,您需要继续将新创建的path
添加到Group
。
以下是我在代码中更改的内容。看看。
import java.util.ArrayList;
import javafx.animation.Animation.Status;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TestMotion extends Application {
int N = 10;
static ArrayList<Integer> move = new ArrayList<Integer>();
private double sceneWidth = 512;
private double sceneHeight = 512;
MyNode node = new MyNode(0, 0, 5);
Group root; //Made root as global variable
int n = 10;
@Override
public void start(Stage primaryStage) throws Exception {
root = new Group();
root.getChildren().addAll(node);
Scene scene = new Scene(root, sceneWidth, sceneHeight);
primaryStage.setScene(scene);
primaryStage.show();
animate(0.0f, 0.0f, 5.0f, 5.0f); //Passing initial coordinates to the method
}
//convention conversion (i,j) to node number x
public static int convert(int i, int j, int N) {
return (j * N + i + 1);
}
//convention conversion node number x to (i,j)
//implement in order of definition
public static int reconvertY(int x, int N) {
return (int) java.lang.Math.floor((x - 1) / N);
}
public static int reconvertX(int x, int N, int j) {
return (x - j * N - 1);
}
private void animate(float moveX, float moveY, float lineX, float lineY) {
Path pathA = new Path();
root.getChildren().add(pathA);
nextPos(move, N);
int y1 = reconvertY(move.get(move.size() - 1), N);
int x1 = reconvertX(move.get(move.size() - 1), N, y1);
//Applying coordinates as obtained
pathA.getElements().add(new MoveTo(moveX, moveY));
pathA.getElements().add(new LineTo(lineX, lineY));
pathA.setStroke(Color.RED);
pathA.setStrokeWidth(1.0);
PathTransition pathTransitionA = new PathTransition();
pathTransitionA.setDuration(Duration.millis(100));
pathTransitionA.setNode(node);
pathTransitionA.setPath(pathA);
pathTransitionA.play();
pathTransitionA.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (pathTransitionA.getStatus() == Status.RUNNING) {
return;
}
animate(lineX, lineY, lineX + 2, lineY + 2); //previous path's endpoint makes the start point of the new Path
}
});
}
//allot new node to the arraylist such that it is adjacent to the previously assigned node
private void nextPos(ArrayList<Integer> array, int N) {
//I removed this part to save space because it is probably irrelevant the the problem at hand
}
public static void main(String[] args) {
move.add(1);
launch(args);
}
public static class MyNode extends StackPane {
public MyNode(double x, double y, double r) {
// create circle
Circle circle = new Circle();
circle.setRadius(r);
circle.setFill(Color.BLUE);
// set position
setTranslateX(x);
setTranslateY(y);
getChildren().add(circle);
}
}
}
希望它有所帮助。