繁体   English   中英

为什么我的Java游戏人生计划无法正常工作?

[英]Why isn't my Java Game of Life program working?

我正在开发一个程序,该程序可以创建Conway的《人生游戏》的图形模型,但是一旦发布,它并不能让我做任何事。 按钮不起作用,网格也没有变化。 我究竟做错了什么?

import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;


public class gameOfLife extends JApplet{
    private static final long serialVersionUID = 1L;

cellClass cell;

public void init() {
    Container contentWindow = getContentPane();
    cell = new cellClass();{{
    setLayout(new FlowLayout()) }};
    contentWindow.add(cell);    
    }
} 

class grid extends JComponent{ 
    private static final long serialVersionUID = 2L;

    int XSIZE = 500;
    int YSIZE = 500;
    private int row;
    private int col;
    private int size = 5;
    private cellClass c;
    private Dimension preferredSize = new Dimension(XSIZE, YSIZE);

    public void paint(Graphics a) {
    int x, y;
        for(x=0; x<row; x++){
        for(y=0; y<col; y++){
            if(c.grid[x][y] != 0){
                a.drawRect(x * size, y * size, 5, 5);
            }
        }
    }
    a.drawRect(0, 0, XSIZE, YSIZE);

}

public grid(cellClass newGrid, int newRow, int newCol, int newSize) {
    setMinimumSize(preferredSize);
    setMaximumSize(preferredSize);
    setPreferredSize(preferredSize);
    this.row = newRow;
    this.col = newCol;
    this.size = newSize;
    this.c = newGrid;

}
}

class cellClass extends JPanel implements ActionListener{
private static final long serialVersionUID = 3L;

static final int ROW = 100;
static final int COL = 100;
static final int SIZE = 5;
static final int min = 2;
static final int max = 3;
static final int birth = 3;
public int genCount = 0;

public int[][] grid;
private int[][] nextGrid;

private GridBagLayout gridBag = new GridBagLayout();
private GridBagConstraints c = new GridBagConstraints();

JLabel title;
JLabel genCounter;
JButton oneGen;
JButton contPlay;
JButton stop;
public grid board;
public boolean paused = true;
public boolean canChange = true;

cellClass() {
    grid = new int [ROW][COL];
    nextGrid = new int[ROW][COL];

    makeGrid(grid);

    setLayout(gridBag);

    title = new JLabel("Game of Life Applet");
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 2;
    c.insets = new Insets(2,0,0,0);
    c.anchor = GridBagConstraints.WEST;
    add(title);

    board = new grid(this,ROW,COL,SIZE);
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 1;
    gridBag.setConstraints(board, c);
    add(board);

    oneGen = new JButton("Move one Generation");
    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 1;
    gridBag.setConstraints(oneGen, c);
    add(oneGen);

    contPlay = new JButton("Play");
    c.gridx = 1;
    c.gridy = 3;
    c.gridwidth = 1;
            contPlay.setVisible(true);
    gridBag.setConstraints(contPlay, c);
    add(contPlay);

    stop = new JButton("Stop");
    c.gridx = 2;
    c.gridy = 3;
    c.gridwidth = 1;
            stop.setVisible(false);
    gridBag.setConstraints(stop, c);
    add(stop);

    genCounter = new JLabel("Generation: 0");
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 1;
    gridBag.setConstraints(genCounter, c);
    add(genCounter);
}

class ButtonListener {
    public void addActionListener(ActionEvent e) throws InterruptedException {
        JButton source = (JButton)e.getSource();

        if(source == oneGen){
            nextGen();
        }
        if(source == contPlay){
            paused = false;
            canChange = false;
                            contPlay.setVisible(false);
                            stop.setVisible(true);
            while (paused = false) {
                nextGen();
                Thread.sleep(1000);
            }
        }
        if(source == stop) {
            paused = true;
            canChange = false;
                            stop.setVisible(false);
                            contPlay.setVisible(true);
        }
    }
}

public void mouseClicked(MouseEvent e){
    int xco = e.getX() - board.getX();
    int yco = e.getY() - board.getY();
    if((e.getComponent() == board) && (paused == true)){
        if(grid[xco/5][yco/5] == 1){
            grid[xco/5][yco/5] = 0;
            board.repaint();
        }else if(grid[xco/5][yco/5] == 0){
            grid[xco/5][yco/5] = 1;
            board.repaint();
        }
    }
}

public void makeGrid(int[][] emptyGrid) {
    int x, y;
    for(x = 0; x < ROW; x++){
        for(y = 0; y < COL; y++){
            emptyGrid[x][y] = 0;
        }
    }
}

public void nextGen() {
    getNextGen();
    board.repaint();
    genCount++;
    genCounter.setText("Generation: " + Integer.toString(genCount));        
}

public void getNextGen() {
    int x, y, neighbor;
    makeGrid(nextGrid);
    for(x = 0; x < ROW; x++){
        for(y=0; y<COL; y++){
            neighbor = calculate(x,y);

            if(grid[x][y] != 0){
                if((neighbor >= min) && (neighbor <= max)) {
                    nextGrid[x][y] = neighbor;
                }
            }else {
                if(neighbor == birth){
                    nextGrid[x][y] = birth;
                }
            }
        }
    }
    makeGrid(grid);
    copyGrid(nextGrid,grid);
}

public void copyGrid(int[][] source, int[][] newGrid) {
    int x, y;
    for(x=0; x<ROW; x++){
        for(y=0; y<COL; y++){
            newGrid[x][y] = source[x][y];
        }
    }
}

private int calculate(int x, int y){
    int a, b, total;

    total = (grid[x][y]);
    for (a = -1; a<= 1; a++) {
        for (b = -1; b <= 1; b++){
            if(grid[(ROW + (x + a)) % ROW][(COL + (y + b)) % COL] != 0) {
                total++;
            }
        }
    }
    return total;
}

@Override
public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub

    }
}       

