gpt4 book ai didi

java - 多个 Swing 计时器

转载 作者:行者123 更新时间:2023-12-02 09:22:33 25 4
gpt4 key购买 nike

我有(应该是)一个简单的问题需要解决,并且我愿意接受其他方法来解决它。我对其他解决方案持开放态度。

问题:我们使用 java swing 来显示回合制、基于图 block 的游戏的图形。我使用带有图标的 jlabel,绝对定位。

为了制作运动动画,我使用了一个 Swing 计时器,每次更新 4 个像素的位置,慢慢地向右、向左移动 Sprite ,等等。

为了最初实现这一目标,我运行了一个计时器,效果非常好。当我尝试向下移动然后向右移动时,问题就出现了。

Sprite 向下移动,永远不会向右移动,如果我通过一些控制台打印来观察执行情况,可以清楚地看到两个计时器同时运行。我在互联网上进行了大量的挖掘,但我无法找到一种方法来告诉 Swing 计时器在第一个计时器停止之前不要执行,并且如果我尝试忙等待直到一个计时器完成(恶心)用户界面根本不显示(显然是朝着错误方向迈出的一步。)

现在我可以完全摆脱计时器,要么让 Sprite 传送到新位置,要么使用一些可怕的忙等待移动方案,但我希望有一个好心的灵魂有一个解决方案。

简而言之:我需要一种方法来运行 Swing 计时器一段设定的时间,停止它,然后然后启动一个新的计时器,这样它们就不会重叠。最好这个方法允许每个计时器都在它自己的方法中,然后我可以一个接一个地调用这些方法。

预先感谢您提供的任何建议。

编辑:扩展示例代码。如果您的建议需要完整的 scsse,那么我很抱歉浪费了您的时间,因为完整的代码是一个野兽。抱歉,这个示例代码根本不起作用,但它应该说明了这一点。

所以。我们有两个函数,每个函数都有一个运行动画周期的计时器,一个用于向下和向右对角线移动,一个用于垂直向下移动。

public class TestClass {
static int counter = 0;
static int counter2 = 0;
static Timer timerC;
static Timer timerX;

public static void main(String[] args) {
moveC();
moveX();
}

public static void moveC() {
int delay = 200; // milliseconds

timerC = new Timer(delay, null);
timerC.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (counter < 32) {
counter = counter + 4;
System.out.println("*C*");
} else {
timerC.stop();
System.out.println("*C STOP*");
}

}
});
timerC.start();
}

public static void moveX() {
int delay = 200; // milliseconds

timerX = new Timer(delay, null);
timerX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (counter < 32) {
counter = counter + 4;
System.out.println("*X*");
} else {
timerX.stop();
System.out.println("*X STOP*");
}

}
});
timerX.start();
}

}

我最终希望在这里看到的是

*C*
*C*
*C*
*C*
*C STOP*
*X*
*X*
*X*
*X*
*X STOP*

我实际得到的是

*C*
*X*
*C*
*X*
*C*
*X*
*C*
*X*
*C STOP*
*X STOP*

我在这里想要表达的观点是运行一个动画周期完成,然后运行另一个。

再次感谢。

最佳答案

不要使用多个计时器,而只使用一个计时器来根据需要处理每个方向。您需要某种类型的队列来保存方向信息,可以是正式队列,也可以是用作队列的集合(先进先出),然后让您的计时器在运行时从该队列中提取方向。例如,在这里,我通过删除并使用首先添加的 Direction(在 JList 顶部)来使用 JList 的模型作为队列:

import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;

public class TimerPlay extends JPanel {
private DefaultListModel directionJListModel = new DefaultListModel();
private JList directionJList = new JList(directionJListModel);
JButton startTimerButton = new JButton(
new StartTimerBtnAction("Start Timer"));

public TimerPlay() {
ActionListener directionBtnListener = new ActionListener() {

@Override
public void actionPerformed(ActionEvent actEvt) {
String actionCommand = actEvt.getActionCommand();
Direction dir = Direction.valueOf(actionCommand);
if (dir != null) {
directionJListModel.addElement(dir);
}
}
};
JPanel directionBtnPanel = new JPanel(new GridLayout(0, 1, 0, 10));
for (Direction dir : Direction.values()) {
JButton dirBtn = new JButton(dir.toString());
dirBtn.addActionListener(directionBtnListener);
directionBtnPanel.add(dirBtn);
}

add(directionBtnPanel);
add(new JScrollPane(directionJList));
add(startTimerButton);
}

private class StartTimerBtnAction extends AbstractAction {
protected static final int MAX_COUNT = 20;

public StartTimerBtnAction(String title) {
super(title);
}

@Override
public void actionPerformed(ActionEvent arg0) {
startTimerButton.setEnabled(false);

int delay = 100;
new Timer(delay, new ActionListener() {
private int count = 0;
private Direction dir = null;

@Override
public void actionPerformed(ActionEvent e) {
if (count == MAX_COUNT) {
count = 0; // restart
return;
} else if (count == 0) {
if (directionJListModel.size() == 0) {
((Timer)e.getSource()).stop();
startTimerButton.setEnabled(true);
return;
}
// extract from "queue"
dir = (Direction) directionJListModel.remove(0);
}
System.out.println(dir); // do movement here
count++;

}
}).start();
}
}

private static void createAndShowGui() {
TimerPlay mainPanel = new TimerPlay();

JFrame frame = new JFrame("TimerPlay");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}

}

enum Direction {
UP, DOWN, LEFT, RIGHT;
}

关于java - 多个 Swing 计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10809814/

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