如何更改 AnimationTimer 速度?
How to change AnimationTimer speed?
我将 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;
}
}
AnimationTimer
的 handle
方法在 FX 应用程序线程上为渲染的每个帧调用一次。你永远不应该阻塞那个线程,所以不要在这里调用 Thread.sleep(...)
。
传递给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;
}
}
由于我已经编写了代码并且 James_D 通知您有关您阻止 UI 的速度更快,我仍然想补充一点,如果您有多个不同时间的 AnimationTimer,您应该创建一个为此专门 class。如果他们每个人都以不同的速度运行,你可以这样实现:
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();
}
这意味着 handle() 方法至少在 sleepMs 毫秒后被调用。
或者您更改参数并指定 fps,无论您需要什么。
你可以像这样使用上面的代码:
AnimationTimerExt timer = new AnimationTimerExt(100) {
@Override
public void handle() {
System.out.println( System.currentTimeMillis());
}
};
timer.start();
另外,一遍又一遍地加载图片也不是最好的选择。如果你想做动画,我建议你看看 Mike 关于 Creating a Sprite Animation with JavaFX.
的博客
new AnimationTimer() {
int frameCount = 0;
@Override
public void handle(long currentNanoTime) {
if (frameCount % 2 == 0) {
// 30 fps ?
}
frameCount++;
}
可能有点笨拙,但可以完成工作
我将 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;
}
}
AnimationTimer
的 handle
方法在 FX 应用程序线程上为渲染的每个帧调用一次。你永远不应该阻塞那个线程,所以不要在这里调用 Thread.sleep(...)
。
传递给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;
}
}
由于我已经编写了代码并且 James_D 通知您有关您阻止 UI 的速度更快,我仍然想补充一点,如果您有多个不同时间的 AnimationTimer,您应该创建一个为此专门 class。如果他们每个人都以不同的速度运行,你可以这样实现:
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();
}
这意味着 handle() 方法至少在 sleepMs 毫秒后被调用。
或者您更改参数并指定 fps,无论您需要什么。
你可以像这样使用上面的代码:
AnimationTimerExt timer = new AnimationTimerExt(100) {
@Override
public void handle() {
System.out.println( System.currentTimeMillis());
}
};
timer.start();
另外,一遍又一遍地加载图片也不是最好的选择。如果你想做动画,我建议你看看 Mike 关于 Creating a Sprite Animation with JavaFX.
的博客new AnimationTimer() {
int frameCount = 0;
@Override
public void handle(long currentNanoTime) {
if (frameCount % 2 == 0) {
// 30 fps ?
}
frameCount++;
}
可能有点笨拙,但可以完成工作