我正在筹建John Conway的生命游戏,以便在即将举行的会议上进行演示,我将该程序放在一个应该完成95%的地方,但是,没有任何回应用户输入。几乎看起来我的动作监听器和鼠标监听器没有正确实现,但我不知道在哪里。该计划几乎完全完成;有一些部分仍然是空的,但它仍然可以正确编译和创建我的JFrame。
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
public class GameOfLife
{
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
}
}
包含全局信息的类:
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
public class GLOBAL
{
/**
* Build Information for GameOfLife
*/
public static final double BUILDVERSION = 0.1;
public static final String BUILDNAME = "Alpha 0.1";
/**
* Global Constants for GameOfLife
*/
public static final int FRAMEHEIGHT = 1000; //Frame Height
public static final int FRAMEWIDTH = 1000; //Frame Width
public static final int HEIGHT = 100; //Game Height
public static final int WIDTH = 100; //Game Width
/**
* Global Variables
*/
public static int delay = 500; //Step Delay (Milliseconds)
public static byte[][] herd0; //Herd Byte Array 0
public static byte[][] herd1; //Herd Byte Array 2
public static byte[][] startHerd; //Customized herd before animation is started
public static byte activeArray; //Array currently being displayed
public static boolean active; //States if simulation is repeating
public static long arraySwitches; //Tallies times active array is switched
/**
* Action Commands
*/
public static final String CLOSE = "close"; //Closes Application
public static final String START = "go"; //Starts looping simulation
public static final String STOP = "stop"; //Stops loop
public static final String RULES = "rules"; //Pops up window with Rules for GOL
public static final String ABOUT = "about"; //Displays about dialog
public static final String RESETGRID = "resetGrid"; //Resets the grid to before the simulation
public static final String NEWGAME = "new"; //Zeroes the grid and arrays
}
框:
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.*;
/**
* @author Brendan Kristiansen
*/
public class MyFrame extends JFrame implements ActionListener, ChangeListener
{
private JPanel mPanel;
private JButton start;
private JButton stop;
private JButton setGame;
private JButton resetGame;
private JButton newGame;
private JLabel speedLabel;
private JSlider speed;
private HerdPanel mHerdPanel;
/**
* Constructor
*/
public MyFrame()
{
GLOBAL.active = false;
initArrays();
setSize(GLOBAL.FRAMEWIDTH, GLOBAL.FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mPanel = new JPanel();
initForm();
setVisible(true);
mPanel.setVisible(true);
JMenuBar menu = new JMenuBar();
JMenu game = new JMenu("GameOfLife");
JMenu help = new JMenu("Help");
JMenuItem gamePlay = new JMenuItem("Play");
JMenuItem gameExit = new JMenuItem("Exit");
JMenuItem helpRules = new JMenuItem("Rules");
JMenuItem helpAbout = new JMenuItem("About");
gamePlay.addActionListener(this);
gameExit.addActionListener(this);
helpRules.addActionListener(this);
helpAbout.addActionListener(this);
gamePlay.setActionCommand(GLOBAL.START);
gameExit.setActionCommand(GLOBAL.CLOSE);
helpRules.setActionCommand(GLOBAL.RULES);
helpAbout.setActionCommand(GLOBAL.ABOUT);
game.add(gamePlay);
game.add(gameExit);
help.add(helpRules);
help.add(helpAbout);
menu.add(game);
menu.add(help);
this.setJMenuBar(menu);
this.setVisible(true);
}
/**
* Lays Out Panel
*/
public void initForm()
{
setGame = new JButton("Set Grid");
resetGame = new JButton("Reset Grid");
newGame = new JButton("Clear Grid");
start = new JButton("Start Simulation");
stop = new JButton("Stop Simulation");
speedLabel = new JLabel("Simulation Speed (ms): " + GLOBAL.delay);
// N speed = new JSlider(3000, 50, GLOBAL.delay);
setGame.addActionListener(this);
resetGame.addActionListener(this);
newGame.addActionListener(this);
start.addActionListener(this);
stop.addActionListener(this);
// setGame.setActionCommand(GLOBAL.SETGRID);
resetGame.setActionCommand(GLOBAL.RESETGRID);
newGame.setActionCommand(GLOBAL.NEWGAME);
start.setActionCommand(GLOBAL.START);
stop.setActionCommand(GLOBAL.STOP);
mPanel = new JPanel();
mPanel.setLayout(new BoxLayout(mPanel, BoxLayout.X_AXIS));
mPanel.setBackground(new Color(100, 100, 100));
mHerdPanel = new HerdPanel();
mPanel.add(setGame);
mPanel.add(resetGame);
mPanel.add(newGame);
mPanel.add(start);
mPanel.add(stop);
// mPanel.add(speedLabel);
// mPanel.add(speed);
getContentPane().add(mPanel, BorderLayout.NORTH);
getContentPane().add(mHerdPanel, BorderLayout.CENTER);
}
/**
* Directs ActionEvents to the proper functions
* @param event
*/
@Override
public void actionPerformed(ActionEvent event)
{
String e = event.toString();
if(e.equals(GLOBAL.CLOSE))
{
System.exit(0);
}
else if(e.equals(GLOBAL.START))
{
GLOBAL.active = true;
playGame();
}
else if(e.equals(GLOBAL.STOP))
{
GLOBAL.active = false;
}
else if(e.equals(GLOBAL.NEWGAME))
{
initArrays();
mHerdPanel.paintImage();
}
else if(e.equals(GLOBAL.RESETGRID))
{
GLOBAL.herd0 = GLOBAL.startHerd;
GLOBAL.herd1 = GLOBAL.startHerd;
GLOBAL.activeArray = 0;
mHerdPanel.paintImage();
}
else if (e.equals(GLOBAL.ABOUT))
{
JOptionPane.showMessageDialog(null, "Game of Life\n Developed by Brendan Kristiansen with MSU Storytelling.");
}
else if (e.equals(GLOBAL.RULES))
{
}
}
/**
* Directs ChangeEvents to the proper functions
* @param e
*/
@Override
public void stateChanged(ChangeEvent e)
{
GLOBAL.delay = speed.getValue();
}
/**
* initializes byte arrays to be 0
*/
public void initArrays()
{
GLOBAL.herd0 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
GLOBAL.herd1 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
for(int i = 0; i <= GLOBAL.HEIGHT - 1; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH - 1; j++)
{
GLOBAL.herd0[i][j] = 0;
}
}
GLOBAL.herd1 = GLOBAL.herd0;
GLOBAL.activeArray = 0;
GLOBAL.arraySwitches = 0;
}
/**
*Controls the advancement of the game
*/
public void playGame()
{
GLOBAL.startHerd = GLOBAL.herd0;
if (GLOBAL.active == true)
{
while(GLOBAL.active == true)
{
nextFrame();
try
{
wait(GLOBAL.delay);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
else
{
nextFrame();
}
}
/**
*Advances Game of Life by one frame
*/
public void nextFrame()
{
if (GLOBAL.activeArray == 0)
{
for(int i = 0; i <= GLOBAL.HEIGHT; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH; j++)
{
int neighbors = countNeighbors(i, j, GLOBAL.herd0);
if (neighbors == 3 || neighbors == 4)
{
GLOBAL.herd1[i][j] = 1;
}
else
{
GLOBAL.herd1[i][j] = 0;
}
}
}
GLOBAL.activeArray = 1;
mHerdPanel.paintImage();
}
else
{
for(int i = 0; i <= GLOBAL.HEIGHT; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH; j++)
{
int neighbors = countNeighbors(i, j, GLOBAL.herd1);
if (neighbors == 3 || neighbors == 4)
{
GLOBAL.herd0[i][j] = 1;
}
else
{
GLOBAL.herd0[i][j] = 0;
}
}
}
GLOBAL.activeArray = 0;
mHerdPanel.paintImage();
}
GLOBAL.arraySwitches++;
}
/**
* Counts the living neighbors of a given cell in a herd
* @param i
* @param j
* @param herd
* @return
*/
public int countNeighbors(int i, int j, byte[][] herd)
{
int neighbors = 0;
if(i == 0 && j == 0) //Top left case
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom Neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
}
else if(i == 0 && j == GLOBAL.WIDTH) //Top right case
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(i == GLOBAL.HEIGHT && j == 0) //Bottom left case
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
}
else if(i == GLOBAL.HEIGHT && j == GLOBAL.WIDTH) //Bottom right case
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(i == 0) //Top Row
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(j == 0) //Left side
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
}
else if(i == GLOBAL.HEIGHT) //Bottom Row
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(j == GLOBAL.WIDTH) //Right side
{
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
}
else //Middle of herd
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
}
return neighbors;
}
}
和HerdPanel课程。这应该是一个网格,你可以点击它来改变一个单元格的颜色,然后用你突出显示的单元格玩生命游戏:
/**
*
* @author Brendan Kristiansen
*/
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;
//https://www.shodor.org/stella2java/rgbint.htmlhttps://www.shodor.org/stella2java/rgbint.html
public class HerdPanel extends JPanel implements MouseListener, MouseMotionListener
{
Graphics2D g;
Graphics2D g2;
BufferedImage grid;
BufferedImage bisonCell;
/**
* Constructor
*/
public HerdPanel()
{
setSize(500, 500); //Width, Height
addMouseListener(this);
addMouseMotionListener(this);
try
{
bisonCell = ImageIO.read(new File("bison.png"));
}
catch (IOException e)
{
System.out.println(e);
}
grid = new BufferedImage(GLOBAL.WIDTH, GLOBAL.HEIGHT, 1);
paintImage();
//g = grid.createGraphics();
}
/**
* Converts byte[][] array to BufferedImage
*/
public void paintImage()
{
if (GLOBAL.activeArray == 0)
{
for (int i = 0; i <= GLOBAL.WIDTH - 1; i++)
{
for (int j = 0; j <= GLOBAL.HEIGHT - 1; j++)
{
if (GLOBAL.herd0[j][i] == 0)
{
grid.setRGB(j, i, 16777215);
} else
{
grid.setRGB(j, i, 0);
}
}
}
}
else
{
for (int i = 0; i <= GLOBAL.WIDTH; i++)
{
for (int j = 0; j <= GLOBAL.HEIGHT; j++)
{
if (GLOBAL.herd1[j][i] == 0)
{
grid.setRGB(j, i, 16777215);
} else
{
grid.setRGB(j, i, 0);
}
}
}
}
g = grid.createGraphics();
super.paintComponent(g);
g.drawImage(grid, null, 0, 0);
repaint();
}
@Override
public void mouseClicked(MouseEvent e)
{
int xClick = (int)(e.getX() / GLOBAL.WIDTH);
int yClick = (int) (e.getY() / GLOBAL.HEIGHT);
if(GLOBAL.activeArray == 0)
{
GLOBAL.herd0[yClick][xClick] = 1;
}
else
{
GLOBAL.herd1[yClick][xClick] = 1;
}
paintImage();
}
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseReleased(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
}
@Override
public void mouseDragged(MouseEvent e)
{
}
@Override
public void mouseMoved(MouseEvent e)
{
}
}
答案 0 :(得分:1)
您的playGame
功能在游戏结束前不会返回。 Swing UI是单线程的。在将控制权返回到swing运行时之前,它不会刷新。
您需要在后台任务中计算您的生活游戏,并通过触发框架中的绘画事件来重新绘制ui。
您可以在此处找到有关如何处理此问题的详细说明:Using threads to paint panel in java