如果有人能告诉我这是怎么回事,那太好了。

您的主要问题之一是您试图在Swing事件线程(也称为事件调度线程或EDT)上运行一个较长的过程,这实际上将冻结您的程序。 我看到这里发生了这个问题:

class ButtonListener {
  public void addActionListener(ActionEvent e) throws InterruptedException {
     JButton source = (JButton) e.getSource();

     // ...

        while (paused = false) { // *******
           nextGen();
           Thread.sleep(1000);  // ******
        }
     }

     // ...

}

您有一个while(true)循环和一个Thread.sleep(...)两者都不应该在事件线程上调用。

相反,您应该使用Swing Timer

有关Swing事件线程的更多信息,请阅读Swing中的并发

另外(1),您在哪里允许将单元格初始化为活动状态? 没有世代相传的活细胞,只会显示一个空的网格吗? 您是否需要将MouseListener添加到一个或多个组件中? 我认为这将是一个好主意。

同样(2),当您向其添加ActionListener时,按钮通常会更好地工作,如Swing按钮教程中所述 您是否已完成Swing教程? 如果没有,请检查一下(在此处查找),因为它们对您有很大帮助。

同样(3),您一次尝试解决太多问题的能力可能会比想得到的要好得多。 当我创建与此类似的GUI时,我希望独立地处理程序的每个部分,并先使其工作,然后再将其组合成一个大程序。 因此,例如,首先在非GUI模型上工作,并通过调用该模型方法的测试代码运行它来使世代工作。 接下来,一次处理GUI的每个部分,包括JButton,MouseListener,生活游戏的显示,然后实现各代。

调试较小的测试程序要容易得多,然后尝试调试整个shebang,请相信我。

您的程序为我启动,但是还有其他问题。 这将帮助您开始解决问题:

更改:

cell = new cellClass();

至:

cell = new cellClass(){{
  setLayout(new FlowLayout());
}}; 

也许在init()中尝试super.init()?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM