Анимации спрайтов
Движок спрайтов
Движок спрайтов Qt Quick представляет собой стохастическую конечный автомат, дополненный возможностью разбиения изображений на несколько кадров анимации.
Конечный автомат
Основной функцией движка спрайтов является его внутренний конечный автомат. Он отличается от состояний и переходов в Qt Quick и больше похож на обычный конечный автомат. Спрайты могут иметь взвешенные переходы к другим спрайтам или обратно к себе. Когда анимация спрайта завершается, движок спрайтов случайным образом выбирает следующий спрайт на основе взвешенных переходов доступных для завершенного спрайта.
Вы можете повлиять на текущий воспроизводимый спрайт двумя способами. Вы можете произвольно заставить его немедленно начать воспроизведение любого спрайта или указать ему постепенно перейти к заданному спрайту. Если вы укажете ему постепенно перейти, он достигнет целевого спрайта, пройдя через допустимые переходы состояний, используя наименьшее количество промежуточных спрайтов (но игнорируя относительные веса). Это позволяет легко вставить анимацию перехода между двумя различными спрайтами.
В качестве примера рассмотрим приведенную выше диаграмму, которая иллюстрирует спрайты для вымышленного 2D-персонажа платформенной игры. Персонаж начинает с отображения состояния стоя. Из этого состояния, за исключением внешних данных, он перейдет к анимации ожидания, анимации ходьбы или снова воспроизведет анимацию стоя. Поскольку веса этих переходов составляют соответственно один, ноль и три, у него есть один шанс из четырех воспроизвести анимацию ожидания при завершении анимации стоя и три шанса из четырех воспроизвести анимацию стоя еще раз. Это позволяет создать персонажа, который ведет себя немного оживленно и варьируется во время ожидания.
Поскольку существует переход с весом ноль в анимацию ходьбы, анимация стоя обычно не будет переходить туда. Но если вы зададите целевую анимацию как анимацию ходьбы, она воспроизведёт анимацию ходьбы после завершения анимации стоя. Если ранее она находилась в анимации ожидания, она закончит её, затем воспроизведёт анимацию стоя, а затем анимацию ходьбы. Она будет продолжать воспроизводить анимацию ходьбы до тех пор, пока целевая анимация не будет снята, в этот момент она переключится на анимацию стоя после завершения анимации ходьбы.
Если затем вы установите целевое состояние в анимацию прыжка, она завершит анимацию ходьбы перед воспроизведением анимации прыжка. Поскольку анимация прыжка не переходит в другие состояния, она будет продолжать воспроизводить анимацию прыжка до тех пор, пока состояние не будет изменено. В этом примере вы можете установить её обратно в ходьбу и изменить целевую анимацию на ходьбу или на ничего (что приведет к воспроизведению анимации стоя после анимации ходьбы). Обратите внимание, что при принудительном установлении анимации вы можете начать её воспроизведение немедленно.
Формат ввода
Форматы файлов, поддерживаемые движком спрайтов, такие же, как и форматы файлов, поддерживаемые другими типами QML, такими как Image. Однако для анимации изображения движку спрайтов требуется, чтобы файл изображения содержал все кадры анимации. Они должны быть расположены в одной непрерывной строке, которая может переходить с правого края файла на нижнюю строку, начиная с левого края файла (и которая размещается непосредственно под предыдущей строкой).
В качестве примера возьмем приведенное выше изображение. Пока рассмотрим только черные числа и предположим, что квадраты имеют размер 40x40 пикселей. Обычно изображение считывается с верхнего левого угла. Если вы указали размер кадра как 40x40 пикселей и количество кадров как 8, то он будет считывать кадры в порядке их нумерации. Кадр в верхнем левом углу будет первым кадром, кадр в верхнем правом углу будет пятым кадром, а затем он перейдет к следующей строке (в точке пикселей 0,40 в файле), чтобы прочитать шестой кадр. Он прекратит чтение после кадра, помеченного как 8, и если в квадрате под кадром четыре были какие-либо данные изображения, то они не будут включены в анимацию.
Возможно загружать анимации с произвольного смещения, но они все равно будут следовать той же схеме. Теперь рассмотрим красные числа. Если мы укажем, что анимация начинается с точки пикселей 120,0, с количеством кадров 5 и тем же размером кадра, что и раньше, то она будет загружать кадры в порядке их нумерации в красном цвете. Первые 120x40 изображения не будут использованы, так как чтение начнётся с блоков 40x40 из позиции 120,0. Когда он достигнет конца файла в 160,0, он начнёт чтение следующей строки с позиции 0,40.
Синие числа показывают номера кадров, если вы попытаетесь загрузить два кадра такого размера, начиная с 40,40. Обратите внимание, что возможно загружать несколько спрайтов из одного файла изображения. Красные, синие и черные числа могут быть загружены как отдельные анимации в один и тот же движок спрайтов. Следующий код загружает анимации в соответствии с изображением. Также в нём указано, что анимации должны воспроизводиться со скоростью 20 кадров в секунду.
Sprite {
name: "black"
source: "image.png"
frameCount: 8
frameWidth: 40
frameHeight: 40
frameRate: 20
}
Sprite {
name: "red"
source: "image.png"
frameX: 120
frameCount: 5
frameWidth: 40
frameHeight: 40
frameRate: 20
}
Sprite {
name: "blue"
source: "image.png"
frameX: 40
frameX: 40
frameCount: 2
frameWidth: 40
frameHeight: 40
frameRate: 20
} Кадры одной анимации должны иметь одинаковый размер. Однако для нескольких анимаций в одном файле это не обязательно. Спрайты без указанного frameCount предполагают, что они занимают весь файл, и вы должны указать размер кадра. Спрайты без размера кадра предполагают, что они квадратные и занимают весь файл без перехода, и вы должны указать количество кадров.
Движок спрайтов внутренне копирует и разрезает изображения, чтобы привести их к более легко читаемому внутреннему формату, что приводит к некоторым ограничениям графической памяти. Поскольку для всех спрайтов одного движка требуется одна текстура, попытка загрузить много разных анимаций может столкнуться с ограничениями памяти текстуры на устройствах с ограниченными ресурсами. В этих ситуациях в консоль будет выведено предупреждение с максимальным размером текстуры.
Существуют различные инструменты, которые могут помочь преобразовать набор изображений в спрайт-листы. Вот некоторые примеры:
- Плагин Photoshop: http://www.johnwordsworth.com/projects/photoshop-sprite-sheet-generator-script
- Плагин SpriteSheet для Gimp
- Инструмент командной строки: http://www.imagemagick.org/script/montage.php
Типы QML, использующие движок спрайтов
Спрайты для движка спрайтов могут быть определены с помощью типа Sprite. Этот тип включает в себя входные параметры, а также длительность анимации и взвешенные переходы к другим анимациям. Это чисто класс данных и не отображает ничего.
SpriteSequence — это тип, который использует движок спрайтов для отрисовки спрайтов, определенных в нём. Это отдельный и автономный движок спрайтов, который не взаимодействует с другими движками спрайтов. Типы Sprite могут быть объединены между типами, использующими движок спрайтов, но это не делается автоматически. Таким образом, если вы определили спрайт в одном SpriteSequence, вам нужно будет переопределить его (или сослаться на тот же тип Sprite) в свойстве sprites другого SpriteSequence, чтобы перейти к этой анимации.
Кроме того, ImageParticle может использовать типы Sprite для определения спрайтов для каждой частицы. Опять же, на каждый тип приходится по одному движку спрайтов. Это работает аналогично SpriteSequence, но также обладает параметрической вариативностью, предоставляемой типом ImageParticle.
Тип AnimatedSprite
Для случаев использования, которым не требуется переход между анимациями, рассмотрите тип AnimatedSprite. Этот тип отображает анимации спрайтов с тем же форматом ввода, но только по одному за раз. Он также предоставляет более тонкий ручное управление, так как движок спрайтов не управляет таймингом и переходами за кулисами.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.13/qtquick-effects-sprites.html