Начальные проблемы с перекрашиванием и подсчет соседних проблем

1

Я пытаюсь создать простую симуляцию Game of Life, чтобы оставаться занятой и в нее вошли две проблемы.

Во-первых, моя "доска" не окрашивается в JFrame, когда она сначала инициализируется, но после ее запуска начнется симуляция. Два, мой код countNeighbours не работает. Или, по крайней мере, наблюдаемый результат не является ожидаемым.

Вот код: Интерфейс: -

public class UserInterface extends JFrame
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public static Screen screen;
    private JPanel controls = new JPanel();
    private JButton start = new JButton("Start");
    private JButton reset = new JButton("Reset");
    private JSlider speed = new JSlider();

    Timer t;
    int tSpeed = (speed.getValue()*10)+1;

    public static void main(String[] args)
    {
        new UserInterface();
        screen.repaint();
    }

    public UserInterface()
    {
        super("Game of Life");
        setSize(600,600);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setLayout(new BorderLayout());
        screen = new Screen();
        add(screen,BorderLayout.CENTER);

        controls.add(start);
        controls.add(reset);
        controls.add(speed);

        add(controls,BorderLayout.SOUTH);

        setVisible(true);

        start.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                if(start.getText().equals("Start"))
                {
                    t = new Timer();
                    start.setText("Stop");
                    t.scheduleAtFixedRate(new TimerTask()
                    {
                        public void run()
                        {
                            tSpeed = (speed.getValue()*10)+1;
                            screen.tick();
                        }
                    },0,tSpeed);
                }
                else
                {
                    start.setText("Start");
                    t.cancel();             
                }
            }
        });
    }
}

Экран: -

public class Screen extends JPanel
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Rules rules = new Rules();
    private int WIDTH;
    private int HEIGHT;

    public Screen()
    {
        repaint();
        setVisible(true);
    }

    public void tick()
    {
        WIDTH = UserInterface.screen.getWidth();
        HEIGHT = UserInterface.screen.getHeight();
        rules.tick();
        repaint();
    }

    public void paint(Graphics g)
    {
        boolean[][] b = rules.getBoard();
        for(int y = 0; y < rules.HEIGHT; y++)
        {
            for(int x = 0; x < rules.WIDTH; x++)
            {
                if(b[x][y] == true) g.setColor(Color.YELLOW);
                else g.setColor(Color.BLACK);
                int w = x*(WIDTH/rules.WIDTH);
                int wsize = (WIDTH/rules.WIDTH);
                int h = y*(HEIGHT/rules.HEIGHT);
                int hsize = (HEIGHT/rules.HEIGHT);
                g.fillRect(w,h,wsize,hsize);
            }
        }   
    }
}

Правила: -

public class Rules 
{
    public final int WIDTH = 100;
    public final int HEIGHT = 100;
    private boolean[][] board = new boolean[WIDTH][HEIGHT];
    private boolean[][] tempBoard = new boolean[WIDTH][HEIGHT];

    public Rules()
    {
        for(int y = 0; y < HEIGHT; y++)
        {
            for(int x = 0; x < WIDTH; x++)
            {
                board[x][y] = false;
            }
        }
        board[5][3] = true;
        board[5][4] = true;
        board[6][3] = true;
        board[6][4] = true;
    }

    public void tick()
    {
        for(int y = 0; y < HEIGHT; y++)
        {
            for(int x = 0; x < WIDTH; x++)
            {
                int n = countNeighbors(x,y);
                if(n>=4)
                {
                    tempBoard[x][y] = false;
                }
                else if(n == 2 || n == 3)
                {
                    tempBoard[x][y] = true;
                }
                else if(n<=1)
                {
                    tempBoard[x][y] = false;
                }
            }
        }

        for(int y = 0; y < HEIGHT; y++)
        {
            for(int x = 0; x < WIDTH; x++)
            {
                board[x][y] = tempBoard[x][y];
            }
        }
    }

    private int countNeighbors(int x, int y)
    {
        int n = 0;

        for(int j = 0; j < 3; j++)
        {
            for(int i = 0; i < 3; i++)
            {
                if(i == 1 && j == 1)
                {}
                else
                {
                    try
                    {
                        if(board[x+1-i][y+1-j]==true)n++;
                    }
                    catch(Exception e)
                    {

                    }
                }
            }
        }
        return n;
    }

    public void alternate(int x, int y)
    {
        board[x][y] = !board[x][y];
    }

    public boolean[][] getBoard()
    {
        return board;
    }
}

Я медленно схожу с ума, и я не могу найти то, что я сделал неправильно. Я бы очень признателен всем, кто мог мне помочь.

Теги:
conways-game-of-life

1 ответ

1

Начнем с того, что ваша основная paint JPanel и NOT вызывает super.paint.

Вместо этого вы должны переопределить paintComponent и super.paintComponent что вы вызываете super.paintComponent прежде чем выполнять какую-либо super.paintComponent роспись. Взгляните на выполнение пользовательской живописи

Не полагайтесь на static значения, особенно на ширину и высоту, вместо этого ваш компонент должен указывать подсказки по объему поставки в систему. Проблема в том, что очень сложно точно рассчитать размер рамки, который учитывает различные требования к декорированию рамы. Вместо этого укажите, что ваш компонент определяет его предпочтительный размер и использует метод pack кадров, чтобы обеспечить размер кадра.

Я также не рекомендую использовать java.util.Timer в пользу javax.swing.Timer поскольку есть меньше шансов на нарушение правил единственного потока Swing и меньше требований к тому, чтобы модель была синхронизирована с красками...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню