Sur cette page

Animations de sprites

Moteur de sprites

Le Qt Quick moteur de sprites est une machine à états stochastique combinée à la capacité de découper des images contenant plusieurs images d’une animation.

Machine à états

L'une des principales fonctions du moteur de sprites est sa machine à états interne. Celle-ci ne correspond pas aux états et transitions de Qt Quick, mais s'apparente davantage à une machine à états classique. Les sprites peuvent avoir des transitions pondérées vers d'autres sprites, ou revenir à eux-mêmes. Lorsqu’une animation de sprite se termine, le moteur de sprites choisit le sprite suivant de manière aléatoire, en fonction des transitions pondérées disponibles pour le sprite qui vient de s’achever.

Vous pouvez influencer le sprite en cours de lecture de deux manières. Vous pouvez le forcer arbitrairement à lancer immédiatement la lecture d’un sprite quelconque, ou vous pouvez lui demander d’effectuer une transition progressive vers un sprite donné. Si vous lui demandez d’effectuer une transition progressive, il atteindra le sprite cible en passant par des transitions d’états valides en utilisant le moins de sprites intermédiaires possible (mais en ignorant les pondérations relatives). Cela vous permet d’insérer facilement une animation de transition entre deux sprites différents.

Diagramme d'états illustrant les transitions d'un sprite entre les états « debout », « en attente », « en marche » et « en saut »

À titre d’exemple, considérez le schéma ci-dessus qui illustre les sprites d’un personnage hypothétique de jeu de plateforme en 2D. Le personnage commence par afficher l’état « debout ». À partir de cet état, sauf intervention externe, il passera soit à l’animation « en attente », soit à l’animation « en marche », soit il rejouera l’animation « debout ». Comme les pondérations de ces transitions sont respectivement de un, zéro et trois, il a une chance sur quatre de passer à l’animation « en attente » à la fin de l’animation « debout », et trois chances sur quatre de rejouer l’animation « debout ». Cela permet au personnage d’adopter un comportement légèrement animé et variable pendant qu’il attend.

Comme la transition vers l'animation de marche a un poids nul, l'animation debout ne mènera normalement pas à celle-ci. Mais si vous définissez l'animation cible comme étant l'animation de marche, celle-ci sera lue à la fin de l'animation debout. S'il se trouvait auparavant dans l'animation d'attente, il terminerait celle-ci, puis passerait à l'animation debout, avant de lancer l'animation de marche. Il continuerait alors à lire l’animation de marche jusqu’à ce que l’animation cible soit désactivée, auquel cas il passerait à l’animation debout après avoir terminé l’animation de marche.

Si vous définissez ensuite l’état cible sur l’animation de saut, le personnage terminera l’animation de marche avant de lancer l’animation de saut. Comme l’animation de saut ne permet pas de transition vers d’autres états, elle continuera à être lue jusqu’à ce que le changement d’état soit forcé. Dans cet exemple, vous pourriez le ramener à l’état « marche » et modifier l’animation cible pour la définir sur « marche » ou sur « rien » (ce qui entraînerait la lecture de l’animation « debout » après l’animation « marche » ). Notez qu’en définissant l’animation de manière forcée, vous pouvez lancer la lecture immédiatement.

Format d’entrée

Les formats de fichiers acceptés par le moteur de sprites sont les mêmes que ceux acceptés par d’autres types QML, tels que Image. Toutefois, pour animer l’image, le moteur de sprites exige que le fichier image contienne toutes les images de l’animation. Celles-ci doivent être disposées en une ligne contiguë, qui peut s’enrouler depuis le bord droit du fichier vers une ligne inférieure commençant au bord gauche du fichier (et qui est placée directement sous la ligne précédente).

Grille indiquant l'ordre de numérotation des images dans une feuille de sprites

Prenons l’image ci-dessus à titre d’exemple. Pour l’instant, ne tenez compte que des chiffres noirs et supposez que les carrés mesurent 40 × 40 pixels. Normalement, l’image est lue à partir du coin supérieur gauche. Si vous avez défini la taille d’une image à 40 × 40 pixels et le nombre d’images à 8, le moteur lira les images dans l’ordre de leur numérotation. L'image en haut à gauche serait la première, celle en haut à droite la cinquième, puis la lecture passerait à la ligne suivante (à la position 0,40 dans le fichier) pour lire la sixième image. La lecture s'arrêterait après l'image marquée du numéro 8, et s'il y avait des données d'image dans le carré situé sous l'image numéro quatre, celles-ci ne seraient pas incluses dans l'animation.

