Eclipse Android〜Gluonでアプリを作る10:アニメーションの基本(パラレル遷移)〜

イントロダクション

前回はこちらのサイトを参考にして「パス遷移」をやりました。(参考サイトの呼び方)そして今回はその続き「パラレル遷移」をやります。

パラレル遷移は単純に複数のアニメーションを組み合わせてアニメーションするというものでした。

とりあえずは実行結果から

実装内容

public void start(Stage primaryStage) throws Exception {

    Group gp = new Group();

    // チュートリアルにあるコード

    final Rectangle rect = new Rectangle(60, 60);

   rect.setArcHeight(15);
 rect.setArcWidth(15);

    rect.setFill(Color.DARKBLUE);

    rect.setTranslateX(50);
    rect.setTranslateY(75);


    FadeTransition fadeTransition = 
 new FadeTransition(Duration.millis(3000), rect);
 fadeTransition.setFromValue(1.0f);

    fadeTransition.setToValue(0.3f);

    fadeTransition.setCycleCount(2);

    fadeTransition.setAutoReverse(true);

    TranslateTransition translateTransition =
   new TranslateTransition(Duration.millis(2000), rect);

    translateTransition.setFromX(50);

    translateTransition.setToX(350);

    translateTransition.setCycleCount(2);

    translateTransition.setAutoReverse(true);

    RotateTransition rotateTransition = 
    new RotateTransition(Duration.millis(3000), rect);
    rotateTransition.setByAngle(180f);

    rotateTransition.setCycleCount(4);

    rotateTransition.setAutoReverse(true);

    ScaleTransition scaleTransition = 
  new ScaleTransition(Duration.millis(2000), rect);
 scaleTransition.setToX(2f);
    scaleTransition.setToY(2f);
    scaleTransition.setCycleCount(2);
    scaleTransition.setAutoReverse(true);
    ParallelTransition parallelTransition = new ParallelTransition();   parallelTransition.getChildren().addAll(fadeTransition,  translateTransition,     rotateTransition,   scaleTransition   );
    parallelTransition.setCycleCount(Timeline.INDEFINITE);  parallelTransition.play();
    // シーンをステージに登録
    gp.getChildren().addAll(rect);
    Scene scene = new Scene(gp, 450, 450);
    primaryStage.setScene(scene);
    primaryStage.setTitle("Animation Basic3");
    primaryStage.show();
    }

今回はチュートリアルをコピペで変数名を多少修正してお終いだったので、まぁ楽でした。今までの実装を行なっていれば「こんな感じ」というのが掴めると思います。

<ソースの内容>

final Rectangle rect = new Rectangle(60, 60);
rect.setArcHeight(15);
rect.setArcWidth(15);
rect.setFill(Color.DARKBLUE);
rect.setTranslateX(50);
rect.setTranslateY(75);

毎度おなじみ、四角形クラス(Rectangle)です。これを縦横60の大きさで作成します。そしてArcHeight, ArcWidthを設定します。(リンクはJavaDocです)

JavaDocの説明は「矩形の4隅にある弧の水平方向の直径を定義します。円弧の幅と円弧の高さの両方のプロパティが0.0より大きい場合にのみ、矩形の角が丸くなります。」とありました。四角形の先っちょが丸くなるんですね(笑)

そしてFill()は色を指定します。setTranslateは位置を指定します。

FadeTransition fadeTransition = 
  new FadeTransition(Duration.millis(3000), rect);

fadeTransition.setFromValue(1.0f);
fadeTransition.setToValue(0.3f);
fadeTransition.setCycleCount(2);
fadeTransition.setAutoReverse(true);

これは初めの方に出てきたアニメーションです。色をフェードアウト・インするアニメーションです。

TranslateTransition translateTransition =
 new TranslateTransition(Duration.millis(2000), rect);
translateTransition.setFromX(50);
translateTransition.setToX(350);
translateTransition.setCycleCount(2);
translateTransition.setAutoReverse(true);

TranslateTransitionクラスを使用した、四角形の移動アニメーションです。

X座標が「50」〜「350」の間を移動します。JavaDocの説明は「このアニメーションのサイクル数を定義します。アニメーションを無限に繰り返す場合はcycleCountをINDEFINITEに設定できます、それ以外の場合は0より大きくする必要があります。」です。

