Qt Quick Particles Exemples - Affecteurs
Voici une série d'exemples d'utilisation des Affecteurs dans le système de particules QML.

Il s'agit d'une série de petits exemples QML relatifs à l'utilisation des affectateurs dans le système de particules. Chaque exemple est un petit fichier QML mettant en avant un type ou une fonctionnalité particulière.
L'exemple « Age » montre comment utiliser un affecteur « Age » pour mettre fin prématurément à la durée de vie des particules.
Age {
anchors.fill: parent
system: particles
once: true
lifeLeft: 1200
advancePosition: false
}Lorsque vous déplacez l’affecteur sur l’écran, les particules qu’il contient (et qui n’ont pas encore été affectées) passent à une durée proche de la fin de leur vie. Cela leur laisse un court laps de temps pour s’éteindre progressivement, mais en définissant `lifeLeft` sur 0 (valeur par défaut), elles atteindraient instantanément la fin de leur vie.
« Attractor » montre comment utiliser un affecteur « Attractor » pour simuler un trou noir
Attractor {
id: gs; pointX: root.width/2; pointY: root.height/2; strength: 4000000;
affectedParameter: Attractor.Acceleration
proportionalToDistance: Attractor.InverseQuadratic
}Toutes les particules de la scène, y compris les gaz d’échappement et les projectiles de la fusée, sont attirées vers le trou noir. Cet effet est d’autant plus fort qu’on se rapproche du trou noir : ainsi, les astéroïdes situés près du haut de l’écran ne sont pratiquement pas affectés, tandis que ceux situés vers le milieu décrivent parfois des trajectoires très courbes. Pour parachever l’effet, un affecteur « Age » recouvre le trou noir afin de détruire les particules qui entrent en contact avec lui.
L’affecteur « Custom » manipule directement les propriétés des particules en JavaScript. Un affecteur est utilisé pour faire osciller les feuilles d’avant en arrière pendant leur chute, ce qui leur donne un aspect plus réaliste que si elles tournaient simplement en rond :
Affector {
width: parent.width
height: parent.height - 100
onAffectParticles: (particles, dt) => {
//Wobbly movement
for (var i=0; i<particles.length; i++) {
var particle = particles[i];
particle.rotation += particle.vx * 0.15 * dt;
particle.update = true;
}
}
}Un autre est utilisé pour appliquer une friction légèrement variable aux feuilles lorsqu’elles « atterrissent », afin de leur donner un aspect plus naturel :
Affector {//Custom Friction, adds some 'randomness'
x: -60
width: parent.width + 120
height: 100
anchors.bottom: parent.bottom
onAffectParticles: (particles, dt) => {
for (var i=0; i<particles.length; i++) {
var particle = particles[i];
var pseudoRand = (Math.floor(particle.t*1327) % 10) + 1;
var yslow = dt * pseudoRand * 0.5 + 1;
var xslow = dt * pseudoRand * 0.05 + 1;
if (particle.vy < 1)
particle.vy = 0;
else
particle.vy = (particle.vy / yslow);
if (particle.vx < 1)
particle.vx = 0;
else
particle.vx = (particle.vx / xslow);
particle.update = true;
}
}
}L’affecteur « Friction » fonctionne de manière similaire à celui des feuilles qui tombent dans l’affecteur personnalisé, à la différence qu’il applique un frottement constant tout au long de la chute, contrairement aux affecteurs personnalisés.
Friction {
anchors.fill: parent
anchors.margins: -40
factor: 0.4
}L’affecteur « Gravité » est un affecteur pratique permettant d’appliquer une accélération constante aux particules qu’il contient
Gravity {
system: sys
magnitude: 32
angle: ground.rotation + 90
}GroupGoal crée deux groupes de particules pour les boules enflammées et non enflammées, et vous offre différentes façons d’effectuer la transition entre les deux.
ParticleGroup {
name: "unlit"
duration: 1000
to: {"lighting":1, "unlit":99}
ImageParticle {
source: "images/particleA.png"
colorVariation: 0.1
color: "#2060160f"
}
GroupGoal {
whenCollidingWith: ["lit"]
goalState: "lighting"
jump: true
}
}Les boules non enflammées ont une chance sur cent de s’enflammer d’elles-mêmes chaque seconde, mais elles sont également soumises à un « GroupGoal » appliqué à l’ensemble du groupe. Cet affecteur agit sur toutes les particules du groupe non enflammé lorsqu’elles entrent en collision avec des particules du groupe enflammé, et les fait passer dans le groupe enflammé.
ParticleGroup {
name: "lighting"
duration: 100
to: {"lit":1}
}Le groupe « lighting » sert de groupe intermédiaire afin que la lueur s’intensifie progressivement et que la transition soit moins brutale. Les particules rejoignent donc automatiquement le groupe « lit » au bout de 100 ms.
ParticleGroup {
name: "lit"
duration: 10000
onEntered: root.score++
TrailEmitter {
id: fireballFlame
group: "flame"
emitRatePerParticle: 48
lifeSpan: 200
emitWidth: 8
emitHeight: 8
size: 24
sizeVariation: 8
endSize: 4
}
TrailEmitter {
id: fireballSmoke
group: "smoke"Le groupe « lit » comporte également des TrailEmitters pour ajouter des effets de feu et de fumée, mais ne subit aucune transition. Il existe deux autres objets « GroupGoal » qui permettent aux particules du groupe « unlit » de passer dans le groupe « lighting » (puis dans le groupe « lit »).
GroupGoal {
groups: ["unlit"]
goalState: "lit"
jump: true
system: particles
x: -15
y: -55
height: 75
width: 30
shape: MaskShape {source: "images/matchmask.png"}
}Le premier est simplement une zone liée à l’emplacement d’une image représentant une flamme pilote. Lorsque des boules non éclairées traversent la flamme, elles passent directement dans le groupe « lit » car la flamme pilote est extrêmement chaude.
//Click to enflame
GroupGoal {
groups: ["unlit"]
goalState: "lighting"
jump: true
enabled: ma.pressed
width: 18
height: 18
x: ma.mouseX - width/2
y: ma.mouseY - height/2
}La seconde est liée à l’emplacement de la dernière interaction du pointeur, de sorte que le fait de toucher ou de cliquer sur des boules non éclairées (ce qui est difficile en raison de leur mouvement constant) les fait passer dans le groupe « éclairage ».
La section « Déplacement » présente quelques effets simples que vous pouvez obtenir en modifiant la trajectoire en cours de route. Les particules rouges sont soumises à un affecteur qui influence leur position, les faisant bondir de 120 px vers l’avant.
Affector {
groups: ["A"]
x: 120
width: 80
height: 80
once: true
position: PointDirection { x: 120; }
}Les particules vertes sont soumises à un affecteur qui agit sur leur vitesse, mais avec une variation d’angle. En ajoutant une composante de vitesse aléatoire à leur vitesse vers l’avant existante, elles commencent à se disperser en formant un cône.
Affector {
groups: ["B"]
x: 120
y: 240
width: 80
height: 80
once: true
velocity: AngleDirection { angleVariation:360; magnitude: 72 }
}Les particules bleues sont soumises à un affecteur qui agit sur leur accélération ; comme celui-ci est défini sur « false », cela réinitialise l’accélération au lieu de l’augmenter. Dès que les particules bleues atteignent l’affecteur, leur vitesse horizontale cesse d’augmenter tandis que leur vitesse verticale diminue.
Affector {
groups: ["C"]
x: 120
y: 400
width: 80
height: 120
once: true
relative: false
acceleration: PointDirection { y: -80; }
}SpriteGoal dispose d’un affecteur qui interagit avec le moteur de sprites des particules, si celles-ci sont dessinées en tant que sprites par ImageParticle.
SpriteGoal {
groups: ["meteor"]
system: sys
goalState: "explode"
jump: true
anchors.fill: rocketShip
width: 60
height: 60
}SpriteGoal suit l’image de la fusée à l’écran, et lorsqu’il interagit avec les particules dessinées sous forme de sprites par ImageParticle, il leur ordonne de passer immédiatement à l’état « exploser », qui correspond dans ce cas à l’animation de l’astéroïde se brisant en mille morceaux.
Turbulence génère une flamme accompagnée de fumée, et les deux ensembles de particules sont affectés par un affecteur Turbulence. Cela produit un léger effet de vent.
Turbulence {
id: turb
enabled: true
height: (parent.height / 2) - 4
width: parent.width
x: parent. width / 4
anchors.fill: parent
NumberAnimation on strength{from: 16; to: 64; easing.type: Easing.InOutBounce; duration: 1800; loops: -1}
}Pour faire changer la direction du vent, remplacez l’image par une image de bruit en noir et blanc dans le paramètre `noiseSource` (il utilise actuellement une source de bruit par défaut).
Wander utilise un affecteur Wander pour ajouter une dérive horizontale aux flocons de neige pendant leur chute.
Wander {
id: wanderer
system: particles
anchors.fill: parent
xVariance: 360/(wanderer.affectedParameter+1);
pace: 100*(wanderer.affectedParameter+1);
}L’application de Wander à différents attributs de la trajectoire génère des mouvements variés ; l’exemple permet donc d’expérimenter facilement et de constater les différences.
© 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.