Вот и настало время следующего рассказа о возможностях платформы JavaFX. Я думал, о чем бы мне рассказать вам и решил, что попробую вкратце рассказать про спрайтовую анимацию. Так как я сам начал изучать JavaFX не так давно, будем изучать вместе :)
Итак, что такое спрайтовая анимация? Она представляет собой набор кадров, которые чередуются через определенный промежуток времени и создают иллюзию движения.
Описывать создание проекта, который будет отображать анимацию спрайтами буду на примере:
Вот такой вот бандит на верблюде, найденный на просторах интернета :)
Что мы имеем в арсенале JavaFX для работы с графическими изображениями? Сейчас мы это узнаем.
Начнем с вывода изображения на экран. Для работы с изображениями в JavaFX есть класс ImageView, который используется для отображения изображения, загруженного с помощью класса Image.
Пусть имя файла с нашим изображением будет bandit.png.
Чтобы загрузить его и подготовить к выводу на экран напишем следующий код:
Вот такой вот бандит на верблюде, найденный на просторах интернета :)
Что мы имеем в арсенале JavaFX для работы с графическими изображениями? Сейчас мы это узнаем.
Начнем с вывода изображения на экран. Для работы с изображениями в JavaFX есть класс ImageView, который используется для отображения изображения, загруженного с помощью класса Image.
Пусть имя файла с нашим изображением будет bandit.png.
Чтобы загрузить его и подготовить к выводу на экран напишем следующий код:
var img2: ImageView = ImageView {
image: Image {
url: "{__DIR__}res.png"
}
}
Рассмотрим подробнее этот код.
В строке 1 мы определяем переменную img2 типа ImageView и присваем ей экземпляр созданного объекта.
В строке 2 мы экземпляру переменной image класса ImageView присваиваем экземпляр объекта Image, который используется для загрузки изображения по указанному URL.
Если мы теперь добавим в сцену переменную img2, то это изображение отобразится в окне нашего приложения.
Код для создания сцены:
Stage {
title: "Application title"
scene: Scene {
width: 900
height: 150
content: img2
}
}
Результатом нашей работы мы должны увидеть вот таке окно:Но наша цель еще не достигнута. Мы хотим чтобы этот бандит стал анимированным, чтобы в разный промежуток времени отображался один из кадров всего изображения.
Что нам для этого нужно знать?
- размеры одного кадра (ширина и высота)
- количество кадров из которых состоит полное изображение
Продолжим дорабатывать наш код... Определим 3 переменные: ширину, высоту спрайта и количество спрайтов.
def w = 75; def h = 89; def n = 12;
У класса ImageView есть свойство viewport типа Rectangle2D. Оно задает область изображения, которая будет отображаться. Если это свойство не задано, то изображение будет отображено полностью. А ведь это именно то, чего мы хотим добиться :) Для решения нашей задачи я предлагаю создать массив значений типа Rectangle2D с разными значениями, которые будут ограничивать каждый кадр из исходного изображения и присвоить начальное значение для отображения нулевому элементу, созданного массива.
def viewports = for (i in [0..<n]) =
{Rectangle2D{minX:i*w,minY:0,height:h,width:w}}>
img2.viewport = viewports[0];
При запуске приложения на данном этапе мы увидим лишь первый кадр из нашего изображения.
Теперь нам необходимо организовать Timeline, в котором на каждом KeyFrame будет устанавливаться новое отображение из массива и запустить его:
var timeline: Timeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames: [
for (i in [0..<n]) {
KeyFrame {
time: i*0.1s
action: function() {
img2.viewport = viewports[i];
}
}
}
]
}
timeline.play();
Этот код в цикле создает 12 кей-фреймов, каждому из них задается конкретное время с шагом в 0.1 сек и устанавливается действие по окончанию времени, которе устанавливает для вывода на экран очередной спрайт.
Вот и все!!! Поздравляю всех с первой спрайтовой анимацией на JavaFX.
Ну и под конец статьи я думаю что стоит сделать что-то еще :) Например заставить двигаться этого бандита вдоль прямой с права налево. Для этого необходимо задать путь по которому будет двигаться изображение:
def path = Path {
elements: [
MoveTo {x:800 y:100}
LineTo {x:100 y:100}
]
}
В JavaFX есть мого разных встроенных преобразований в числе которых присутствует PathTransition. Именно его мы будем использовать для перемещения объекта вдоль пути. В нашем случае путь - это линия, поэтому перемещение можно было сделать и обычным изменением координаты X, однако в случае более сложных путей использование PathTransition значительно облегчает жизнь программисту.
var pathtr = PathTransition {
duration: 20s
node: img2
path: AnimationPath.createFromPath(path)
interpolator: Interpolator.LINEAR
}
pathtr.play();
Здесь мы создаем объект PathTransition с длительностью прохода по пути 20 сек, привязываем это преобразование в объекту img2, создаем аинмационный путь из нашего пути, устанавливаем линейную интерполяцию и в конце всего этого запускаем Transition и любуемся нашим результатом.
В конце приведу полный текст нашего эксперимента с анимацией:
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.geometry.Rectangle2D;
import javafx.scene.shape.Path;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.LineTo;
import javafx.animation.transition.PathTransition;
import javafx.animation.transition.AnimationPath;
import javafx.animation.Interpolator;
var img2: ImageView = ImageView {
x: 0
y: 0
image: Image {
url: "{__DIR__}res.png"
}
}
def w = 75;
def h = 89;
def n = 12;
def viewports = for (col in [0..<n]) {Rectangle2D{minX:col*w, minY:0, height: h, width: w}}
img2.viewport = viewports[0];
def path = Path {
elements: [
MoveTo {x:800 y:100}
LineTo {x:100 y:100}
]
}
var timeline: Timeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames: [
for (i in [0..<n]) {
KeyFrame {
time: i*0.1s
action: function() {
img2.viewport = viewports[i];
}
}
}
]
}
timeline.play();
var pathtr = PathTransition {
duration: 20s
node: img2
path: AnimationPath.createFromPath(path)
interpolator: Interpolator.LINEAR
}
pathtr.play();
Stage {
title: "Application title"
scene: Scene {
width: 900
height: 150
content: img2
}
}
Удачи и новых открытий!!!

Комментариев нет:
Отправить комментарий