【问题标题】:Java Game of Life using Swing使用 Swing 的 Java 人生游戏
【发布时间】:2017-03-14 02:59:25
【问题描述】:

我正在尝试使用 swing 制作生命游戏的复制品,我承认我使用了其他 1 中的代码,因为我试图了解它,然后继续我自己的实现。我对他们的代码有一些了解,但我想在他们的代码中实现 2 个附加功能。但是我发现它的编写方式存在问题,因为我想添加一个 MouseListener(在单击时使单元格栩栩如生)和 WindowListener(用于启动、暂停和恢复按钮)。

我确实在一定程度上理解它们的工作原理,但我需要你的帮助来解决这个问题。

代码如下:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.Transient;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


@SuppressWarnings("serial")
public class ConwaysGameOfLife extends JPanel implements MouseListener{

    private int[][] cellsGrid; // grid is the size of the 2d array
    private static final Random rnd = new Random(); // make a new random generator
    private int generationCounter; // counter for the generation

    public ConwaysGameOfLife(int width, int height) {
        this.cellsGrid = new int[width / 4][height / 4];// divides by 4 whatever the width and height set is 
        setupGrid();
    }// new method for creating the game with input sizes for the size of the game window

    /*The grid consists fully of cells, the grid size is divided by 4 to make the cells
     * setupGrid makes the grid of cells
     * 
     * */
    private void setupGrid() {
        for (int[] row : cellsGrid) {
            for (int j = 0; j < row.length; j++) {
                if (rnd.nextDouble() < 0.92)
                    continue;
                row[j] = rnd.nextInt(2);
                //
            }
        }
    }
    /*
     * applies the rule to the existing cells changing their state depending on the position to neighbors set in the rules
     * */
    public void updateGrid() {
        for (int i = 0; i < cellsGrid.length; i++) {
            for (int j = 0; j < cellsGrid[i].length; j++) {
                applyRule(i, j);
            }
        }
    }

    // Rules of game of life cells iterations
    private void applyRule(int i, int j) {
        int left = 0, right = 0, up = 0, down = 0;
        int dUpperLeft = 0, dUpperRight = 0, dLowerLeft = 0, dLowerRight = 0;
        //this shows the 8 possible neighbors in terms of position

        if (j < cellsGrid.length - 1) {
            right = cellsGrid[i][j + 1];
            if(i>0)
                dUpperRight = cellsGrid[i - 1][j + 1];
            if (i < cellsGrid.length - 1)
                dLowerRight = cellsGrid[i + 1][j + 1];
        }

        if (j > 0) {
            left = cellsGrid[i][j - 1];
            if (i > 0)
                dUpperLeft = cellsGrid[i - 1][j - 1];
            if (i< cellsGrid.length-1)
                dLowerLeft = cellsGrid[i + 1][j - 1];
        }

        if (i > 0)
            up = cellsGrid[i - 1][j];
        if (i < cellsGrid.length - 1)
            down = cellsGrid[i + 1][j];

        int sum = left + right + up + down + dUpperLeft + dUpperRight
                + dLowerLeft
                + dLowerRight;

        if (cellsGrid[i][j] == 1) {
            if (sum < 2)
                cellsGrid[i][j] = 0;
            if (sum > 3)
                cellsGrid[i][j] = 0;
        }

        else {
            if (sum == 3)
                cellsGrid[i][j] = 1;
        }

    }

    @Override
    @Transient
    public Dimension getPreferredSize() {
        return new Dimension(cellsGrid.length * 4, cellsGrid[0].length * 4);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Color gColor = g.getColor();

        g.drawString("Generation: " + generationCounter++, 0, 10);
        for (int i = 0; i < cellsGrid.length; i++) {
            for (int j = 0; j < cellsGrid[i].length; j++) {
                if (cellsGrid[i][j] == 1) {
                    g.setColor(Color.black); // change colour
                    g.fillRect(j * 8, i * 8, 8, 8); // change size of cells
                }
            }
        }

        g.setColor(gColor);
        //paint the cells to a colour
    }

    public static void main(String[] args) {
        final ConwaysGameOfLife c = new ConwaysGameOfLife(800, 800);
        JFrame frame = new JFrame();
        frame.getContentPane().add(c);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        JButton start=new JButton("START");
        /* This method specifies the location and size
         * of button. In method setBounds(x, y, width, height)
         * x,y) are cordinates from the top left 
         * corner and remaining two arguments are the width
         * and height of the button.
         */
        start.setBounds(80,0,80,20);

        //Adding button onto the frame
        //frame.add(start);

        new Timer(100, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                frame.add(start);
                c.updateGrid();
                c.repaint();
            }
        }).start();
    }


    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub



    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }
}

首先,按钮闪烁,只有当鼠标悬停时才会出现,仍然闪烁。然后我希望在按下开始按钮后开始迭代,并暂停按钮来暂停它,然后继续(有一个不错的想法,它是如何工作的,但不知道如何用这段代码中完成的摇摆结构来实现它。 )

其次,我希望单元格在被鼠标按下时变得栩栩如生,但是,我不确定如何实现 mouseListener 来做到这一点。

我尝试了类似 cellsGrid[i][j] = 1;鼠标点击时出现错误,这是由于我对cellGrid的实现缺乏了解。

我并不期待问题的解决方案,我想要一些指导来更好地理解听众,也许如何让这对我来说更容易理解。谢谢你:)

【问题讨论】:

  • 您每 100 毫秒添加一次“开始”按钮,这可能不是您想要的,因为您将代码放在刷新计时器“循环”中。这可能会导致一些闪烁,但也可能是摆动元素的双缓冲组件。
  • 欢迎来到 Stack Overflow!请使用tour,环顾四周,并通读help center,尤其是How do I ask a good question?What topics can I ask about here?。 - 请仅发布您拥有完全版权的代码。然后:请发布您收到的 complete 错误消息,并在示例中标记错误消息行号所指的行。
  • 放在外面的时候还是会闪烁,swing双缓冲的是哪一部分?
  • 1) 提示:添加@xander(或任何重要的@)以通知此人有新评论。 2)另见working example of GOL

标签: java swing conways-game-of-life


【解决方案1】:

您的模拟有一个模型,它是一个单元格;它有一个 view,它绘制一个 8 x 8 的正方形来表示网格中的一个单元格。正如here 建议的那样,您可以使用linear interpolation 映射模型和视图坐标。特别是,给定以下比例,您可以交叉乘法并求解缺失的坐标。

view.x : panelWidthInPixels :: model.x : modelXRange
view.y : panelHeightInPixels :: model.y : modelYRange

作为参考,这个完整的example 将鼠标坐标映射到图像中的像素坐标。 John Conway’s Game of Life in Java Swing 的完整示例引用here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多