Python中文网

一个关于 编程问题的解答网站.

有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Conway的生命游戏模拟绘图问题

我正在制作康威的生命模拟游戏,我遇到了一个我似乎无法解决的问题。我似乎无法在每次迭代中更新我的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;
    }

}

共 (1) 个答案

  1. # 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应该显示的信息