Как стать автором
Обновить

Спрайтовая анимация с помощью 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. Но об этом в следующих сериях.

Спасибо за внимание. :)
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.