我在java中制作一个简单的棋盘游戏,我想在其中制作动画骰子。所以我用这样的骰子拍照:
public Timer roll_dice = new Timer(50, this);
...
public void actionPerformed(ActionEvent evt) {
if(roll_dice.getDelay() > 500){
roll_dice.setDelay(50);
roll_dice.stop();
movePiece();
}else{
roll_dice.setDelay(roll_dice.getDelay() + 50);
dice_panel.repaint(0);
}
}
}
movePiece(){
//do some more painting
}
所以骰子会这样显示几次随机数,然后慢慢地确定一个数字。完成后我想调用movePiece()
方法。但是,实际上,重新绘制会偶尔出现并将所有内容拧紧,以便在骰子卷实际完成动画之前调用movePiece()
。
有没有人有任何想法我怎么能在最后的重画发生后调用movePiece?
答案 0 :(得分:1)
所以骰子会这样显示几次随机数,然后慢慢地确定一个数字。完成之后我想调用movePiece()方法。然而,实际上,重新绘制偶尔发生并将所有内容都拧紧,以便在骰子卷实际完成动画之前调用movePiece()。
这里让我担心的是为什么你的绘画偶尔发生 - 它根本不应该这样做,也许 是你需要修复的。我想知道你每次进行绘图时是否正在读取文件中的图像,或者其他原因是为了减慢绘图速度。如果您在此问题上需要更多帮助,那么您必须向我们提供有关您如何进行绘画的更多信息。无论如何,你应该避免使程序逻辑依赖于绘画,因为你无法完全控制何时或甚至是否会发生绘画。
为什么不在程序启动时简单地将滚动的骰子图像放入ImageIcons,然后在Swing Timer中,在JLabel中交换图标,而不是重绘图像并调用repaint()。然后在延迟时间足够长的情况下停止你的计时器,如果是块,请移动你的计件。
因此,假设你有几个骰子,每个骰子都可以由一个名为diceLabel的JLabel数组中的JLabel显示,而ImageIcons可以保存在一个名为diceIcons的数组中。然后你可以做类似的事情:
public void actionPerformed(ActionEvent e) {
if (roll_dice.getDelay() > 500) {
roll_dice.setDelay(50);
roll_dice.stop();
movePiece(); // I like this -- this shouldn't change
} else {
roll_dice.setDelay(roll_dice.getDelay() + 50);
// dice_panel.repaint(0);
for (JLabel dieLabel : diceLabels) {
int randomIndex = random.nextInt(diceIcons.length);
dieLabel.setIcon(diceIcons[randomIndex]);
}
}
}
当你致电movePiece()
时,我喜欢你的逻辑,我认为这应该保持不变。
答案 1 :(得分:0)
您可以在另一个线程中调用滚动并将当前线程加入()到滚动线程。这样主代码将等到滚动螺纹死亡(完成滚动)。
public void actionPerformed(ActionEvent evt) {
if(roll_dice.getDelay() > 500){
Thread rollerThread = new RollerThread();
rollerThread.start();
rollerThread.join();
movePiece();
}
else{
roll_dice.setDelay(roll_dice.getDelay() + 50);
dice_panel.repaint(0);
}
}
private RollerThread extends Thread
{
public void run(){
roll_dice.setDelay(50);
roll_dice.stop();
}
}
但是,这可能不适用于EDT - 因为重新绘制应该计划到队列。也许你可以使用SwingUtilities.invokeAndWait()
:
public void actionPerformed(ActionEvent evt) {
Thread thread = new Thread(){
public void run(){
if(roll_dice.getDelay() > 500){
SwingUtilities.invokeAndWait(new Runnable(){
public void run(){
roll_dice.setDelay(50);
roll_dice.stop();
}
});
movePiece();
}
else{
roll_dice.setDelay(roll_dice.getDelay() + 50);
dice_panel.repaint(0);
}
}
};
thread.start();
}
答案 2 :(得分:0)
如果您将movePiece();
中的SwingUtilities.invokeLater(Runnable);
拨打电话,那会有什么变化吗?
if(roll_dice.getDelay() > 500){
roll_dice.setDelay(50);
roll_dice.stop();
SwingUtilities.invokeLater(new Runnable() {
public void run() { movePiece(); }
});
}
...