我正在用java创建生命游戏,但我在动画部分遇到了问题。我在一个JComponent上绘制了单元格,它的显示是应该的,但我有一个启动按钮,应该启动整个动画过程,但当我点击启动按钮时,什么也没有发生。
从我所看的教程和我所做的研究中,我知道你一定有一个叫做 "JComponent "的程序。ActionListener
的按钮和一个 actionPerformed()
我的代码如下。
import javax.swing.JFrame;
import java.util.Random;
import java.util.Arrays;
import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.*;
import javax.swing.*;
import java.awt.BorderLayout;
public class GameOfLife extends JFrame {
int PIXELSIZE = 10;
int ROW = 75;
int COLUMN = 75;
Random random = new Random();
JButton start;
public GameOfLife() {
JPanel panel = new JPanel();
DrawCells cellsComp = new DrawCells();
DrawCells buttonListener = new DrawCells();
start = new JButton("Start");
start.addActionListener(cellsComp);
panel.setLayout(new BorderLayout());
start.setToolTipText("Click to start game of life");
this.setTitle("Game Of Life: Java");
this.setSize(PIXELSIZE * ROW, PIXELSIZE * COLUMN);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.add(start, BorderLayout.SOUTH);
panel.add(cellsComp, BorderLayout.CENTER);
this.add(panel);
this.setVisible(true);
}
private class DrawCells extends JComponent implements ActionListener {
int x;
int y;
int grid[][] = new int[ROW][COLUMN];
int updatedGrid[][] = new int[ROW][COLUMN];
public void createGrid() {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = random.nextInt(2);
}
}
}
public void applyRules() {
for (int i = 1; i < ROW - 1; i++) {
for (int j = 1; j < COLUMN - 1; j++) {
int neighboursCount = 0; // used to count the neighbours of each cell
neighboursCount += grid[i-1][j-1]; // top left
neighboursCount += grid[i][j-1]; // top center
neighboursCount += grid[i+1][j-1]; // top right
neighboursCount += grid[i-1][j]; // middle left
neighboursCount += grid[i+1][j]; // middle right
neighboursCount += grid[i-1][j+1]; // top left
neighboursCount += grid[i][j+1]; // top center
neighboursCount += grid[i+1][j+1]; // top right
// Game of Life rules:
// Alive cells:
if (grid[i][j] == 1) {
// rule 1 any live cell with fewer than two live neighboours dies, as if by underpopulation
if (neighboursCount < 2) {
updatedGrid[i][j] = 0;
}
// rule 2 any live cell with two or three live neighbours, lives on to the generation
else if (neighboursCount == 2 || neighboursCount == 3) {
updatedGrid[i][j] = 1;
}
// rule 3 any live cell with more than three live neighbours dies, as if by overpopulation
else if (neighboursCount > 3 && neighboursCount <= 8) {
updatedGrid[i][j] = 0;
}
else {
updatedGrid[i][j] = 0;
}
}
// Dead cells
else if (grid[i][j] == 0) {
// rule 4 any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction
if (neighboursCount == 3) {
updatedGrid[i][j] = 1;
}
else {
updatedGrid[i][j] = 0;
}
}
}
}
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
grid[i][j] = updatedGrid[i][j];
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
createGrid();
Graphics2D g2 = (Graphics2D) g;
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
if (grid[i][j] == 1) {
g2.setColor(Color.RED);
g2.fillRect(i * PIXELSIZE, j * PIXELSIZE, PIXELSIZE, PIXELSIZE);
}
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == start) {
applyRules();
repaint();
thread.sleep();
}
}
}
public static void main(String[] args) {
GameOfLife gol = new GameOfLife();
}
}
其实我想问的是一个清晰的解释 如何让一些代码产生动画效果 或者是一个好的方向指引 我缺少什么需要添加什么才能让我的代码产生动画效果?
先谢谢你的帮助:D
我假设你的gui工作正常。在你执行的动作中,你需要启动动画。在swing中做动画的一个常见方法是使用一个 定时器.
Timer animation;
public void actionPerformed(ActionEvent e) {
if (e.getSource() == start && animation == null) {
createGrid(); //remove this from paint component.
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
applyRules();
repaint();
}
};
animation = new Timer(delay, taskPerformer);
animation.start();
}
}
我使用的是匿名类 taskPerformer
因为那是来自于所提供的javadoc链接中的例子。