Il est possible de charger des animations à partir d’un décalage arbitraire, mais elles suivront toujours le même schéma. Considérons maintenant les chiffres rouges. Si nous spécifions que l’animation commence à la position de pixel 120,0, avec un nombre de trames égal à 5 et la même taille de trame que précédemment, alors les trames seront chargées selon leur numérotation en rouge. Les 120 × 40 premiers pixels de l’image ne seront pas utilisés, car la lecture commence par des blocs de 40 × 40 à partir de la position 120,0. Lorsqu’elle atteint la fin du fichier à 160,0, elle commence alors à lire la ligne suivante à partir de 0,40.

Les chiffres bleus indiquent les numéros d’images si vous essayez de charger deux images de cette taille, en commençant à partir de 40,40. Notez qu’il est possible de charger plusieurs sprites à partir d’un seul fichier image. Les chiffres rouges, bleus et noirs peuvent tous être chargés en tant qu’animations distinctes dans le même moteur de sprites. Le code suivant charge les animations conformément à l’image. Il précise également que les animations doivent être lues à une cadence de 20 images par seconde.

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
}

Les images d’une même animation doivent être de la même taille. Ce n’est toutefois pas le cas pour plusieurs animations contenues dans le même fichier. Les sprites pour lesquels aucune taille d’ frameCount n’est spécifiée sont considérés comme occupant l’intégralité du fichier, et vous devez donc spécifier la taille de l’image. Les sprites pour lesquels aucune taille d’image n’est spécifiée sont considérés comme carrés et occupent l’intégralité du fichier sans retour à la ligne ; vous devez donc spécifier un nombre d’images.

Le moteur de sprites copie et découpe en interne les images pour les adapter à un format interne plus facile à lire, ce qui entraîne certaines limitations en matière de mémoire graphique. Étant donné que tous les sprites d’un même moteur doivent figurer dans la même texture, tenter de charger de nombreuses animations différentes peut se heurter aux limites de mémoire de texture sur les appareils embarqués. Dans ces situations, un message d’avertissement indiquant la taille maximale de la texture s’affichera sur la console.

Il existe plusieurs outils permettant de transformer un ensemble d’images en feuilles de sprites. En voici quelques exemples :

Types QML utilisant le moteur de sprites

Les sprites destinés au moteur de sprites peuvent être définis à l’aide du type « Sprite ». Ce type inclut les paramètres d’entrée, ainsi que la durée de l’animation et les transitions pondérées vers d’autres animations. Il s’agit d’une classe de données pure, qui n’effectue aucun rendu.

SpriteSequence Il s’agit d’un type qui utilise un moteur de sprites pour dessiner les sprites qui y sont définis. Il s’agit d’un moteur de sprites unique et autonome, qui n’interagit pas avec d’autres moteurs de sprites. Les types ` Sprite ` peuvent être partagés entre les types utilisant le moteur de sprites, mais cela ne se fait pas automatiquement. Ainsi, si vous avez défini un sprite dans un « SpriteSequence », vous devrez le redéfinir (ou référencer le même type « Sprite ») dans la propriété « sprites » d’un autre « SpriteSequence » afin de passer à cette animation.

De plus, ImageParticle peut utiliser des types d’ Sprite s pour définir des sprites pour chaque particule. Il s’agit là encore d’un moteur de sprites unique par type. Cela fonctionne de manière similaire à SpriteSequence, mais bénéficie également de la variabilité paramétrée fournie par le type ImageParticle.

Type AnimatedSprite

Pour les cas d’utilisation ne nécessitant pas de transition entre les animations, envisagez le type AnimatedSprite. Ce type affiche des animations de sprites avec le même format d’entrée, mais une seule à la fois. Il offre également un contrôle manuel plus précis, car aucun moteur de sprites ne gère la synchronisation et les transitions en arrière-plan.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.