我有(应该是)一个简单的问题需要解决,我对其他解决方法持开放态度.我对其他解决方案持开放态度.
问题:我们正在使用java swing来显示基于回合的,基于图块的游戏的图形.我正在使用带有图标的jlabels,绝对定位.
为了动画运动,我使用一个摆动计时器,一次更新4个像素的位置,慢慢地向右,向左移动精灵等.
为了实现这一目标,我正在运行一个计时器,它工作得非常好.当我试图向下移动然后向右移动时,问题出现了.
精灵向下移动,从不向右移动,如果我通过某些控制台打印观察执行,很明显两个计时器同时运行.我已经在互联网上做了相当多的挖掘工作,直到第一个计时器停止,我才能找到一种告诉摆动计时器不执行的方法,如果我尝试忙,等到一个计时器完成(根本没有显示UI(显然是错误方向的一步).
现在我可以完全转离计时器,或者将精灵传送到新的位置,或使用一些可怕的忙等待运动方案,但我希望某种善良的灵魂有解决方案.
简而言之:我需要一种方法来运行一段时间的摇摆计时器,停止它,然后启动一个新的计时器,这样它们就不会重叠.优选地,该方法将允许每个计时器处于其自己的方法中,然后我可以一个接一个地调用这些方法.
提前感谢您提出的任何建议.
编辑:扩展示例代码.如果完整的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();
}
}
Run Code Online (Sandbox Code Playgroud)
}
我最终想在这里看到的是
*C*
*C*
*C*
*C*
*C STOP*
*X*
*X*
*X*
*X*
*X STOP*
Run Code Online (Sandbox Code Playgroud)
我真正得到的是
*C*
*X*
*C*
*X*
*C*
*X*
*C*
*X*
*C STOP*
*X STOP*
Run Code Online (Sandbox Code Playgroud)
我试图在这里得到的一点是运行一个动画周期完成,然后另一个.
再次感谢.
不要使用多个定时器,而是只使用一个定时器来处理每个方向.您需要某种类型的队列来保存方向信息,无论是正式队列还是用作队列的集合(先进先出),然后让Timer在运行时从该队列中提取方向.例如,在这里我通过删除和使用首先添加的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;
}
Run Code Online (Sandbox Code Playgroud)
将所有Icon
s置于某种形式的数组中
Timer
短暂创建一个Swing
在Swing中ActionListener
,从数组中获取每个`Icon,从屏幕中获取getBounds,将Icon移动一步
重复直到达到目标。
归档时间: |
|
查看次数: |
7624 次 |
最近记录: |