简体   繁体   English

使用Swing动画进行计时

[英]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 in y 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 如果你记住这一点

  • All interaction with the Swing components should happen on the EDT (Event Dispatch Thread, see the Concurrency in Swing article for more info) 所有与Swing组件的交互都应该在EDT上进行(事件调度线程,请参阅Swutch中Concurrency文章了解更多信息)
  • You should never block the EDT as this will freeze your UI, meaning you cannot 'wait' in the EDT until a repaint is done or the repaint will never happen 你永远不应该阻止EDT,因为这会冻结你的UI,这意味着你不能在EDT中“等待”,直到重绘完成或重绘永远不会发生
  • Repaint requests can be grouped, so calling repaint 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教程包含更多信息。

  1. don't extend JFrame , create JFrame as local variable 不延长JFrame ,创建JFrame作为局部变量

  2. don't use KeyListener , use KeyBindings instead 不要使用KeyListener ,而是使用KeyBindings

  3. don't paint directly to the JFrame , use drawImage() to the JLabel or JComponent/JPanel 不要直接绘制到JFrame ,使用drawImage()JLabelJComponent/JPanel

  4. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM