生命游戏 - Java,不起作用(不显示单元格)

时间:2016-10-18 20:50:39

标签: java swing

目前,我正致力于创建“生命游戏”版本。但是我的细胞不会出现。

这是我的Cell Class:

class Cell{
boolean alive; //true if cell is alive, false if cell is dead
int numNeighbors; //number of alive neightboring cells 

//change alive/dead state of the cell
void setAlive(boolean state){
    alive = state;
}

//return alive/dead state of the cell
boolean isAlive(){
    return alive;
}

//set numNeightbors of the cell to n
void setNumNeighbors(int n){
    numNeighbors = n;
}

//take the cell to the next generation
void update(){
    if(numNeighbors <2 || numNeighbors >3){
        alive = false;
    } else if((numNeighbors == 2 || numNeighbors == 3) && alive == true){
        alive = true;
    } else if(numNeighbors == 3 && alive == false){
        alive = true;
    }
}
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor( Color.blue );
    g.setOpaque(true);
    for(int i = 0; i < row; i++){
        for(int j = 0; j < col; j++){
            if(grid[i][j].isAlive()){
                g.setColor( Color.BLACK);
            } else {
                g.setColor ( Color.WHITE);
                g.fillRect(50, 50, 50*i, 50*j);
            }
        }
    }
} 

这是我的GameOfLife Class

<pre>import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import java.io.*;


public class GameOfLife implements MouseListener{
Cell[][] grid; //contain grid of cells
String birthFilename = "birth.txt"; //text file where initial generation is stored
int row; //number of rows
int col; //number of columns


ActionListener actionListener = new ActionListener(){
    javax.swing.Timer timer = new javax.swing.Timer(500, this); //new timer 

    @Override
    public void actionPerformed(ActionEvent event){
    }
};

public void buildIt() {
    int width = 600;
    int height = 600;
    JFrame frame = new JFrame("Game of Life");
    readInitial();

    //adds button interface
    JPanel buttonbar = new JPanel();
    frame.add(buttonbar, BorderLayout.SOUTH);
    JButton start = new JButton("Start");
    JButton stop = new JButton("Stop");
    JButton nextg = new JButton("Next Generation");
    buttonbar.add(nextg);
    buttonbar.add(start);
    buttonbar.add(stop);

    JPanel panel = new JPanel();
    frame.add(panel);
    panel.setPreferredSize(new Dimension(width, height));
    panel.setLayout(new GridLayout(row, col, 4, 4));
    frame.pack();
    frame.setBackground(Color.WHITE);
    frame.setVisible(true);


}

public void mousePressed( MouseEvent e) {
//add code to update x and y
} 
public void mouseReleased( MouseEvent e) { }
public void mouseClicked( MouseEvent e) { } 
public void mouseEntered( MouseEvent e) { }
public void mouseExited( MouseEvent e) { }


//calculate number of living neightbors of each cell and sets numNeighbors
//Does not update dead/live state of cells
void calculateNumNeighbors(){
    int numNeighbors = 0;
    for(int i = 1; i < row + 1; i++){
        for(int j = 1; j < col + 1; j++){
            for(int k = -1; k < 2; k++){
                for(int m = -1; m < 2; m++){
                    if(grid[i+k][j+m].isAlive() && !(k == 0 && m == 0)){
                        numNeighbors++;
                    }
                }
            }
            grid[i][j].setNumNeighbors(numNeighbors);
        }
    }
}

//create grid and read initial generation from file
void readInitial(){
    try{
        grid = new Cell[row + 2][col + 2]; //empty neighbors at corners, so + 2 
        File file = new File(birthFilename);
        Scanner scanner = new Scanner( file ); 
        row = scanner.nextInt();
        col = scanner.nextInt();

        for(int i = 0; i < row + 2; i++){
            for (int j = 0; j < col + 2; j++){
                grid[i][j] = new Cell(); 
            }
        }

        for(int i = 1; i < row + 1; i++){
            for (int j = 1; j < col + 1; j++){
                if(scanner.next().equals(".")){
                    grid[i][j].setAlive(false);
                } else if(scanner.next().equals("*")){
                    grid[i][j].setAlive(true);
                }
            }
        }

        for(int i = 0; i < row + 2; i++){
            grid[0][i].setAlive(false);
            grid[row+2][i].setAlive(false);
        }
        for(int j = 0; j < col + 2; j++){
            grid[j][0].setAlive(false);
            grid[j][col+2].setAlive(false);
        }

    } catch(FileNotFoundException e) {
        grid = new Cell[12][12]; 
        row = 10;
        col = 10;
        for(int i = 0; i < 12; i++){
            for (int j = 0; j < 12; j++){
                grid[i][j] = new Cell();
                grid[i][j].setAlive(false);
            }
        }
    }
}



//update grid to the next generation, using the values of numNeightbors in the cells
void nextGeneration(){
    for(int i = 1; i < row + 1; i++){
        for (int j = 1; j < col + 1; j++){
            grid[i][j].update();
        }
    }
}


public static void main(String[] arg) {
    (new GameOfLife()).buildIt();    
}

我希望任何人都可以帮助我使这个计划有效。

1 个答案:

答案 0 :(得分:5)

我不明白为什么要画画。你有一个具有paintComponent方法的Cell类,但是这个方法没有意义,因为它不是Swing组件的一部分。您的JPanel,您应该在哪里绘图 - 什么都不做。你还有Cell类的其他问题,因为它似乎试图绘制整个网格,而不仅仅是一个单元格。

