使用Swing的Java生活游戏
我正在尝试使用swing制作一个生活游戏的复制品,我承认我使用了其他人的代码,因为我正在尝试了解它,然后继续我自己的实现。我对他们的代码有一些了解,但我想在他们的代码中实现另外两个特性。然而,我发现它的编写方式带来了一些问题,因为我想添加一个鼠标侦听器,使单元格在单击时恢复活力,并使用WindowListener创建开始、暂停和恢复按钮 在某种程度上,我确实理解它们是如何工作的,但我需要你的帮助来解决这个问题 代码如下:使用Swing的Java生活游戏,java,swing,conways-game-of-life,Java,Swing,Conways Game Of Life,我正在尝试使用swing制作一个生活游戏的复制品,我承认我使用了其他人的代码,因为我正在尝试了解它,然后继续我自己的实现。我对他们的代码有一些了解,但我想在他们的代码中实现另外两个特性。然而,我发现它的编写方式带来了一些问题,因为我想添加一个鼠标侦听器,使单元格在单击时恢复活力,并使用WindowListener创建开始、暂停和恢复按钮 在某种程度上,我确实理解它们是如何工作的,但我需要你的帮助来解决这个问题 代码如下: import java.awt.Color; import java.aw
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
}
}
首先,按钮会闪烁,只有当鼠标悬停在上方时才会出现,仍然闪烁。然后,我希望迭代在按下start按钮后开始,并使用pause按钮暂停它,我有一个不错的想法,知道它将如何工作,但不知道如何用这段代码中完成的swing结构来实现它
第二,我希望细胞在被鼠标按下时能够复活,但是,我不确定如何实现鼠标侦听器来实现这一点
我试过像cellsGrid[I][j]=1这样的东西;当用鼠标点击时,我会出错,这是因为我对cellsGrid的实现缺乏了解
我并不期待问题的解决方案,我想要一些指导来更好地理解听众,也许是如何让我更容易理解。谢谢:您的模拟有一个网格单元模型;它有一个视图,可以绘制一个8 x 8的正方形来表示网格中的单元。正如建议的那样,可以使用映射模型和视图坐标。特别是,给定以下比例,可以交叉乘法并求解缺少的坐标
view.x:panelWidthInPixels::model.x:modelXRange
view.y:panelHeightInPixels::model.y:modelRange
作为参考,这完整的映射鼠标坐标到图像中的像素坐标。引用了一个完整的示例。您每100毫秒添加一次开始按钮,这可能不是您想要的,因为您将代码放在刷新计时器循环中。这可能会导致一些闪烁,但也可能是对swing元素的双缓冲组件造成的。欢迎使用堆栈溢出!请拿着这本书,四处看看,仔细阅读,尤其是和请仅使用您拥有完全版权的代码。然后:请发布您收到的完整错误消息,并在示例中标记错误消息行号所指的行。当它放置在外部时,它仍然闪烁,哪个部分由swing双重缓冲?1提示:添加@xander或其他人,@对于通知此人新的评论非常重要。2也请看这一点。