ともさんのHP >プロブラミング >JavaFX >AnimationTimerとTimelineの違い

JavaFXでアニメーション AnimationTimerとTimelineの違い

JavaFXを使ってアニメーションを表示する方法について説明しています。
二つの方法で立方体を回転させるアニメーションを作りました。
JavaFXアニメーション


広告


AnimationTimerを用いる

AnimationTimerを使って割り込みを行い、この中で動かします。
アニメーションタイマーは60FPSで割り込みをかけます。逆に言うと1秒間に60回です。
サンプルプログラムでは、1秒間経つごとに立方体の角度を変えています。
handleメソッドで現在の時刻がナノミリ秒単位で得られるので、これを使って経過時間を調べています。

サンプルプログラム

package x_test.fx;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.*;
import javafx.stage.Stage;

/**単純なJavaFX楽天 プログラム
 *アニメーション
 * */
public class BoxAnimation extends Application {
Rotate boxrotateX = null;
Rotate boxrotateY = null;

 public static void main(String[] args) {
  Application.launch(args);
 }
 
 @Override
 public void start(Stage stage) throws Exception {
  Scene scene = make3dScene();
  stage.setScene(scene);
  //タイトルの表示
  stage.setTitle("AnimationTimer");
  stage.show();
  //アニメーションを始める
 new Animation().start();
 }

private Scene make3dScene(){
 Group group = new Group();
 //箱を置く
 Box box = new Box( 10 , 10 , 10 );
 boxrotateX = new Rotate( 0 , new Point3D( 1 , 0 , 0 ) );
 boxrotateY = new Rotate( 0 , new Point3D( 0 , 1 , 0 ) );
 box.getTransforms().add( boxrotateX );
 box.getTransforms().add( boxrotateY );
 group.getChildren().add( box );
 // カメラを置く
 PerspectiveCamera camera = new PerspectiveCamera( true );
 //方向と位置
 Translate cameratranslate = new Translate(0,0,-50);
 camera.getTransforms().add( cameratranslate ); 
 //視界の角度
 camera.setFieldOfView( 30. );
 group.getChildren().add( camera ); 
 //点光源を置く
 LightBase light = new PointLight();
 light.setTranslateX(  30.0 );
 light.setTranslateY( -30.0 );
 light.setTranslateZ( -30.0 );
 group.getChildren().add( light );
 //Sceneの設定
 Scene s3d = new Scene(group, 640, 480);
 s3d.setFill(Color.ALICEBLUE);
 s3d.setCamera( camera );
return s3d;
}

 private class Animation extends AnimationTimer {
 long stime   = 0;
 long foreno = -1;
 int i=-1;
  @Override
  public void handle(long now) {
  //nowはナノ秒単位
   if( stime == 0 ){ stime = now; }
   i++;
   //所定時間経過の確認
   Long no = (Long)( ( now - stime )/1000000000 );
   if( foreno != no ){ foreno = no; } else { return; }
   System.out.println(no+" 秒経過  " + i +" 回/秒" );
   i=0;
   //更新作業
   boxrotateX.setAngle( no );
   boxrotateY.setAngle( no );
  }
 }
}


Timelineを用いる

Timelineを使うと割り込み間隔は1msごとに設定できます、最小で1秒間に1000回割り込むことが可能です。
間隔は初期化時に決めます。

Timeline timer = new Timeline(new KeyFrame(Duration.millis(1), new EventHandler(){ }));

アニメーションの場合は60FPSでも十分ですが、割り込みでたくさんの計算をしたい場合はこちらを使うほうが良いでしょう。
計算が長くて終わらない場合は、タイマーを一旦止めてから計算して終わった後に再始動します。
これをしないと計算中に次の割り込みがかかってしまいます。
しかし一旦止めてから再開するとこれにも時間がかかるので、悩ましいところです。
それでも時間の掛かる計算をする場合は、一旦止めてから重い計算を実行して再開した方がAnimationTimerを用いるよりも早くなります。
こちらのサンプルプログラムも1秒経つことに立方体の角度を変えています。
動作は同じですが、AnimationTimerは60回ほどの割り込み、タイムラインは1000回の割り込みを行っています。

サンプルプログラム

package x_test.fx;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.*;
import javafx.stage.Stage;
import javafx.util.Duration;

/**単純な Java 楽天 FXプログラム
 *アニメーション
 * */
public class BoxTimeLine extends Application {
Rotate boxrotateX = null;
Rotate boxrotateY = null;
public Timeline timer=null;

 public static void main(String[] args) {
  Application.launch(args);
 }

 @Override
 public void start(Stage stage) throws Exception {
  Scene scene = make3dScene();
  stage.setScene(scene);
  //タイトルの表示
  stage.setTitle("AnimationTimer");
  stage.show();
  //アニメーションを始める
 this.setTimer();
 }

private Scene make3dScene(){
 Group group = new Group();
 //箱を置く
 Box box = new Box( 10 , 10 , 10 );
 boxrotateX = new Rotate( 0 , new Point3D( 1 , 0 , 0 ) );
 boxrotateY = new Rotate( 0 , new Point3D( 0 , 1 , 0 ) );
 box.getTransforms().add( boxrotateX );
 box.getTransforms().add( boxrotateY );
 group.getChildren().add( box );
 //  カメラ 楽天 を置く
 PerspectiveCamera camera = new PerspectiveCamera( true );
 //方向と位置
 Translate cameratranslate = new Translate(0,0,-50);
 camera.getTransforms().add( cameratranslate );
 //視界の角度
 camera.setFieldOfView( 30. );
 group.getChildren().add( camera );
 //点光源を置く
 LightBase light = new PointLight();
 light.setTranslateX(  30.0 );
 light.setTranslateY( -30.0 );
 light.setTranslateZ( -30.0 );
 group.getChildren().add( light );
 //Sceneの設定
 Scene s3d = new Scene(group, 320, 240);
 s3d.setFill(Color.ALICEBLUE);
 s3d.setCamera( camera );
return s3d;
}


long foreno = -1;
long i=-1;


 private void setTimer() {
 //タイマーをセットする
timer = new Timeline(new KeyFrame(Duration.millis(1), new EventHandler<ActionEvent>(){
@Override
public void handle( ActionEvent event ){
//timer.pause();
  i++;
  //所定時間経過の確認
   Long no = (Long)( i/1000 );
   //System.out.println( i +" 回/秒" );
   if( foreno != no ){ foreno = no; } else { /*timer.play();*/return; }
   System.out.println( no+" 秒経過  " );
   //i=0;
   //更新作業
   boxrotateX.setAngle( no*2 );
   boxrotateY.setAngle( no*2 );
//timer.play();
return;
}
}));
timer.setCycleCount(Timeline.INDEFINITE);
timer.play();
return;
}

最終更新日: 2020-03-16 14:34:57

ともさんのHP >プロブラミング >JavaFX >AnimationTimerとTimelineの違い

広告
新着ページ

椅子の買い替え  
実用的な温室の自作  
畑小屋の設計と製作  
クズ(葛)の枯らし方  
ソラマメの栽培方法  
フリーソフト開発者の嘆き  
任形状の平面ポリゴンの作成方法  
電子部品棚を処分する  
USBカメラで天体写真撮影  
顕微鏡+USBカメラ  
デジタルスリットカメラの自作  

他のサイト

3D-CAD
洋裁CAD

いいねなど

 RSS 

Author: Tomoyuki Ito

このサイトの文章・写真の無断転載を禁じます