矩形在移动,尽管不应该

时间:2019-09-15 09:15:21

标签: java javafx graphics 2d path-finding

我有一个基本程序,其中有3个矩形,分别是红色,绿色和黄色。红色将追逐最接近的矩形,该矩形是通过距离公式计算得出的。黄色的将跟随我的鼠标,而绿色的将永远不会移动。但是,由于某种原因,每当黄色矩形位于其右下角时,绿色矩形都会移动,这很奇怪,因为它不应该移动。

有7个课程,但我只会发布3个相关的课程,以免使课程时间太长。

PathfindingTest.java是主要类,处理所有图形。

package pathfindingtest;

import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 *
 * @author Preston Tang
 */
public class PathfindingTest extends Application {

    private final long[] frameTimes = new long[100];
    private int frameTimeIndex = 0;
    private boolean arrayFilled = false;

    private double mouseX, mouseY;

    private static Virus[] viruses;
    private static Cell[] cells;

    int[][] layout
            = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};

    @Override
    public void start(Stage stage) {
        WeightedGrid base = WeightedGrid.getInstance();
        base.setGrid(layout);
        base.setStyle("-fx-background-color: rgb(" + 40 + "," + 40 + ", " + 40 + ");");

        viruses = new Virus[1];
        cells = new Cell[2];

        for (int a = 0; a < viruses.length; a++) {
            viruses[a] = new Virus(100, 100, 20, 1.5, Color.RED);
            base.getChildren().add(viruses[a]);
        }

//        for (int b = 0; b < cells.length; b++) {
//            cells[b] = new Cell(400, new Random().nextInt(50) + 200, 20, 3, Color.GREEN);
//            base.getChildren().add(cells[b]);
//        }
        cells[0] = new Cell(400, new Random().nextInt(50) + 200, 20, 3, Color.YELLOW);
        cells[1] = new Cell(400, 400, 20, 3, Color.GREEN);
        base.getChildren().add(cells[0]);
        base.getChildren().add(cells[1]);

        base.setOnMouseMoved((MouseEvent event) -> {
            mouseX = event.getX();
            mouseY = event.getY();
        });

        Scene scene = new Scene(base, 800, 550);

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                //To get frame data
                long oldFrameTime = frameTimes[frameTimeIndex];
                frameTimes[frameTimeIndex] = now;
                frameTimeIndex = (frameTimeIndex + 1) % frameTimes.length;
                if (frameTimeIndex == 0) {
                    arrayFilled = true;
                }
                if (arrayFilled) {
                    long elapsedNanos = now - oldFrameTime;
                    long elapsedNanosPerFrame = elapsedNanos / frameTimes.length;
                    double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame;
//                    System.out.println(String.format("Current frame rate: %.3f", frameRate));
                }

                if (!(mouseX == 0) && !(mouseY == 0)) {
//                    virus.directPath(MathUtil.getInstance().getAngle(virus.getX() + virus.getWidth() / 2, virus.getY() + virus.getHeight() / 2, mouseX, mouseY), virus.getSpeed());
                    viruses[0].followClosestCell();
                    cells[0].directPath(MathUtil.getInstance().getAngle(cells[0].getX() + cells[0].getWidth() / 2, cells[0].getY() + cells[0].getHeight() / 2, mouseX, mouseY), cells[0].getSpeed());
//                    cells[1].directPath(MathUtil.getInstance().getAngle(cells[1].getX() + cells[1].getWidth() / 2, cells[1].getY() + cells[1].getHeight() / 2, mouseX, mouseY), cells[1].getSpeed());
//                    System.out.println(viruses[0].getSpeed() + " " + cells[0].getSpeed() + " " + cells[1].getSpeed());
                }

            }
        };

        timer.start();

        stage.setTitle("Pathfinding Test Application Started 9/9/2019");
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    public Cell[] getCells() {
        return this.cells;
    }

    public Virus[] getViruses() {
        return this.viruses;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

Entity.java,它扩展了矩形。

package pathfindingtest;

import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;

/**
 *
 * @author Preston Tang
 */
public class Entity extends Rectangle {

    private Rectangle rec;
    private double x, y, size, speed;
    private Color c;

    public Entity(double x, double y, double size, double speed, Color c) {
        rec = new Rectangle();
        this.setX(x);
        this.setY(y);
        this.setWidth(size);
        this.setHeight(size);
        this.speed = speed;

        this.setFill(c);
    }

    public void directPath(double angle, double distance) {
        if (canCross(angle)) {
            this.setX(this.getX() + (distance * Math.cos(angle)));
            this.setY(this.getY() + (distance * Math.sin(angle)));
        } else {
            this.setX(this.getX());
            this.setY(this.getY());
        }
    }

    public boolean canCross(double angle) {
        rec.setX(this.getX() + (speed * Math.cos(angle)));
        rec.setY(this.getY() + (speed * Math.sin(angle)));
        rec.setWidth(this.getWidth());
        rec.setHeight(this.getHeight());

        GridCell[][] cells = WeightedGrid.getInstance().getCells();
        for (int r = 0; r < cells.length; r++) {
            for (int c = 0; c < cells[r].length; c++) {
                GridCell cell = cells[r][c];
                if (!(cells[r][c].isTraversable()) && rec.intersects(cell.getX(), cell.getY(), cell.getWidth(), cell.getHeight())) {
                    return false;
                }
            }
        }

        return true;

    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public double getSize() {
        return size;
    }

    public void setSize(double size) {
        this.size = size;
    }

    public Color getC() {
        return c;
    }

    public void setC(Color c) {
        this.c = c;
    }

}

MathUtil,它是一个单例,包含我所有的数学方法。

package pathfindingtest;

/**
 *
 * @author Preston
 *
 * This class contains all Math methods for this program.
 *
 * Is a Singleton.
 */
public class MathUtil {

    private static MathUtil instance;

    private MathUtil() {
    }

    public static MathUtil getInstance() {
        if (instance == null) {
            instance = new MathUtil();
        }
        return instance;
    }

    public double getDistance(double x1, double y1, double x2, double y2) {
        return Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
    }

    public double getAngle(double x1, double y1, double x2, double y2) {
        return Math.atan2((y2 - y1), (x2 - x1));
    }

}

Virus.java,它是红色矩形,并且扩展了Entity。

package pathfindingtest;

import java.util.ArrayList;
import java.util.Collections;
import javafx.scene.paint.Color;

/**
 *
 * @author Preston Tang
 */
public class Virus extends Entity {

    public Virus(double x, double y, double size, double speed, Color c) {
        super(x, y, size, speed, c);
    }

    public Cell getClosestCell() {
        Cell[] cellsO = new PathfindingTest().getCells();

        Cell[] cells = cellsO;

        ArrayList<Double> distances = new ArrayList<>();

        for (Cell cell : cells) {
            distances.add(MathUtil.getInstance().getDistance(this.getX(), this.getY(), cell.getX(), cell.getY()));
        }

        for (int i = 0; i < distances.size(); i++) {
            for (int j = 0; j < distances.size(); j++) {
                if (distances.get(i) < distances.get(j)) {
                    double temp = distances.get(i);
                    distances.set(i, distances.get(j));
                    distances.set(j, temp);

                    Cell temper = cells[i];
                    cells[i] = cells[j];
                    cells[j] = temper;
                }
            }
        }

        System.out.println(MathUtil.getInstance().getDistance(this.getX(), this.getY(), cellsO[0].getX(), cellsO[0].getY()) + " " + MathUtil.getInstance().getDistance(this.getX(), this.getY(), cellsO[1].getX(), cellsO[1].getY()));
        return cells[0];
    }

    public void followClosestCell() {
        Cell c = getClosestCell();

        directPath(MathUtil.getInstance().getAngle(this.getX(), this.getY(), c.getX(), c.getY()), this.getSpeed());
    }

}

非常感谢您的帮助!谢谢您的宝贵时间。

0 个答案:

没有答案