  • 摆脱Cell的paintComponent方法
  • 而是给它一个允许它绘制自己的public void draw(Graphics g)方法。
  • 创建一个包含单元格网格的JPanel
  • 让这个JPanel在其paintComponent覆盖中执行绘图。它将调用它在for循环中保存的所有Cell的draw(g)方法。
  • 始终在任何重写方法上方放置@Override注释。如果你已经完成了这个,在paintComponent之上,编译器会警告你出错了。

例如:这是一个没有做生命游戏的小程序,但是显示了一个JPanel保持并显示非组件单元网格的示例。通过“非组件”,SimpleCell类不会从Swing组件扩展,没有任何Swing方法,但如上所述,确实有draw(...)方法,并且可以使用它来绘制自己。它还有一个public boolean contains(Point p)方法,主程序可以在其MouseListener中使用它来决定它是否被点击:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class SimpleCellGrid extends JPanel {
    private static final int ROWS = 40;
    private static final int COLS = 40;
    private static final int CELL_WIDTH = 10;
    private static final int PREF_W = CELL_WIDTH * COLS;
    private static final int PREF_H = CELL_WIDTH * ROWS;
    private SimpleCell[][] cellGrid = new SimpleCell[ROWS][COLS];

    public SimpleCellGrid() {
        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        for (int row = 0; row < cellGrid.length; row++) {
            for (int col = 0; col < cellGrid[row].length; col++) {
                int x = col * CELL_WIDTH;
                int y = row * CELL_WIDTH;
                cellGrid[row][col] = new SimpleCell(x, y, CELL_WIDTH);
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        for (SimpleCell[] cellRow : cellGrid) {
            for (SimpleCell simpleCell : cellRow) {
                simpleCell.draw(g2);
            }
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private class MyMouse extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            for (SimpleCell[] cellRow : cellGrid) {
                for (SimpleCell simpleCell : cellRow) {
                    if (simpleCell.contains(e.getPoint())) {
                        simpleCell.setAlive(!simpleCell.isAlive());
                    }
                }
            }
            repaint();
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("SimpleCellGrid");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new SimpleCellGrid());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;

public class SimpleCell {
    private static final Color CELL_COLOR = Color.RED;
    private boolean alive = false;
    private int x;
    private int y;
    private int width;
    private Rectangle rectangle;

    public SimpleCell(int x, int y, int width) {
        this.x = x;
        this.y = y;
        this.width = width;
        rectangle = new Rectangle(x, y, width, width);
    }

    public boolean isAlive() {
        return alive;
    }

    public void setAlive(boolean alive) {
        this.alive = alive;
    }

    public void draw(Graphics2D g2) {
        if (alive) {
            g2.setColor(CELL_COLOR);
            g2.fill(rectangle);
        }
    }

    public boolean contains(Point p) {
        return rectangle.contains(p);
    }

    @Override
    public String toString() {
        return "SimpleCell [alive=" + alive + ", x=" + x + ", y=" + y + ", width=" + width + ", rectangle=" + rectangle
                + "]";
    }

}