Анимации спрайтов
Движок спрайтов
Движок спрайтов 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-6.0/qtquick-effects-sprites.html