使用更新的Path()在Scene上绘制新行

时间:2016-12-30 04:52:33

标签: java javafx

我是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(),并且应定期更新nodehere。那么每次迭代都不应该显示蚂蚁的最新路径段吗?

有人可以解释一下这个问题吗?是否无法利用Path()PathTransition()来显示这些细分受众群并避免使用Line()

1 个答案:

答案 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);

        }

    }

}

希望它有所帮助。