我在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();
}
这会激活我的角色,但速度太快,以至于我们可以看到一个东西,我该怎么做才能观看动画?
答案 0 :(得分:7)
Jonas已经给出了答案(使用Swing计时器),但解释为什么你没有看到动画,以及为什么计时器是解决这个问题的最佳解决方案可能是有用的。
为什么我看不到不同的重绘
当您致电JComponent#repaint
时,JComponent
未重新粉饰。相反,在EDT上安排重新绘制某个组件的异步请求。如果您调用了许多repaint
个调用,Swing可能会决定对这些请求进行分组并重新绘制该组件一次。
我没有立即在Oracle文档中找到这方面的官方参考(Swing painting article似乎没有提到它)。我发现这个的唯一地方是this article中的一个注释,但我很确定这是在某处记录的。
为什么使用Timer
最佳解决方案
对于动画,你基本上想说:
我的角色应在
x
毫秒内移动y
像素
最好,您希望在屏幕上拥有流畅的动画,因此您需要经常重新绘制。如果你记住
x
次并不能保证您的paint
方法也被x
次调用克服此限制的解决方案是使用Timer
。使用相同的示例(在屏幕上移动角色),您可以使用Timer
更新角色的位置并安排重新绘制。由于在EDT上触发了Timer
代码,因此您不会违反Swing线程规则。
在组件的paintComponent
方法中,然后在当前位置绘制角色。这可能是“之前的位置+ 1”,或“之前的位置+2”(或...),具体取决于之前Timer
来电与paint
之间触发paint
次的次数当前{{1}}来电。这可以确保角色移动的速度与系统无关。只有动画的平滑度取决于您的系统(例如:有多少重绘请求被分组)。
Jonas已经链接的Swing Timer
tutorial包含更多信息。
答案 1 :(得分:3)
不要展开JFrame
,创建JFrame
作为本地变量
请勿使用KeyListener
,请改用KeyBindings
不要直接在JFrame
上绘画,使用drawImage()
到JLabel
或JComponent/JPanel
这会激活我的角色,但速度太快,以至于我们可以看到一个东西,我该怎么做才能观看动画?
KeyListener
的另一个问题,您必须设置两个KeyEvents
之间的延迟
答案 2 :(得分:2)
您可以使用Swing Timer并定期更新动画。见How to Use Swing Timers