Pull to refresh

Спрайтовая анимация с помощью JavaFX Timeline

Добрый день.

Если вы заходили на проходившие в этом году Sun Tech Days, то могли видеть меня на стенде JavaFX. За два дня оного эскпириенса мне пришлось ответить на некоторое количество похожих вопросов, что, в общем-то и сподвигло на написание этой небольшой статьи, чуть шире отвечающей на один из них. Надеюсь, не последней.

Раз вы читаете эти строки, то скорее всего, имеете какое-то представление о том, что такое JavaFX. Но для чистоты совести, оставлю ссылку на javafx.com, где всё подробно описано.

Timeline, одно из полезнейших средств JavaFX, в туториалах представляют исключительно как средство анимации движущихся объектов (например тут).

Но кроме этого timelines являются удобнейшим инструментом для контроля любых процессов, протекающих во время работы приложения. Об этом, собственно, и статья.


Рассмотрим простейшую задачку — спрайтовую анимацию.

Воспользуемся Timeline, чтобы задать изменение картинки в зависимости от времени:

import javafx.scene.Group;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.util.Math;

public class Sprite extends Group {
  public var imagePath : String[];

  var timeline = Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames: [
      KeyFrame {
        time: 0.5s
        canSkip: false
        action: function () {
          image = Image {
            url: imagePath[Math.abs(currentFrame)]
          };
          // небольшой трюк, чтобы перебирать картинки туда и обратно
          if (++currentFrame >= sizeof imagePath){
            currentFrame = 2 - sizeof imagePath;
          }
        }
      }
    ]
  };

  var image: Image;
  var currentFrame = 0;

  init {
    content = ImageView {
      image: bind image;
    }
    timeline.play();
  }

}

* This source code was highlighted with Source Code Highlighter.

Тут мы видим, что в Timeline присутствует всего 1 кадр, который случается каждые полсекунды и задаёт действие, которое меняет картинку на следующую из списка.

Далее во избежание авторских прав я собственноручно нарисовал в paint несколько страшненькую, но наглядную «анимацию» растущей стрелочки:
image

Для использования нашего спрайта достаточно задать ему список картинок:

import javafx.stage.Stage;
import javafx.scene.Scene;

Stage {
  title: "JavaFX Sprite Animation Sample"
  scene: Scene {
    width: 250
    height: 80
    content: [
      Sprite {
        translateX: 100;
        imagePath: for (i in [0..4]) {
          "{__DIR__}images/arrow{i}.png"
          }
      }
    ]
  }
}


* This source code was highlighted with Source Code Highlighter.

Посмотреть получившееся:
Java WebStart.

Далее с этим спрайтом можно безболезненно делать что угодно, например, применить Timeline классическим образом для вращения:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.animation.Timeline;
import javafx.animation.Interpolator;
import javafx.scene.transform.Rotate;

var angle = 100;

Timeline {
  repeatCount: Timeline.INDEFINITE
  keyFrames: [
    at (0s) {angle => 0},
    at (4s) {angle => 360 tween Interpolator.LINEAR}
  ]
}.play();

Stage {
  title: "JavaFX Sprite Animation Sample"
  scene: Scene {
    width: 250
    height: 250
    content: [
      Sprite {
        transforms: Rotate {
          pivotX: 0.0, pivotY: 0.0, angle: bind angle
        }
        translateY: 100;
        translateX: 100;
        imagePath: for (i in [0..4]) {
          "{__DIR__}images/arrow{i}.png"
          }
      }
    ]
  }
}


* This source code was highlighted with Source Code Highlighter.
Посмотреть получившееся:
Java WebStart.

Следующим шагом можно представить управление спрайтом с помощью клавиатуры или мыши, что, как это не удивительно, тоже легко делается с помощью Timeline. Но об этом в следующих сериях.

Спасибо за внимание. :)
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.