我正在制作一个程序,试图让卡片在屏幕上移动,就好像你真的从桌面上画了一样。以下是动画的代码:
public void move(int x, int y) {
int curX = this.x; //the entire class extends rectangle
int curY = this.y;
// animate the movement to place
for (int i = curX; i > x; i--) {
this.x = i;
}
this.x = x;
this.y = y;
}
此矩形对象位于jframe内部的面板内。为了重新粉刷小组,我有这个:
public void run() {
while (Core.isRunning()) {
gamePanel.repaint(); //panel in which my rectangle object is in
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这是一个线程,每50毫秒重新绘制一次游戏面板。
现在,我意识到这可能不是做这种事情的最好方法。如果有更好的方法来做这整个重绘的事情,请通知我!
但是,我遇到的问题是,当我为我的矩形调用move()
命令时,它会通过线程,但图像不会更新直到结束,所以它只是从点a跳到最后的位置。
为什么会这样?任何人都可以批评/改进我的代码吗?谢谢!
答案 0 :(得分:3)
问题是您在Event Dispatch Thread中调用了Thread.sleep()
,导致GUI无法响应。为避免这种情况,您可能需要使用Swing Timer代替:
Timer timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(!stop) {
gamePanel.repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
timer.setRepeats(true);
timer.setDelay(50);
timer.start();
其中stop
是一个布尔标志,表示动画必须停止。
答案 1 :(得分:-1)
最有可能的是,方法for
中的move()
循环运行速度太快,您看不到任何转换。解决此问题的最简单方法是在move()
方法中在循环内添加睡眠,例如:
public void move(int x, int y) {
int curX = this.x; //the entire class extends rectangle
int curY = this.y;
// animate the movement to place
for (int i = curX; i > x; i--) {
this.x = i;
Thread.sleep(20); // Just experiment with other sleep amounts
}
this.x = x;
this.y = y;
}
关于重绘逻辑,在每个循环中让一个单独的线程重绘所有内容通常是低效的,主要是因为你可能正在重新绘制实际没有变化的东西。通常更新只更新变化的东西会更有效。
在一个复杂的情况下,几个形状相互重叠,你需要确定哪些变化和什么不变,因为如果某些事物没有移动但是被一些形状重叠,你需要更新重叠的形状以确保正确绘制。有一些软化的algortihms可以解决这个问题,但是如果你的场景没有很多形状,那么当事情发生变化时重新绘制所有内容可能会更简单。