任何人都可以提供一些关于如何正确创建动画的 help/advice 吗?
Can anyone offer some help/advice on how to correctly create an animation?
所以我正在 java 中创建生活游戏,但我在动画部分遇到了问题。我在 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();
}
}
我实际上要求的是关于如何为某些代码添加动画效果的清晰解释,或者在我 missing/need 添加的正确方向上的一个好点,以使我的代码具有动画效果。
提前感谢您的帮助:D
我会假装你的图形用户界面能正常工作。在您执行的操作中,您需要启动动画。在 swing 中制作动画的一种常见方法是使用 Timer.
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();
}
}
我使用匿名 class taskPerformer
因为那是来自提供的 javadoc link 中的示例。
所以我正在 java 中创建生活游戏,但我在动画部分遇到了问题。我在 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();
}
}
我实际上要求的是关于如何为某些代码添加动画效果的清晰解释,或者在我 missing/need 添加的正确方向上的一个好点,以使我的代码具有动画效果。
提前感谢您的帮助:D
我会假装你的图形用户界面能正常工作。在您执行的操作中,您需要启动动画。在 swing 中制作动画的一种常见方法是使用 Timer.
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();
}
}
我使用匿名 class taskPerformer
因为那是来自提供的 javadoc link 中的示例。