2015-05-10 2 views
2

Я использую AnimationTimer для нескольких задач, таких как анимация с меняющимися фотографиями и ProgressIndicator анимация. Для достижения необходимой скорости я помещаю поток в режим сна, но когда несколько анимаций работают одновременно, они влияют на скорость каждого другого. Есть ли другой способ изменить скорость AnimationTimer? Пример кода:Как изменить скорость 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; 
    } 
} 

ответ

4

handle Метод AnimationTimer «ы вызывается один раз для каждого кадра, который вынесенным на FX Application тему. Вы никогда не должны блокировать этот поток, поэтому не звоните 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; 
    } 
} 
+0

Для получения дополнительной информации об использовании 'AnimationTimer', я рекомендую прочитать [this] (http://svanimpe.be/blog/game-loops.html) и [this] (http://svanimpe.be/blog/ game-loops-fx.html) –

+0

Если 'handle' вызывается с фиксированной скоростью, скажем каждые 16 мс или около того, не использует ли этот метод джиттер, делая обновления в 16, 32, 16, 16, 32 мс и т. д. ? –

+0

@StevensMiller Да, в этом случае это повлияет на гладкость (слегка). Ссылки в моем предыдущем комментарии обсуждают возможные решения этого в деталях. Не совсем понятно, почему OP захочет глубже затухать это за «естественной» скоростью рендеринга кадров инструментария JavaFX. –

3

Так как я уже писал код и James_D был быстрее информирующее о том, что вы блокируете пользовательский интерфейс, мне все равно хочется добавить, что если у вас есть несколько AnimationTimers с разными таймингами, вы должны создать для этого выделенный класс. Если каждый из них работает с различной скоростью, можно реализовать так:

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(); 

} 

Это означает, что дескриптор метода() вызывается по крайней мере, после sleepMs прошедших миллисекунд.

Или вы изменяете параметр и указываете fps, что вам нужно.

Вы можете использовать приведенный выше код, как это:

AnimationTimerExt timer = new AnimationTimerExt(100) { 

    @Override 
    public void handle() { 

     System.out.println(System.currentTimeMillis()); 

    } 
}; 

timer.start(); 

Кроме того, загружая картину снова и снова это не самый лучший выбор. Если вы хотите сделать анимацию, я предлагаю вам взглянуть на блог Майка о Creating a Sprite Animation with JavaFX.

+0

Я немного поработал над вашим классом: https://pastebin.com/WGnaf4pK – Hydro

Смежные вопросы