JavaFX アニメーションのサンプルプログラム
AnimationTimerを使ったノードのアニメーションのサンプルプログラムを紹介します。
Cameraの扱いかた (こちら
)を読まれてから読むと判りやすいと思います。このページではカメラの代わりにボックスを動かしています。
サンプルプログラムを実行すると下記のように表示されます。
アニメーション化する手順
AnimationTimerをextendsしたインナークラスを作り、start()メソッドを実行すると、インナークラス内のhandle()が呼び出されます。
public class BoxAnimation extends Application {
public static void main(String[] args) {
Application.launch(args);
}
public void start(Stage stage) throws Exception {
//アニメーションを始める
new Animation().start();
}
private class Animation extends AnimationTimer {
@Override
public void handle(long now) {
}
}
}
BOXを回転する場合、あらかじめボックスをRotateで回転させておき、handleの中でRotateの角度を変更します。
JavaSwingに慣れていたので、repaint()が無くて最初はかなり戸惑いました。
Rotate boxrotateX = null;
Rotate boxrotateY = null;
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 );
public void handle(long now) {
boxrotateX.setAngle( no );
boxrotateY.setAngle( no );
}
アニメーション速度の設定
handle()の呼び出されるままにアニメーションすると速すぎるので、設定時間より早ければreturnします。 Handleで得られるlong nowは単位ナノ秒で示される経過時間です。
private class Animation extends AnimationTimer {
// アニメーション間隔の設定
long kankaku = 50 * 1000000L; //50ミリ秒
long stime = 0;
long foreno = -1;
@Override
public void handle(long now) {
if( stime == 0 ){ stime = now; }
//所定時間経過の確認
Long no = (Long)(( now - stime ) / kankaku );
if( foreno != no ){ foreno = no; } else { return; }
}
}
アニメーションサンプルプログラム
全体のコードは下記のようになります。
package tomojavalib.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;
/**単純な
Java
楽天 FXプログラム
*アニメーション
* */
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("アニメーション試験");
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, 320, 240);
s3d.setFill(Color.ALICEBLUE);
s3d.setCamera( camera );
return s3d;
}
private class Animation extends AnimationTimer {
// アニメーション間隔の設定
long kankaku = 50 * 1000000L; //50ミリ秒
long stime = 0;
long foreno = -1;
@Override
public void handle(long now) {
if( stime == 0 ){ stime = now; }
//所定時間経過の確認
Long no = (Long)(( now - stime ) / kankaku );
if( foreno != no ){ foreno = no; } else { return; }
System.out.println(no);
//更新作業
boxrotateX.setAngle( no );
boxrotateY.setAngle( no );
}
}
}
最終更新日: 2017-03-13 19:01:50