我写了一个程序,递归地创建一个迷宫,但是在每一步之后都无法弄清楚如何让它画出迷宫。迷宫的任何更改都会在下一次递归调用之前发生。迷宫被预渲染到JPanel
上作为方格网格,我试图让程序渲染每一步,在下一次递归调用之前使用JPanel.repaint
(我在{{1}中有评论我之前尝试重新绘制的方法。无论我尝试什么,迷宫只是简单地在最后一次渲染完成的产品(迷宫中包含所有路径,墙壁等)。附件是我的递归{{ 1}}方法。
generate
使用generate
类中保存的信息,将每个单元格单独渲染到private static boolean generate(int x, int y) {
System.out.println("xcord: " + x + ", ycord: " + y);
//panel.repaint(); when i have repaint here, it renders the entire maze at the end
a[x][y].visited = true;
if (unvisitedCells == 0) { // if you have visited all of the cells, maze is done generating
System.out.println("done");
return true;
}
int movesTried = 0; // keeps track of which directions have been tried
int currentMove = (int) (Math.random() * 4); // try moving a random direction first (0 = north, 1 = east, etc.)
while (movesTried < 4) { // continue as long as all four moves havent been tried
// north move
if (a[x][y].northCell != null && a[x][y].northCell.visited != true && currentMove == 0) {
a[x][y].northCell.visited = true;
a[x][y].northWall = false;
a[x][y].northCell.southWall = false;
unvisitedCells -= 1;
// tried repainting here, but had no effect
if (generate(x, y - 1)) {
return true; // move successful
}
}
// east move
if (a[x][y].eastCell != null && a[x][y].eastCell.visited != true && currentMove == 1) {
a[x][y].eastCell.visited = true;
a[x][y].eastWall = false;
a[x][y].eastCell.westWall = false;
unvisitedCells -= 1;
// tried repainting here, but had no effect
if (generate(x + 1, y)) {
return true; // move successful
}
}
// south move
if (a[x][y].southCell != null && a[x][y].southCell.visited != true && currentMove == 2) {
a[x][y].southCell.visited = true;
a[x][y].southWall = false;
a[x][y].southCell.northWall = false;
unvisitedCells -= 1;
// tried repainting here, but had no effect
if (generate(x, y + 1)) {
return true; // move successful
}
}
// west move
if (a[x][y].westCell != null && a[x][y].westCell.visited != true && currentMove == 3) {
a[x][y].westCell.visited = true;
a[x][y].westWall = false;
a[x][y].westCell.eastWall = false;
unvisitedCells -= 1;
// tried repainting here, but had no effect
if (generate(x - 1, y)) {
return true; // move successful
}
}
movesTried++; // another move has been tried
if (currentMove == 3 && movesTried < 4) {
currentMove = 0; // wraps back to north move if maze started at a move greater than 0, and you
// have more moves to try
} else {
currentMove++;
}
}
// at this point, all 4 moves have been tried, and there are no possible moves
// from the current maze cell
return false;
}
上。
JPanel
在这里,我设置了一个MazeCell
,根据4个方向中是否有一个墙,单独绘制每个单元格。
public class MazeCell {
public boolean northWall = true;
public boolean eastWall = true;
public boolean southWall = true;
public boolean westWall = true;
public MazeCell northCell = null;
public MazeCell eastCell = null;
public MazeCell southCell = null;
public MazeCell westCell = null;
public boolean visited = false;
}
答案 0 :(得分:3)
使用SwingWorker扭曲长进程(generate(int x, int y)
),并让它更新GUI。这是一个例子:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
public class RecursiveGuiUpdate extends JFrame {
private final int SIZE = 4;
JLabel[][] grid = new JLabel[SIZE][SIZE];
RecursiveGuiUpdate() {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
add(getGrid(), BorderLayout.NORTH);
JButton paint = new JButton("Paint");
paint.addActionListener(a -> updateGui());
add(paint, BorderLayout.SOUTH);
pack();
setVisible(true);
}
private void updateGui() {
new Task().execute();
}
private Component getGrid() {
JPanel panel = new JPanel(new GridLayout(SIZE, SIZE));
for(int i=0; i<=(SIZE-1); i++) {
for(int j=0; j<=(SIZE-1); j++) {
JLabel l = new JLabel(i+"-"+j, JLabel.CENTER);
l.setOpaque(true);
panel.add(l);
grid[i][j] = l;
}
}
return panel;
}
class Task extends SwingWorker<Void,Void> {
@Override
public Void doInBackground() {
updateGui(0, 0);
return null;
}
@Override
public void done() { }
//recursively set labels background
void updateGui(int i, int j) {
System.out.println(i+"-"+j);
//set random, background color
grid[i][j].setBackground(new Color((int)(Math.random() * 0x1000000)));
try {
Thread.sleep(500); //simulate long process
} catch (InterruptedException ex) { ex.printStackTrace();}
if((i==(SIZE-1))&&(j==(SIZE-1))) { return; }
if(i<(SIZE-1)) {
updateGui(++i, j);
}else {
i=0;
updateGui(i, ++j);
}
}
}
public static void main(String[] args) {
new RecursiveGuiUpdate();
}
}
如果需要,您可以覆盖process(java.util.List)以获取和处理期中结果 如果您需要有关此类解决方案的帮助,请使用mcve发布另一个问题。