我在使用 Swing 和动画角色时遇到一些问题, 我有一个带有按键监听器的 JFrame,当用户按下时,它会在此处调用我的 JPanel 方法
for(int i=1;i<4;i++)
{
pY+=16;
g.drawImage(perso,pX,pY,pX+50,pY+50,0+50*i,0,50+50*i,50,this
this.repaint();
}
这为我的角色设置了动画,但速度太快,我们可以看到一个东西,我该如何查看动画?
最佳答案
Jonas 已经给出了答案(使用 Swing 计时器),但解释为什么您看不到动画以及为什么计时器是此问题的最佳解决方案可能会很有用。
为什么我看不到不同的重绘
当您调用JComponent#repaint
时JComponent
没有重新粉刷。相反,重绘某个组件的异步请求会在 EDT 上安排。如果您调用许多 repaint
调用时,Swing 可能会决定对这些请求进行分组并仅重绘组件一次。
我没有立即在 Oracle 文档中找到对此的官方引用(Swing painting article 似乎没有提及它)。我唯一找到这个的地方是在 this article 的注释中。 ,但我很确定这在某处有记录。
为什么使用 Timer
最佳解决方案
对于动画,你基本上想说的是:
my character should move
x
pixels iny
milliseconds
最好,您希望屏幕上有流畅的动画,因此需要经常重新绘制。如果你记住这一点
- 与 Swing 组件的所有交互都应在 EDT 上进行(事件调度线程,请参阅 Concurrency in Swing 文章了解更多信息)
- 您永远不应该阻止 EDT,因为这会卡住您的 UI,这意味着您无法在 EDT 中“等待”直到重绘完成,否则重绘永远不会发生
- 重绘请求可以分组,因此调用重绘
x
时代并不保证您的paint
方法调用x
次也是如此
克服此限制的解决方案是使用 Timer
。对于相同的示例(在屏幕上移动角色),您可以使用 Timer
更新角色的位置并安排重新绘制。自 Timer
代码在 EDT 上触发,您没有违反 Swing 线程规则。
在 paintComponent
方法,然后在当前位置绘制角色。这可能是“先前位置 + 1”或“先前位置 +2”(或...),具体取决于 Timer
的次数。已在之前的 paint
之间触发通话和当前paint
称呼。这确保了角色移动的速度与系统无关。只有动画的平滑度取决于您的系统(例如:对多少个重绘请求进行分组)。
Swing Timer
tutorial乔纳斯已经链接到的内容包含更多信息。
关于java - Swing 动画的计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11088910/