【发布时间】:2017-11-26 00:53:29
【问题描述】:
我完成了一个递归创建迷宫的程序,但无法弄清楚如何让它在每一步之后绘制迷宫。对迷宫的任何更改都发生在下一次递归调用之前。迷宫被预渲染到JPanel 作为正方形网格,我试图让程序在下一次递归调用之前使用JPanel.repaint 渲染每个步骤(我的generate 方法中有cmets,我有之前尝试重新绘制。无论我尝试什么,迷宫只是简单地在最后一次渲染完成的产品(包含所有路径、墙壁等的迷宫)。附件是我的递归 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;
}
每个单元格都使用MazeCell 类中保存的信息单独呈现到JPanel。
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;
}
在这里我设置了一个JPanel,它根据4个方向的每一个方向是否有墙来单独绘制每个单元格。
panel = new JPanel() {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
super.paintComponent(g);
a[0][0].northWall = false;
a[mazeSize - 1][mazeSize - 1].southWall = false;
for (int y = 0; y < mazeSize; y++) {
for (int x = 0; x < mazeSize; x++) {
if (a[x][y].northWall) {
g.drawLine(100 + (x * 25), 100 + (y * 25), 100 + (x * 25) + 25, 100 + (y * 25));
}
if (a[x][y].eastWall) {
g.drawLine(100 + (x * 25) + 25, 100 + (y * 25), 100 + (x * 25) + 25, 100 + (y * 25) + 25);
}
if (a[x][y].southWall) {
g.drawLine(100 + (x * 25), 100 + (y * 25) + 25, 100 + (x * 25) + 25, 100 + (y * 25) + 25);
}
if (a[x][y].westWall) {
g.drawLine(100 + (x * 25), 100 + (y * 25), 100 + (x * 25), 100 + (y * 25) + 25);
}
}
}
}
};
【问题讨论】:
-
“我无法重绘迷宫”——这是什么意思?请访问help center 并阅读How to Ask 以了解如何使用此步骤。
-
谢谢,我已经编辑了我的帖子以消除模糊性
-
对不起,“我无法让迷宫在每一步出现时渲染它们” 仍然没有任何意义。尝试呈现步骤的代码在哪里? “渲染一步”是什么意思?当您尝试渲染一个步骤时会发生什么?你有例外吗?没发生什么事?电脑像 1980 年代那些俗气的电影一样发出一阵火花?
-
我怀疑您想使用 Swing
Timer在每个步骤的生成之间产生一个小的停顿。这将改变您的代码的工作方式,因为它不会像您现在拥有的那样“递归”,而是您需要将状态作为实例字段进行管理,这些字段为需要创建的下一步提供种子
标签: java swing recursion paintcomponent