そして最後のsetAutoReverseは名前から想像できますね。※動きからも見て取れると思います。

ちょっと余談ですが、「想像できますね」という記載をしましたが、コーディングをするときのメソッド名をつけるとき、変数名をつけるとき、処理の内容が「簡単に想像できる」というのはとても大切なことです。これがわかりづらいと結局ソースの中身を追いかけることになります。

そして、「RotateTransition」「ScaleTransition」は説明を割愛します。

最後のクラスです。

ParallelTransition parallelTransition = new ParallelTransition();

parallelTransition.getChildren().addAll(
fadeTransition,
translateTransition,
rotateTransition,
scaleTransition
);

本題の「パラレル遷移」クラスです。今まで作成したアニメーションクラスを登録しています。これでアニメーションを複合して実行しています。

最後に。。。

ここまでで、とりあえずはチュートリアルを止めようと思っております。

なぜかというと「じゃんけんゲーム」で必要なアニメーションの作成ができるようになったからです。つまり今回の「パラレル遷移」をじゃんけんゲームで使用します。ちょいとした戦いになりそうですが。。。

追加でやって見た

四角をコインのように回転してみる。

追加で修正した部分は以下の「RotateTransition」の部分です。

RotateTransition rotateTransition = 
 new RotateTransition(Duration.millis(800), rect);
rotateTransition.setAxis(new Point3D(0, 10, 0));

rotateTransition.setByAngle(360f);
rotateTransition.setInterpolator(Interpolator.TANGENT(Duration.millis(100), 10000.0));

rotateTransition.setCycleCount(RotateTransition.INDEFINITE);

コンストラクタに渡している「Duration」が回転のスピードになります。値が少ないほど回転が早い。

そしてPoint3Dで回転する方向を指定します。今回は横軸(Y軸)方向に回転するのでYの値のみを設定しています。

そして参考サイトはこちら(Java Code Examples)

でわでわ。。。


関連ページ一覧

  1. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫:Label〜
  2. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫2:Label〜
  3. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫3:Button〜
  4. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫4:RadioButton〜
  5. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫5:ToggleButton〜
  6. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫6:CheckBox〜
  7. Eclipse Android〜Gluonでアプリを作る6: アニメーションを作る準備〜
  8. Eclipse Android〜Gluonでアプリを作る7: 木琴アプリの解析〜
  9. Eclipse Android〜Gluonでアプリを作る8:アニメーションの基本(遷移)〜
  10. Eclipse Android〜Gluonでアプリを作る9:アニメーションの基本(パス遷移)〜
  11. Eclipse Android〜Gluonでアプリを作る10:アニメーションの基本(パラレル遷移)〜


Eclipse Android〜Gluonでアプリを作る9:アニメーションの基本(パス遷移)〜

イントロダクション

前回はこちらのサイトを参考にして「フェード遷移」をやりました。(参考サイトの呼び方)そして今回はその続き「パス遷移」をやります。

「パス遷移」とはPath(線)を引いて、そのパスの端から端まで移動するというものです。参考サイトより画像を引用します。

ちなみにこのPath(クラス)を利用すると文字列をオシャレにデコレーションできます。

こちらのサイトから失敬しました。

そんなわけで、今日は「パス遷移」をやります。

<ソースコード>

@Override
public void start(Stage primaryStage) throws Exception {
    Group gp = new Group();
    // チュートリアルにあるコード
    final Rectangle rect = new Rectangle(60, 60);
    rect.setArcHeight(50);
    rect.setArcWidth(50);
    rect.setFill(Color.ORANGE);
    Path path = new Path();
    path.getElements().add(new MoveTo(30,30));
    path.getElements().add(new CubicCurveTo(380, 0, 380, 120, 200, 120));
    path.getElements().add(new CubicCurveTo(0, 120, 0, 240, 380, 240));
    PathTransition pathTransition = new PathTransition();
    pathTransition.setDuration(Duration.millis(10000));
    pathTransition.setPath(path);
    pathTransition.setNode(rect);
    pathTransition.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
    pathTransition.setCycleCount(Timeline.INDEFINITE);
    pathTransition.setAutoReverse(true);
    pathTransition.play();
    // シーンをステージに登録
    gp.getChildren().addAll(rect, path);
    Scene scene = new Scene(gp, 450, 450);
    primaryStage.setScene(scene);
    primaryStage.setTitle("Animation Basic2");
    primaryStage.show();
}
  1. 四角形を描き(60 x 60のオレンジ色でちょいと角を丸くする)
  2. アニメーションするための線(Path)を描き
  3. アニメーションする時間を設定(setDuration())
  4. PathTransitionに線(Path)と四角形を登録する※「ORTHOGONAL_TO_TANGENT」の意味はよくわかりませんでした。

  5. そしてINDEFINITE「stop()メソッドを呼び出すまで無限に繰り返すアニメーションを指定」
  6. オートリバース(自動繰り返し)をTrueで設定(自動で繰り返し動く)

