Вот и настало время следующего рассказа о возможностях платформы 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 } }
Удачи и новых открытий!!!
Комментариев нет:
Отправить комментарий