康威的生命游戏模拟 - 绘图问题

时间:2015-04-28 04:00:13

标签: java swing user-interface paint

我正在创建一个康威的生命游戏模拟,我遇到了一个我似乎无法弄清楚的问题。我似乎无法让我的JPanel更新每次迭代。我有一种感觉,这是一种简单的东西,我忽略了,但任何帮助将不胜感激。基本上第一帧被渲染但在此之后,面板不会重新绘制。

这是我的代码:

GameOfLife.java

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);
        }

    }   
}

Board.java

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;
    }

}

1 个答案:

答案 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要显示的信息。