とこんな感じで実装してありました。

でわでわ。。。

[rakuten ids="book:17135078"]



Eclipse Android〜Gluonでアプリを作る8:アニメーションの基本(遷移)〜

イントロダクション

今回からアニメーションの学習に入ります。参考にするサイトはこちらです。

https://docs.oracle.com/javase/jp/8/javafx/visual-effects-tutorial/basics.htm

今までのJavaFXをやってきたなら、楽勝だと思います。ちょっとわかりづらいのが、Durationクラスと、FadeTransitionクラスだと思います。リンク先のJavaDocにもあるように、Durationで時間(間隔)を指定してFadeTransitionでフェードさせています。「百聞は一見に〜」ということで。。。こんな感じです。

<ソース>

@Override
public void start(Stage primaryStage) throws Exception {
    Group gp = new Group();
    // チュートリアルにあるコード
    final Rectangle rect1 = new Rectangle(10, 10, 100, 100);
    rect1.setArcHeight(20);
    rect1.setArcWidth(20);
    rect1.setFill(Color.RED);
    FadeTransition ft = new FadeTransition(Duration.millis(3000), rect1);
    ft.setFromValue(1.0);
    ft.setToValue(0.1);
    ft.setCycleCount(Timeline.INDEFINITE);
    ft.setAutoReverse(true);
    ft.play();

    // シーンをステージに登録
    gp.getChildren().addAll(rect1);
    Scene scene = new Scene(gp, 450, 450);
    primaryStage.setScene(scene);
    primaryStage.setTitle("Animation Basic1");
    primaryStage.show();
}

特に調べる必要はないと思ったので今回はここまでにします。

でわでわ。。。

[rakuten ids="excellentimports:13167241"]

関連ページ

  1. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫:Label〜
  2. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫2:Label〜
  3. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫3:Button〜
  4. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫4:RadioButton〜
  5. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫5:ToggleButton〜
  6. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫6:CheckBox〜
  7. Eclipse Android〜Gluonでアプリを作る6: アニメーションを作る準備〜
  8. Eclipse Android〜Gluonでアプリを作る7: 木琴アプリの解析〜



Eclipse Android〜Gluonでアプリを作る7: 木琴アプリの解析〜

イントロダクション

前回は、チュートリアルの入り口、概要について記載しいました。アニメーションなのに3D描画から始めているのでちょっとずれている感じがします。

なのでタイトルを変更しました、木琴アプリの解析をやります。元のソース、音データはこちらからダウンロードできます。

そして、ソースを読んで見た内容にコメントをつけました。※Gitにアップしたソースです。

そして、ソースを読んでいてわからない部分もありました。その部分のコードを一度コメントアウトして実行して見ます。ちなみに参考サイトはこちらです。

https://docs.oracle.com/javase/jp/8/javafx/visual-effects-tutorial/transformation-types.htm

rectangleGroup(Group)を追加しないパターン

251行目、

setCamOffsetを設定しない(シーンサイズ半分、分の位置をずらさない)

338行目をコメントアウト:

340行目をコメントアウト:

341行目をコメントアウト:

342行目をコメントアウト:

そして255行目以降の「scene.setOn〜」はボタン押下などのアクション処理の実装になります。なので今は置いておきます。

とりあえずは、理解の整理

  1. Groupクラスを継承した「Cam」クラスをフィールド変数の「camOffset」「cam」で使用している。
  2. ステージ(Stageクラス)にカメラ(PerspectiveCameraクラス)を設定
  3. Groupクラスを継承した「Cube」クラスを木琴のバー、土台として使用(内訳としてはRectangleクラスを「面」として使用)
  4. 木琴は「cam(Group)」に追加
  5. 「cam」は「camOffset」に追加、「camOffset」をステージに追加

