我正在制作一个带有 GUI 的 A* 寻路应用程序。我有:
- 一个枚举 TileType
START(Color.GREEN),
WALL(Color.BLACK),
BLANK(new Color(240, 240, 240)),
END(Color.RED);
- 一个网格类
public class Grid extends JPanel {
private final Color lineColour = new Color(200, 200, 200);
private Color defaultColour;
private final int pixelsPerTile;
private final int rows;
private final int columns;
private TileType[][] tiles;
public Grid(int rows, int columns, int pixelsPerTile) {
this.pixelsPerTile = pixelsPerTile;
this.rows = rows;
this.columns = columns;
this.tiles = new TileType[rows][columns];
this.setPreferredSize(new Dimension(rows * pixelsPerTile, columns * pixelsPerTile));
setTile(rows / 2 - 5, columns / 2, TileType.START);
setTile(rows / 2 + 5, columns / 2, TileType.END);
}
public void resetBoard() {
for (int i = 0; i < tiles.length; i++) {
for (int j = 0; j < tiles[0].length; j++) {
if (getTile(i, j) != TileType.START && getTile(i, j) != TileType.END) {
tiles[i][j] = null;
}
}
}
}
public void removeTile(int x, int y) {
tiles[x][y] = TileType.BLANK;
}
public TileType getTile(int x, int y) {
return tiles[x][y];
}
public Point getTile(boolean start) {
for (int x = 0; x < tiles.length; x++) {
for (int y = 0; y < tiles[0].length; y++) {
if (tiles[x][y] == (start ? TileType.START : TileType.END)) {
return new Point(x, y);
}
}
}
return null;
}
public void setTile(int x, int y, TileType tile) {
if (getTile(x, y) != TileType.START && getTile(x, y) != TileType.END) {
tiles[x][y] = tile;
}
}
@Override
public void paint(Graphics g1) {
Graphics2D g = (Graphics2D) g1;
for (int x = 0; x < columns; x++) {
for (int y = 0; y < columns; y++) {
if (getTile(x, y) != null) {
g.setColor(getTile(x, y).getColour());
g.fillRect(x * pixelsPerTile, y * pixelsPerTile, pixelsPerTile, pixelsPerTile);
}
}
}
// have the grid appear on top of blank tiles
g.setColor(lineColour);
for (int x = 0; x < columns; x++) {
for (int y = 0; y < rows; y++) {
g.drawLine(x * pixelsPerTile, 0, x * pixelsPerTile, getHeight());
g.drawLine(0, y * pixelsPerTile, getWidth(), y * pixelsPerTile);
}
}
}
public int getPixelsPerTile() {
return pixelsPerTile;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
}
- 框架类
public class Frame extends JFrame {
private Grid grid;
public Frame() {
grid = new Grid(33, 33, 15); // odd so there is a definitive middle point
this.setAutoRequestFocus(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle("A* Path finder");
this.setBounds(new Rectangle((grid.getRows()) * grid.getPixelsPerTile(),
(grid.getColumns() + 2) * grid.getPixelsPerTile()));
this.setResizable(true);
this.add(grid);
this.setVisible(true);
this.getContentPane().addMouseListener(new MouseLsntr()); // fixes alignment problems
ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(5);
se.scheduleAtFixedRate(new RedrawGrid(), 0L, 20L, TimeUnit.MILLISECONDS);
}
private class RedrawGrid implements Runnable {
@Override
public void run() {
grid.repaint();
}
}
private class MouseLsntr implements MouseListener {
@Override
public void mouseClicked(MouseEvent me) {
int x = me.getX() / grid.getPixelsPerTile();
int y = me.getY() / grid.getPixelsPerTile();
switch (me.getButton()) {
case MouseEvent.BUTTON1:
if (grid.getTile(x, y) != TileType.WALL) {
grid.setTile(x, y, TileType.WALL);
System.out.println(String.format("(%d, %d) (%d, %d) wall", x, y, x, y));
} else {
grid.removeTile(x, y);
System.out.println(String.format("(%d, %d) (%d, %d) blank", x, y, x, y));
}
break;
}
}
@Override
public void mousePressed(MouseEvent me) {}
@Override
public void mouseReleased(MouseEvent me) {}
@Override
public void mouseEntered(MouseEvent me) {}
@Override
public void mouseExited(MouseEvent me) {}
}
}
- 显然是一个调用 Frame() 的主类
当用户左键单击网格时,他们会在该位置创建一个墙。如果它已经是一堵墙,它就会变成空白。我希望用户能够通过单击它然后拖动到他们想要停止的位置来移动 START 和 END 磁贴,但我无法做到这一点。任何帮助将不胜感激,因为我已经为此困惑了一段时间。