java 如何更改 AnimationTimer 速度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30146560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change AnimationTimer speed?
提问by Alyona
I use AnimationTimer
for several tasks like animation with changing pictures and ProgressIndicator
animation. To achieve needed speed I put thread to sleep, but when several animations are running simultaneously they affect each others speed. Is there any other way to change speed of AnimationTimer
? Code sample:
我AnimationTimer
用于多个任务,例如带有不断变化的图片和ProgressIndicator
动画的动画。为了达到所需的速度,我让线程进入睡眠状态,但是当多个动画同时运行时,它们会影响彼此的速度。有没有其他方法可以改变速度AnimationTimer
?代码示例:
private void initialize() {
programButtonAnimation=new AnimationTimer(){
@Override
public void handle(long now) {
showClockAnimation();
}
};
programButtonAnimation.start();
}
private void showClockAnimation(){
String imageName = "%s_"+"%05d"+".%s";
String picturePath="t093760/diploma/view/styles/images/pink_frames/"+String.format( imageName,"pink" ,frameCount,"png");
programButton.setStyle("-fx-background-image:url('"+picturePath+"')");
frameCount++;
try {
Thread.sleep(28);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(frameCount>=120){
programButtonAnimation.stop();
frameCount=0;
}
}
回答by James_D
The AnimationTimer
's handle
method is invoked once for each frame that is rendered, on the FX Application Thread. You should never block that thread, so do not call Thread.sleep(...)
here.
所述AnimationTimer
的handle
方法被调用一次,所呈现,在FX应用程序线程的每个帧。你永远不应该阻塞那个线程,所以不要Thread.sleep(...)
在这里调用。
The parameter passed to the handle(...)
method is a timestamp, in nanoseconds. So if you want to throttle updates so they don't happen more than once every, say 28 milliseconds, you can use this to do so:
传递给该handle(...)
方法的参数是一个时间戳,以纳秒为单位。因此,如果您想限制更新,使更新不会超过一次,例如 28 毫秒,您可以使用它来执行此操作:
private void initialize() {
programButtonAnimation=new AnimationTimer(){
private long lastUpdate = 0 ;
@Override
public void handle(long now) {
if (now - lastUpdate >= 28_000_000) {
showClockAnimation();
lastUpdate = now ;
}
}
};
programButtonAnimation.start();
}
private void showClockAnimation(){
String imageName = "%s_"+"%05d"+".%s";
String picturePath="t093760/diploma/view/styles/images/pink_frames/"+String.format( imageName,"pink" ,frameCount,"png");
programButton.setStyle("-fx-background-image:url('"+picturePath+"')");
frameCount++;
if(frameCount>=120){
programButtonAnimation.stop();
frameCount=0;
}
}
回答by Roland
Since I already wrote the code and James_D was faster with informing you about you blocking the UI, I still like to add that if you have multiple AnimationTimers of different timings you should create a dedicated class for that. If each of them runs at a different speed, you could implement it like that:
由于我已经编写了代码并且 James_D 更快地通知您您阻止了 UI,我仍然想补充一点,如果您有多个不同时间的 AnimationTimer,您应该为此创建一个专用类。如果它们中的每一个都以不同的速度运行,您可以像这样实现它:
import javafx.animation.AnimationTimer;
public abstract class AnimationTimerExt extends AnimationTimer {
private long sleepNs = 0;
long prevTime = 0;
public AnimationTimerExt( long sleepMs) {
this.sleepNs = sleepMs * 1_000_000;
}
@Override
public void handle(long now) {
// some delay
if ((now - prevTime) < sleepNs) {
return;
}
prevTime = now;
handle();
}
public abstract void handle();
}
Which means that the handle() method is invoked at least after sleepMs milliseconds have passed.
这意味着至少在经过 sleepMs 毫秒后调用 handle() 方法。
Or you change the parameter and specify the fps, whatever you need.
或者您可以更改参数并指定 fps,无论您需要什么。
You can use the above code like this:
您可以像这样使用上面的代码:
AnimationTimerExt timer = new AnimationTimerExt(100) {
@Override
public void handle() {
System.out.println( System.currentTimeMillis());
}
};
timer.start();
Also, loading the picture over and over again is not the best choice. If you'd like to do animations, I suggest you take a look at Mike's Blog about Creating a Sprite Animation with JavaFX.
此外,一遍又一遍地加载图片也不是最好的选择。如果您想做动画,我建议您查看 Mike 的关于使用 JavaFX 创建 Sprite 动画的博客。
回答by Progreg
new AnimationTimer() {
int frameCount = 0;
@Override
public void handle(long currentNanoTime) {
if (frameCount % 2 == 0) {
// 30 fps ?
}
frameCount++;
}
might be a bit hacky but gets the job done
可能有点hacky但可以完成工作