そして、「A」「F」のボタンを押下すると木琴の位置が変わります。そして「スペース」で全画面表示になります。注目ポイントは305行目〜328行目。

アニメーションに関連深そうなのはボタン押下時に木琴を移動する部分が怪しいです。

インナークラスのコードを記載します。

<Camクラス>

class Cam extends Group {
    Translate t  = new Translate();
    Translate p  = new Translate();
    Translate ip = new Translate();
    Rotate rx = new Rotate();
    { rx.setAxis(Rotate.X_AXIS); }
    Rotate ry = new Rotate();
    { ry.setAxis(Rotate.Y_AXIS); }
    Rotate rz = new Rotate();
    { rz.setAxis(Rotate.Z_AXIS); }
    Scale s = new Scale();
    public Cam() { super(); getTransforms().addAll(t, p, rx, rz, ry, s, ip); }
}

<Cubeクラス>

public class Cube extends Group {
    final Rotate rx = new Rotate(0, Rotate.X_AXIS);
    final Rotate ry = new Rotate(0, Rotate.Y_AXIS);
    final Rotate rz = new Rotate(0, Rotate.Z_AXIS);
    public Cube(double size, Color color, double shade) {
        getTransforms().addAll(rz, ry, rx);

//          back face
        Rectangle backFace = new Rectangle(size,size);
        backFace.setFill(color.deriveColor(0.0, 1.0, (1 - 0.5*shade), 1.0));
        backFace.setTranslateX(-0.5*size);
        backFace.setTranslateY(-0.5*size);
        backFace.setTranslateZ(-0.5*size);

        // bottom face
        Rectangle bottomFace = new Rectangle(size,size);
        bottomFace.setFill(color.deriveColor(0.0, 1.0, (1 - 0.4*shade), 1.0));
        bottomFace.setTranslateX(-0.5*size);
        bottomFace.setTranslateY(0);
        bottomFace.setRotationAxis(Rotate.X_AXIS);
        bottomFace.setRotate(90);

//          right face
        Rectangle rightFace = new Rectangle(size,size);
        rightFace.setFill(color.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0));
        rightFace.setTranslateX(-1*size);
        rightFace.setTranslateY(-0.5*size);
        rightFace.setRotationAxis(Rotate.Y_AXIS);
        rightFace.setRotate(90);

//            leftFace
        Rectangle leftFace = new Rectangle(size,size);
        leftFace.setFill(color.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0));
        leftFace.setTranslateX(0);
        leftFace.setTranslateY(-0.5*size);
        leftFace.setRotationAxis(Rotate.Y_AXIS);
        leftFace.setRotate(90);

//            topFace
        Rectangle topFace = new Rectangle(size,size);
        topFace.setFill(color.deriveColor(0.0, 1.0, (1 - 0.1*shade), 1.0));
        topFace.setTranslateX(-0.5*size);
        topFace.setTranslateY(-1*size);
        topFace.setRotationAxis(Rotate.X_AXIS);
        topFace.setRotate(90);

//          frontFace
        Rectangle frontFace = new Rectangle(size,size);
        frontFace.setFill(color);
        frontFace.setTranslateX(-0.5*size);
        frontFace.setTranslateY(-0.5*size);
        frontFace.setTranslateZ(-0.5*size);

        getChildren().addAll(backFace, bottomFace, rightFace, leftFace, topFace,frontFace);

    }
}

これで大分処理の概要が見えてきたと思います。(自分は見えてきました。)

【補足】

  1. Rectangleは四角を表現するクラスです。
  2. Rotateは回転を表現するクラスです。
  3. Boundsは境界を示すために使用されるクラスです。
  4. AudioClipは音データを扱うためのクラスです。

[rakuten ids="neowing-r:10866284"]

そして、最後にチュートリアルにある「スケーリングの処理」を302行目に追加します。チュートリアルの「例2-3 スケーリング」にあるコードを追加します。

最終的なコードはこちらです。

次回はついにアニメーションにてが届く



Eclipse Android〜Gluonでアプリを作る6: アニメーションを作る準備〜

イントロダクション

前回までは、とりあえず動くところまで作りました。概要は以下の通りです。

  1. ゲームのタイトル表示
  2. ゲームの開始画面表示
  3. 「じゃんけん」の開始ボタン押下後の処理

