gpt4 book ai didi

java - 使用按钮启动动画 Java Swing

转载 作者:行者123 更新时间:2023-12-02 10:35:43 25 4
gpt4 key购买 nike

我想在屏幕上创建一些对象(“宇宙飞船”)的动画,并带有开始按钮。这是我到目前为止所拥有的:

public class SpaceGame extends JPanel implements ActionListener {
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);

@Override
public void actionPerformed(ActionEvent e) {
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext()) {
Spaceship s = iter.next();
s.moveSpaceship();

}
repaint();
}

public void paintComponent(Graphics g) {
super.paintComponent(g);

for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
}

public static void main(String[] args) {
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
fr.setSize(990,690);
fr.add(game);

game.playingList .add(new Spaceship(3, 0, 570));
game.playingList .add(new Spaceship(1, 250, 570));
game.playingList .add(new Spaceship(2, 500, 570));


JButton start = new JButton("START");
start.addActionListener(game);
fr.add(start,BorderLayout.SOUTH);

fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

}

地点:

import java.awt.Graphics;

public class Spaceship {
int initialSpeed;
int locX, locY; //current location

public Spaceship(int initalSpeed, int initX, int initY) {
this.initialSpeed = initalSpeed;
locX = initX;
locY = initY;
}

public void drawSpaceship(Graphics g) {
g.setColor(Color.GREEN);
g.fillOval(locX, locY, 100, 40);
}

public void moveSpaceship() {
locY -= initialSpeed;
}


}

当然,这个想法是按下按钮会触发动画。问题是,动画会在没有按下开始按钮的情况下自动开始,然后当动画结束时,该按钮没有任何效果。我该如何解决这个问题?

最佳答案

让我们从显而易见的开始......

public void paintComponent(Graphics g) {
super.paintComponent(g);

for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
}

paintComponent内调用t.start是一个非常非常糟糕的主意。您无法控制绘制过程(即当 paintComponent 被调用时),因此它可能会出于多种原因随时被调用,而且通常是快速连续的。

您应该看看Painting in AWT and Swing有关 Swing 中绘画工作原理的更多详细信息

绘制应该简单地绘制组件的当前状态,而不是其他任何东西。

第二个问题是,Timer 和按钮都调用相同的 actionPerformed 方法,这实际上没有意义。事实上,在完美的世界中,您不会像这样直接实现 ActionListener ,而是使用 Anonymous Classes这将防止外部类直接或间接调用该方法。

那么,解决办法是什么?向您的 SpaceGame 添加一个方法,可以调用该方法来启动动画,例如...

public class SpaceGame extends JPanel implements ActionListener {
//The list of spaceships that should be painted

LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);

public void start() {
if (t.isRunning()) {
return;
}
t.start();
}

@Override
public void actionPerformed(ActionEvent e) {
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext()) {
Spaceship s = iter.next();
s.moveSpaceship();

}
repaint();
}

public void paintComponent(Graphics g) {
super.paintComponent(g);

for (Spaceship s : playingList) {
s.drawSpaceship(g);
}
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);

game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));

JButton start = new JButton("START");
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
game.start();
}
});
fr.add(start, BorderLayout.SOUTH);

fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
}

然后更新您的主要方法来调用它...

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);

game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));

JButton start = new JButton("START");
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
game.start();
}
});
fr.add(start, BorderLayout.SOUTH);

fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}

关于java - 使用按钮启动动画 Java Swing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53309623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com