[英]Timing with Swing animation
i have some problems with Swing and animate a character, I Have a JFrame with key listener and when the user hit down,it calls my JPanel method here 我有一些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();
}
This animate my character but so fast that we can see a thing,how do i can do to view the animation? 这为我的角色设置了动画,但速度太快,以至于我们可以看到一个东西,我该怎么做才能观看动画?
The answer is already given by Jonas (use a Swing timer), but it might be useful to explain why you are not seeing the animation, and why the timer is the best solution for this problem. Jonas已经给出了答案(使用Swing计时器),但是解释为什么你没有看到动画可能是有用的,以及为什么计时器是这个问题的最佳解决方案。
Why do I not see the different repaints 为什么我看不到不同的重绘
When you call JComponent#repaint
the JComponent
is not repainted. 当您调用
JComponent#repaint
,不重新JComponent#repaint
JComponent
。 Instead, an asynchronous request to repaint a certain component is scheduled on the EDT. 相反,在EDT上安排重新绘制某个组件的异步请求。 If you invoke many
repaint
calls, Swing might decide to group those requests and repaint the component just once. 如果您调用许多
repaint
调用,Swing可能会决定对这些请求进行分组并仅重新绘制一次该组件。
I did not immediately found an official reference for this in the Oracle documentation (the Swing painting article does not seem to mention it). 我没有立即在Oracle文档中找到这方面的官方参考( Swing绘画文章似乎没有提到它)。 The only place where I found this was in a note in this article , but I am pretty certain this is documented somewhere.
我发现这个的唯一地方是在本文的一个注释中,但我很确定这是在某处记录的。
Why is using a Timer
the best solution 为什么使用
Timer
是最佳解决方案
For an animation, you basically want to say: 对于动画,你基本上想说:
my character should move
x
pixels iny
milliseconds我的角色应该在
y
毫秒内移动x
像素
And preferably, you want to have a smooth animation on screen so you need to repaint rather frequently. 最好是,您希望在屏幕上拥有流畅的动画,因此您需要经常重新绘制。 If you keep in mind that
如果你记住这一点
x
times does not guarantee you that your paint
method is called x
times as well x
次并不能保证您的paint
方法也被调用x
次 The solution to overcome this limitations is to use a Timer
. 克服此限制的解决方案是使用
Timer
。 With the same example (moving a character on screen), you can use a Timer
to update the position of the character and schedule a repaint. 使用相同的示例(在屏幕上移动字符),您可以使用
Timer
更新角色的位置并安排重新绘制。 Since the Timer
code is triggered on the EDT, you do not violate the Swing threading rules. 由于在EDT上触发了
Timer
代码,因此不违反Swing线程规则。
In the paintComponent
method of your component, you then paint the character at the current location. 在组件的
paintComponent
方法中,然后在当前位置绘制字符。 This might be the 'previous location + 1', or the 'previous location +2' (or ...) depending on how many times the Timer
has been triggered between the previous paint
call and the current paint
call. 这可能是“先前位置+ 1”,或“前一个位置+2”(或......),具体取决于在上一次
paint
调用和当前paint
调用之间触发Timer
次数。 This ensures the speed at which your character moves is system-independent. 这可以确保角色移动的速度与系统无关。 Only the smoothness of the animation will depend on your system (as in: how many repaint requests get grouped).
只有动画的平滑度取决于您的系统(如:有多少重绘请求被分组)。
The Swing Timer
tutorial to which Jonas already linked contains more information. Jonas已经链接的Swing
Timer
教程包含更多信息。
don't extend JFrame
, create JFrame
as local variable 不延长
JFrame
,创建JFrame
作为局部变量
don't use KeyListener
, use KeyBindings
instead 不要使用
KeyListener
,而是使用KeyBindings
don't paint directly to the JFrame
, use drawImage()
to the JLabel
or JComponent/JPanel
不要直接绘制到
JFrame
,使用drawImage()
到JLabel
或JComponent/JPanel
This animate my character but so fast that we can see a thing,how do i can do to view the animation?
这为我的角色设置了动画,但速度太快,以至于我们可以看到一个东西,我该怎么做才能观看动画?
another issue with KeyListener
, you have to set for delay betweens two KeyEvents
KeyListener
另一个问题是,您必须设置两个KeyEvents
之间的延迟
You can use a Swing Timer and update the animation in regular intervals. 您可以使用Swing Timer并定期更新动画。 See How to Use Swing Timers
请参见如何使用摆动计时器
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.