「3」の部分で開始ボタンを押下後にイメージを表示して終了している状態で前回の作業を終わりました。

ここからは、プログラムでのアニメーション作成方法に注目します。

アニメーション作成の前に

参考にするサイトはこちらです。Oracleのチュートリアルになります。

  1. 変換の概要:transformations.zipリンクよりサンプルコードをダウンロードできます。
  2. このzipファイルをダウンロード、展開して(Eclipse上では)下のようにファイルを配置します。
    展開後のファイル →
    Eclipseに配置 → 
  3. とりあえず、プログラムを実行してみます。

おー素晴らしい!やはり操作して音が出ると違います。

本題

このコードを解析して中身を理解します。以前3次元表現(描画)に挑戦したけどうまくいかなかったので、自分自身ここで問題を解決したいと思っています。

1 変換の概要

サンプル・ソースコード(Gitにアップロードしています)をダウンロードできます。そして「以下の変換について記載してますよ」ということが書いてありました。

  1. 平行移動
  2. 回転
  3. スケーリング
  4. 変形

そして、次のトピックへ進む前にサンプルコードの内容を(大雑把に)理解します。

【前提】

  1. JavaFXを起動する部分(Applicationクラスの継承とMainメソッドの実装)は割愛します。よくわからない場合はここのページを読み返してみてください(それでもわからない場合は実行してみてください)
  2. サンプルソースは、ダウンンロードするソースが1ファイルで良いようにまとめてあります。1クラス1ファイルになっていないので注意が必要です。
    (注)クラスの中に作成するクラス(インナークラス)に「Camクラス」「Cubeクラス」を実装しています。

ソース解析

実際のソースは、結構長いのでこちらを参照してください。(サンプルソースのリンクも同じ場所を参照しています)

まずはクラス構成から見ていきます。

1. インナークラス

大元のクラスは「Xylophone」クラスです、そしてこのクラスにインナークラスが下のようなクラスが2つあります。

  1. Camクラス 
  2. Cubeクラス 

「class」の左側に「public」がついているものと、ついていないものがありますが、これはフィールド変数と同様に

「class Cam」はパッケージ内でのみ使用、参照が可能なアクセス修飾子(何もない)状態を示します。

「public class Cube」はクラスの外部からも、全ての場所から参照することができます。(Xylophone.Cubeのような形で参照する)

しかし、インナークラスは「1クラス1ファイル」の作り方からは逸脱するのであまり使用しません。使用するのは以下のような場合のみです。

対象のクラスからのみ使用される(CubeがXylophneクラスからのみ使用される)

  1. start()メソッドを見る

JavaFXアプリケーションの場合は必ず「Application」クラスを継承したクラスを実装します。そしてこのクラスには「start()」メソッドを実装する(実装することを強制している)ので必ず実装します。

つまり、必ず動くメソッドということです。見ていきます。

フィールド変数に「Cam」クラスが2つあります。

このクラスは、位置と回転を制御するための仕組みがついています。

class Cam extends Group {
    Translate t  = new Translate();
    Translate p  = new Translate();
    Translate ip = new Translate();
    Rotate rx = new Rotate();
    { rx.setAxis(Rotate.X_AXIS); }
    Rotate ry = new Rotate();
    { ry.setAxis(Rotate.Y_AXIS); }
    Rotate rz = new Rotate();
    { rz.setAxis(Rotate.Z_AXIS); }
    Scale s = new Scale();
    public Cam() { super(); getTransforms().addAll(t, p, rx, rz, ry, s, ip); }
}

「Transrate」クラスは位置を管理するため、「Rotate」クラスは回転を管理するためのクラスです。

そして、赤い字で記載した部分に関してフィールド変数と同様に処理を実装するためのスコープ("{", "}")です。これを外すとエラーになります。

本来はメソッドを作成する方が良いのでしょうが、これ以外に処理がないのでここに作成したようです。

そして、ポイントは「Group」クラスを継承しているというところです。

つまり「Group」クラスを拡張しているので細かい処理は全て親クラス(Group)に実装してあるものを使用します。必要に応じてメソッドをオーバーライド、追加の実装を行います。

とりあえずは、キリが良いので今回はここまでにします。

でわでわ。。。

[rakuten ids="book:17734116"]