我有一个基本程序,其中有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());
}
}
非常感谢您的帮助!谢谢您的宝贵时间。