我正在创建一个康威的生命游戏模拟,我遇到了一个我似乎无法弄清楚的问题。我似乎无法让我的JPanel
更新每次迭代。我有一种感觉,这是一种简单的东西,我忽略了,但任何帮助将不胜感激。基本上第一帧被渲染但在此之后,面板不会重新绘制。
这是我的代码:
import javax.swing.JFrame;
public class GameOfLife {
private Board currentBoard;
private Board nextBoard;
private int generation = 0;
private JFrame currentFrame;
public GameOfLife() {
currentBoard = new Board(200, 100);
nextBoard = new Board(currentBoard.getXSize(), currentBoard.getYSize());
currentBoard.populate();
}
public void step() {
generation++;
System.out.println(generation);
nextBoard.clear();
for (int i = 0; i < currentBoard.getXSize(); i++) {
for (int j = 0; j < currentBoard.getYSize(); j++) {
if(currentBoard.getAt(i, j) == true && (currentBoard.numNeighbors(i, j) == 2 || currentBoard.numNeighbors(i, j) == 3)) {
nextBoard.setAlive(i, j);
}
else if (currentBoard.getAt(i, j) == false && currentBoard.numNeighbors(i, j) == 3){
nextBoard.setAlive(i, j);
}
}
}
//System.out.println(nextBoard.toString());
//System.out.println(currentBoard.toString());
currentBoard = nextBoard.copy();
currentBoard.repaint();
}
public Board getBoard() {
return currentBoard;
}
public void setFrame(Board panel) {
currentFrame.setContentPane(panel);
}
public static void main(String[] args) throws InterruptedException {
GameOfLife game = new GameOfLife();
JFrame frame = new JFrame();
game.currentFrame = frame;
frame.setContentPane(game.getBoard());
frame.setSize(game.getBoard().getWidth(), game.getBoard().getHeight());
frame.setVisible(true);
for(int i = 0; i < 10; i++) {
game.step();
Thread.sleep(5);
}
}
}
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Random;
/*
* Board for Game of Life
*/
@SuppressWarnings("serial")
public class Board extends JPanel{
private boolean[][] board;
private int xSize;
private int ySize;
private final int CELL_SIZE = 5;
private ArrayList<String> alive;
private Random rand = new Random();
private final double SPAWN_CHANCE = .4;
public Board(int xSize, int ySize) {
this.xSize = xSize;
this.ySize = ySize;
board = new boolean[xSize][ySize];
alive = new ArrayList<String>();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
if(board[i][j]) {
g2d.fillRect(CELL_SIZE*i, CELL_SIZE*j, CELL_SIZE, CELL_SIZE);
}
else {
g2d.drawRect(CELL_SIZE*i, CELL_SIZE*j, CELL_SIZE, CELL_SIZE);
}
}
}
}
public void clear() {
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
board[i][j] = false;
}
}
}
public void populate() {
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
if(rand.nextDouble() < SPAWN_CHANCE) {
board[i][j] = true;
alive.add(i+","+j);
}
}
}
}
public void setAlive(int x, int y) {
board[x][y] = true;
alive.add(x+","+y);
}
public int numNeighbors(int row, int col) {
int neighbors = 0;
for (int x = Math.max(0,row-1); x < Math.min(row+2,xSize); x++) {
for (int y = Math.max(0,col-1); y < Math.min(col+2,ySize); y++) {
if (board[x][y]) {
neighbors ++;
}
}
}
//System.out.println("Num Neighbors for " + row + "," + col + ": " + neighbors);
return neighbors;
}
public Board copy() {
Board newBoard = new Board(xSize, ySize);
for(int i = 0; i < board.length; i++)
for(int j = 0; j < board[0].length; j++) {
if(this.getAt(i, j)) {
newBoard.setAlive(i, j);
}
}
return newBoard;
}
public int getWidth() {
return xSize*CELL_SIZE;
}
public int getHeight() {
return ySize*CELL_SIZE;
}
public int getXSize() {
return xSize;
}
public int getYSize() {
return ySize;
}
public boolean getAt(int x, int y) {
return board[x][y];
}
public String toString() {
String toReturn = "";
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
if(board[i][j]) {
toReturn += "X";
}
else {
toReturn += "O";
}
}
toReturn += "\n";
}
return toReturn;
}
}
答案 0 :(得分:1)
如果我们查看Board#copy
,我们可以看到您正在创建Board
的全新副本/实例...
public Board copy() {
Board newBoard = new Board(xSize, ySize);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (this.getAt(i, j)) {
newBoard.setAlive(i, j);
}
}
}
return newBoard;
}
但是这从未添加到屏幕上,因此永远无法显示。
不要创建电路板的“副本”,而是更新Board
要显示的信息。